-- 
cgit v1.2.3

From 9e3371021541dbb7d8428b419c2e77156b166f1a Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:30 +0200
Subject: Imported nxagent-3.1.0-2.tar.gz

Summary: Imported nxagent-3.1.0-2.tar.gz
Keywords:

Imported nxagent-3.1.0-2.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Agent.h         |  130 +
 nx-X11/programs/Xserver/hw/nxagent/Args.c          | 2357 ++++++++
 nx-X11/programs/Xserver/hw/nxagent/Args.h          |   84 +
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |  785 +++
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |   65 +
 nx-X11/programs/Xserver/hw/nxagent/Binder.c        |  177 +
 nx-X11/programs/Xserver/hw/nxagent/Binder.h        |   27 +
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       | 5815 ++++++++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/COPYING         |  339 ++
 nx-X11/programs/Xserver/hw/nxagent/Client.c        |  526 ++
 nx-X11/programs/Xserver/hw/nxagent/Client.h        |  119 +
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     | 1557 ++++++
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h     |   46 +
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c      |  577 ++
 nx-X11/programs/Xserver/hw/nxagent/Colormap.h      |   84 +
 nx-X11/programs/Xserver/hw/nxagent/Composite.c     |  209 +
 nx-X11/programs/Xserver/hw/nxagent/Composite.h     |   51 +
 nx-X11/programs/Xserver/hw/nxagent/Cursor.c        |  601 ++
 nx-X11/programs/Xserver/hw/nxagent/Cursor.h        |  106 +
 nx-X11/programs/Xserver/hw/nxagent/Dialog.c        |  563 ++
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h        |  223 +
 nx-X11/programs/Xserver/hw/nxagent/Display.c       | 2705 +++++++++
 nx-X11/programs/Xserver/hw/nxagent/Display.h       |  179 +
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      | 3201 +++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Drawable.h      |  221 +
 nx-X11/programs/Xserver/hw/nxagent/Error.c         |  636 +++
 nx-X11/programs/Xserver/hw/nxagent/Error.h         |   37 +
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 3822 +++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |  223 +
 nx-X11/programs/Xserver/hw/nxagent/Extensions.c    |  197 +
 nx-X11/programs/Xserver/hw/nxagent/Extensions.h    |   35 +
 nx-X11/programs/Xserver/hw/nxagent/Font.c          | 1690 ++++++
 nx-X11/programs/Xserver/hw/nxagent/Font.h          |   77 +
 nx-X11/programs/Xserver/hw/nxagent/GC.c            | 1712 ++++++
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         | 1995 +++++++
 nx-X11/programs/Xserver/hw/nxagent/GCOps.h         |  105 +
 nx-X11/programs/Xserver/hw/nxagent/GCs.h           |  111 +
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      | 1272 +++++
 nx-X11/programs/Xserver/hw/nxagent/Handlers.h      |  121 +
 nx-X11/programs/Xserver/hw/nxagent/Holder.c        |  226 +
 nx-X11/programs/Xserver/hw/nxagent/Holder.h        |   27 +
 nx-X11/programs/Xserver/hw/nxagent/Icons.h         |   29 +
 nx-X11/programs/Xserver/hw/nxagent/Image.c         | 1816 ++++++
 nx-X11/programs/Xserver/hw/nxagent/Image.h         |  108 +
 nx-X11/programs/Xserver/hw/nxagent/Imakefile       |  220 +
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |  491 ++
 nx-X11/programs/Xserver/hw/nxagent/Init.h          |   40 +
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      | 1359 +++++
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |  114 +
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  216 +
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.h     |   27 +
 nx-X11/programs/Xserver/hw/nxagent/LICENSE         |   26 +
 nx-X11/programs/Xserver/hw/nxagent/Literals.h      |  198 +
 nx-X11/programs/Xserver/hw/nxagent/Millis.c        |   70 +
 nx-X11/programs/Xserver/hw/nxagent/Millis.h        |   30 +
 nx-X11/programs/Xserver/hw/nxagent/NXcomposite.c   |  359 ++
 nx-X11/programs/Xserver/hw/nxagent/NXcomposite.h   |   86 +
 .../programs/Xserver/hw/nxagent/NXcompositeext.h   |   55 +
 .../programs/Xserver/hw/nxagent/NXcompositeint.h   |   76 +
 .../programs/Xserver/hw/nxagent/NXcompositeproto.h |  148 +
 nx-X11/programs/Xserver/hw/nxagent/NXdamage.c      |    5 +
 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c    | 4716 ++++++++++++++++
 .../Xserver/hw/nxagent/NXdispatch.c.NX.original    | 4716 ++++++++++++++++
 .../Xserver/hw/nxagent/NXdispatch.c.XF86.original  | 4110 ++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c    | 2883 ++++++++++
 .../Xserver/hw/nxagent/NXdixfonts.c.NX.original    | 2883 ++++++++++
 .../Xserver/hw/nxagent/NXdixfonts.c.XF86.original  | 2223 ++++++++
 nx-X11/programs/Xserver/hw/nxagent/NXevents.c      | 4797 ++++++++++++++++
 .../Xserver/hw/nxagent/NXevents.c.NX.original      | 4797 ++++++++++++++++
 .../Xserver/hw/nxagent/NXevents.c.XF86.original    | 4637 ++++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/NXextension.c   |  528 ++
 .../Xserver/hw/nxagent/NXextension.c.NX.original   |  528 ++
 .../Xserver/hw/nxagent/NXextension.c.XF86.original |  486 ++
 nx-X11/programs/Xserver/hw/nxagent/NXglxext.c      |  550 ++
 .../Xserver/hw/nxagent/NXglxext.c.NX.original      |  550 ++
 .../Xserver/hw/nxagent/NXglxext.c.XF86.original    |  489 ++
 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c       |  511 ++
 .../Xserver/hw/nxagent/NXglyph.c.NX.original       |  511 ++
 .../Xserver/hw/nxagent/NXglyph.c.XF86.original     |  416 ++
 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c   |  252 +
 .../Xserver/hw/nxagent/NXglyphcurs.c.NX.original   |  252 +
 .../Xserver/hw/nxagent/NXglyphcurs.c.XF86.original |  197 +
 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h    |  161 +
 .../Xserver/hw/nxagent/NXglyphstr.h.NX.original    |  161 +
 .../Xserver/hw/nxagent/NXglyphstr.h.XF86.original  |  127 +
 nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c    |  938 ++++
 .../Xserver/hw/nxagent/NXmiexpose.c.NX.original    |  938 ++++
 .../Xserver/hw/nxagent/NXmiexpose.c.XF86.original  |  873 +++
 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c     |  322 ++
 .../Xserver/hw/nxagent/NXmiglyph.c.NX.original     |  322 ++
 .../Xserver/hw/nxagent/NXmiglyph.c.XF86.original   |  239 +
 nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c      |  204 +
 .../Xserver/hw/nxagent/NXmitrap.c.NX.original      |  204 +
 .../Xserver/hw/nxagent/NXmitrap.c.XF86.original    |  196 +
 nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c    | 1205 ++++
 .../Xserver/hw/nxagent/NXmiwindow.c.NX.original    | 1205 ++++
 .../Xserver/hw/nxagent/NXmiwindow.c.XF86.original  | 1176 ++++
 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c     | 1512 +++++
 .../Xserver/hw/nxagent/NXpicture.c.NX.original     | 1512 +++++
 .../Xserver/hw/nxagent/NXpicture.c.XF86.original   | 1305 +++++
 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h  |  533 ++
 .../Xserver/hw/nxagent/NXpicturestr.h.NX.original  |  533 ++
 .../hw/nxagent/NXpicturestr.h.XF86.original        |  501 ++
 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c    |  921 ++++
 .../Xserver/hw/nxagent/NXproperty.c.NX.original    |  921 ++++
 .../Xserver/hw/nxagent/NXproperty.c.XF86.original  |  736 +++
 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c       | 1229 +++++
 .../Xserver/hw/nxagent/NXrandr.c.NX.original       | 1229 +++++
 .../Xserver/hw/nxagent/NXrandr.c.XF86.original     | 1197 ++++
 nx-X11/programs/Xserver/hw/nxagent/NXrender.c      | 3048 ++++++++++
 .../Xserver/hw/nxagent/NXrender.c.NX.original      | 3048 ++++++++++
 .../Xserver/hw/nxagent/NXrender.c.XF86.original    | 2584 +++++++++
 nx-X11/programs/Xserver/hw/nxagent/NXresource.c    | 1103 ++++
 .../Xserver/hw/nxagent/NXresource.c.NX.original    | 1103 ++++
 .../Xserver/hw/nxagent/NXresource.c.XF86.original  |  975 ++++
 nx-X11/programs/Xserver/hw/nxagent/NXshm.c         | 1425 +++++
 .../Xserver/hw/nxagent/NXshm.c.NX.original         | 1425 +++++
 .../Xserver/hw/nxagent/NXshm.c.XF86.original       | 1257 +++++
 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c      | 4179 ++++++++++++++
 .../Xserver/hw/nxagent/NXwindow.c.NX.original      | 4179 ++++++++++++++
 .../Xserver/hw/nxagent/NXwindow.c.XF86.original    | 3947 +++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c      |  755 +++
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h      |  168 +
 nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h   |  104 +
 nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c      | 2277 ++++++++
 .../Xserver/hw/nxagent/NXxvdisp.c.NX.original      | 2277 ++++++++
 .../Xserver/hw/nxagent/NXxvdisp.c.XF86.original    | 2214 ++++++++
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |  178 +
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |  397 ++
 nx-X11/programs/Xserver/hw/nxagent/Pixels.c        |  384 ++
 nx-X11/programs/Xserver/hw/nxagent/Pixels.h        |  162 +
 nx-X11/programs/Xserver/hw/nxagent/Pixmap.c        | 1646 ++++++
 nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h       |  136 +
 nx-X11/programs/Xserver/hw/nxagent/Pointer.c       |  157 +
 nx-X11/programs/Xserver/hw/nxagent/Pointer.h       |   45 +
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |  788 +++
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.h     |   68 +
 nx-X11/programs/Xserver/hw/nxagent/Render.c        | 2810 ++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Render.h        |  108 +
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      | 1112 ++++
 nx-X11/programs/Xserver/hw/nxagent/Rootless.h      |   93 +
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        | 3984 ++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |  130 +
 nx-X11/programs/Xserver/hw/nxagent/Splash.c        |  335 ++
 nx-X11/programs/Xserver/hw/nxagent/Splash.h        |   45 +
 nx-X11/programs/Xserver/hw/nxagent/Split.c         | 1248 +++++
 nx-X11/programs/Xserver/hw/nxagent/Split.h         |   84 +
 nx-X11/programs/Xserver/hw/nxagent/TestExt.c       |   83 +
 nx-X11/programs/Xserver/hw/nxagent/Trap.c          |   99 +
 nx-X11/programs/Xserver/hw/nxagent/Trap.h          |  100 +
 nx-X11/programs/Xserver/hw/nxagent/Utils.h         |   39 +
 nx-X11/programs/Xserver/hw/nxagent/Visual.c        |  159 +
 nx-X11/programs/Xserver/hw/nxagent/Visual.h        |   73 +
 nx-X11/programs/Xserver/hw/nxagent/Window.c        | 3614 ++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Windows.h       |  300 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c    | 2073 +++++++
 .../Xserver/hw/nxagent/X/NXdamage.c.NX.original    | 2073 +++++++
 .../Xserver/hw/nxagent/X/NXdamage.c.X.original     | 1966 +++++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  | 4670 ++++++++++++++++
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  | 4670 ++++++++++++++++
 .../Xserver/hw/nxagent/X/NXdispatch.c.X.original   | 4035 ++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  | 2797 ++++++++++
 .../Xserver/hw/nxagent/X/NXdixfonts.c.NX.original  | 2797 ++++++++++
 .../Xserver/hw/nxagent/X/NXdixfonts.c.X.original   | 2143 ++++++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    | 4827 ++++++++++++++++
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    | 4827 ++++++++++++++++
 .../Xserver/hw/nxagent/X/NXevents.c.X.original     | 4670 ++++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c |  508 ++
 .../Xserver/hw/nxagent/X/NXextension.c.NX.original |  508 ++
 .../Xserver/hw/nxagent/X/NXextension.c.X.original  |  474 ++
 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c    |  575 ++
 .../Xserver/hw/nxagent/X/NXglxext.c.NX.original    |  575 ++
 .../Xserver/hw/nxagent/X/NXglxext.c.X.original     |  505 ++
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |  566 ++
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |  566 ++
 .../Xserver/hw/nxagent/X/NXglyph.c.X.original      |  478 ++
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c |  241 +
 .../Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original |  241 +
 .../Xserver/hw/nxagent/X/NXglyphcurs.c.X.original  |  194 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h  |  174 +
 .../Xserver/hw/nxagent/X/NXglyphstr.h.NX.original  |  174 +
 .../Xserver/hw/nxagent/X/NXglyphstr.h.X.original   |  148 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c  |  979 ++++
 .../Xserver/hw/nxagent/X/NXmiexpose.c.NX.original  |  979 ++++
 .../Xserver/hw/nxagent/X/NXmiexpose.c.X.original   |  905 +++
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c   |  318 ++
 .../Xserver/hw/nxagent/X/NXmiglyph.c.NX.original   |  318 ++
 .../Xserver/hw/nxagent/X/NXmiglyph.c.X.original    |  243 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c    |  233 +
 .../Xserver/hw/nxagent/X/NXmitrap.c.NX.original    |  233 +
 .../Xserver/hw/nxagent/X/NXmitrap.c.X.original     |  190 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c  | 1222 ++++
 .../Xserver/hw/nxagent/X/NXmiwindow.c.NX.original  | 1222 ++++
 .../Xserver/hw/nxagent/X/NXmiwindow.c.X.original   | 1184 ++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c   | 2220 ++++++++
 .../Xserver/hw/nxagent/X/NXpicture.c.NX.original   | 2220 ++++++++
 .../Xserver/hw/nxagent/X/NXpicture.c.X.original    | 1864 +++++++
 .../programs/Xserver/hw/nxagent/X/NXpicturestr.h   |  678 +++
 .../hw/nxagent/X/NXpicturestr.h.NX.original        |  678 +++
 .../Xserver/hw/nxagent/X/NXpicturestr.h.X.original |  654 +++
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |  904 +++
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |  904 +++
 .../Xserver/hw/nxagent/X/NXproperty.c.X.original   |  729 +++
 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c     | 1344 +++++
 .../Xserver/hw/nxagent/X/NXrandr.c.NX.original     | 1344 +++++
 .../Xserver/hw/nxagent/X/NXrandr.c.X.original      | 1319 +++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    | 3799 +++++++++++++
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    | 3799 +++++++++++++
 .../Xserver/hw/nxagent/X/NXrender.c.X.original     | 3306 +++++++++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c  | 1173 ++++
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  | 1173 ++++
 .../Xserver/hw/nxagent/X/NXresource.c.X.original   |  954 ++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       | 1455 +++++
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       | 1455 +++++
 .../Xserver/hw/nxagent/X/NXshm.c.X.original        | 1267 +++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c    | 4174 ++++++++++++++
 .../Xserver/hw/nxagent/X/NXwindow.c.NX.original    | 4174 ++++++++++++++
 .../Xserver/hw/nxagent/X/NXwindow.c.X.original     | 3853 +++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c    | 2286 ++++++++
 .../Xserver/hw/nxagent/X/NXxvdisp.c.NX.original    | 2286 ++++++++
 .../Xserver/hw/nxagent/X/NXxvdisp.c.X.original     | 2217 ++++++++
 nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm     |   41 +
 nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm   |   48 +
 nx-X11/programs/Xserver/hw/nxagent/os2Stub.c       |  402 ++
 nx-X11/programs/Xserver/hw/nxagent/screensaver     |  703 +++
 225 files changed, 263307 insertions(+)
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Agent.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Args.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Args.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Atoms.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Atoms.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Binder.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Binder.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/COPYING
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Client.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Client.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Colormap.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Colormap.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Composite.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Composite.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Cursor.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Cursor.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Dialog.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Dialog.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Display.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Display.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Drawable.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Drawable.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Error.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Error.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Events.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Events.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Extensions.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Extensions.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Font.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Font.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/GC.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/GCOps.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/GCOps.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/GCs.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Handlers.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Handlers.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Holder.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Holder.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Icons.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Image.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Image.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Imakefile
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Init.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Init.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/LICENSE
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Literals.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Millis.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Millis.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXcomposite.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXcomposite.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXcompositeext.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXcompositeint.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXcompositeproto.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXdamage.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXevents.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXevents.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXextension.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXextension.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglxext.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrender.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrender.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXresource.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXresource.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXresource.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXshm.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXshm.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXshm.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.XF86.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Options.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Options.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Pixels.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Pixels.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Pointer.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Pointer.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Render.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Render.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Rootless.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Rootless.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Screen.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Screen.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Splash.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Splash.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Split.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Split.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/TestExt.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Trap.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Trap.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Utils.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Visual.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Visual.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Window.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/Windows.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/screensaver

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Agent.h b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
new file mode 100644
index 000000000..f976fd768
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
@@ -0,0 +1,130 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+
+Copyright (c) 1995  X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+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 X CONSORTIUM 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.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+
+#ifndef __Agent_H__
+#define __Agent_H__
+
+/*
+ * Machines with a 64 bit library interface and a 32 bit
+ * server require name changes to protect the guilty.
+ */
+
+#ifdef _XSERVER64
+#define _XSERVER64_tmp
+#undef _XSERVER64
+typedef unsigned long XID64;
+typedef unsigned long Mask64;
+typedef unsigned long Atom64;
+typedef unsigned long VisualID64;
+typedef unsigned long Time64;
+#define XID     XID64
+#define Mask    Mask64
+#define Atom    Atom64
+#define VisualID VisualID64
+#define Time    Time64
+typedef XID Window64;
+typedef XID Drawable64;
+typedef XID Font64;
+typedef XID Pixmap64;
+typedef XID Cursor64;
+typedef XID Colormap64;
+typedef XID GContext64;
+typedef XID KeySym64;
+#define Window          Window64
+#define Drawable        Drawable64
+#define Font            Font64
+#define Pixmap          Pixmap64
+#define Cursor          Cursor64
+#define Colormap        Colormap64
+#define GContext        GContext64
+#define KeySym          KeySym64
+
+#define XlibAtom        Atom64
+#define XlibWindow      Window64
+#define XlibPixmap      Pixmap64
+#define XlibFont        Font64
+#define XlibKeySym      KeySym64
+#define XlibXID         XID64
+
+#else   /*_XSERVER64*/
+
+#define XlibAtom        Atom
+#define XlibWindow      Window
+#define XlibPixmap      Pixmap
+#define XlibFont        Font
+#define XlibKeySym      KeySym
+#define XlibXID         XID
+
+#endif  /*_XSERVER64*/
+
+#define NX_TRANS_SOCKET
+#define GC XlibGC
+#include "Xlib.h"
+#include "X11/extensions/shape.h"
+#undef GC
+
+#ifdef _XSERVER64_tmp
+#define _XSERVER64
+#undef _XSERVER64_tmp
+#undef XID
+#undef Mask
+#undef Atom
+#undef VisualID
+#undef Time
+#undef Window
+#undef Drawable
+#undef Font
+#undef Pixmap
+#undef Cursor
+#undef Colormap
+#undef GContext
+#undef KeySym
+#endif /*_XSERVER64_tmp*/
+
+#define validateString(string) ((string) ? (string) : "(null)")
+
+#endif /* __Agent_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
new file mode 100644
index 000000000..07526de56
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -0,0 +1,2357 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef __sun
+#include <strings.h>
+#endif
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "servermd.h"
+#include "opaque.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Args.h"
+#include "Options.h"
+#include "Binder.h"
+#include "Trap.h"
+#include "Screen.h"
+#include "Image.h"
+#ifdef RENDER
+#include "Render.h"
+#endif
+#include "Handlers.h"
+#include "Error.h"
+
+/*
+ * NX includes and definitions.
+ */
+
+#include "NXlib.h"
+#include "NXpack.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  WATCH
+
+#ifdef WATCH
+
+#include "unistd.h"
+
+#endif
+
+/*
+ * Define this to force the dispatcher
+ * to always use the dumb scheduler.
+ */
+
+#undef DISABLE_SMART_SCHEDULE
+
+int nxagentUserDefinedFontPath = 0;
+
+/*
+ * From X11/ImUtil.c.
+ */
+
+extern int _XGetBitsPerPixel(Display *dpy, int depth);
+
+extern char dispatchExceptionAtReset;
+
+char nxagentDisplayName[1024];
+
+char nxagentShadowDisplayName[1024] = {0};
+
+char nxagentWindowName[256];
+char nxagentDialogName[256];
+char nxagentSessionId[256] = {0};
+char *nxagentOptionFile;
+
+Bool nxagentFullGeneration = False;
+int nxagentDefaultClass = TrueColor;
+Bool nxagentUserDefaultClass = False;
+int nxagentDefaultDepth;
+Bool nxagentUserDefaultDepth = False;
+struct UserGeometry nxagentUserGeometry = {0, 0, 0, 0, 0};
+Bool nxagentUserBorderWidth = False;
+int nxagentNumScreens = 0;
+Bool nxagentDoDirectColormaps = False;
+Window nxagentParentWindow = 0;
+Bool nxagentIpaq = False;
+
+int nxagentLockDeferLevel = 0;
+
+Bool nxagentResizeDesktopAtStartup = False;
+
+Bool nxagentUseNXTrans   = False;
+Bool nxagentForceNXTrans = False;
+
+int nxagentMaxAllowedResets = 0;
+
+char *nxagentKeyboard = NULL;
+
+Bool nxagentOnce = True;
+
+static void nxagentParseOptionString(char*);
+
+/*
+ * Get the caption to be used for helper dialogs
+ * from agent's window name passed as parameter.
+ */
+
+static int nxagentGetDialogName(void);
+
+char nxagentVerbose = 0;
+
+int ddxProcessArgument(int argc, char *argv[], int i)
+{
+  /*
+   * Ensure that the options are set to their defaults.
+   */
+
+  static Bool resetOptions = True;
+
+  if (resetOptions == True)
+  {
+    char *envOptions = NULL;
+    char *envDisplay = NULL;
+    int j;
+
+    nxagentInitOptions();
+
+    resetOptions = False;
+
+    /*
+     * Ensure the correct order of options evaluation:
+     * the environment first, then those included in
+     * the options file and, last, the command line
+     * options.
+     */
+
+    envDisplay = getenv("DISPLAY");
+
+    if (envDisplay != NULL && strlen(envDisplay) == 0)
+    {
+      envDisplay = NULL;
+    }
+
+    for (j = 0; j < argc; j++)
+    {
+      if ((!strcmp(argv[j], "-display")) && (j + 1 < argc))
+      {
+        envOptions = malloc(strlen(argv[j + 1]) + 1);
+
+        if (envOptions != NULL)
+        {
+          envOptions = strcpy(envOptions, argv[j + 1]);
+        }
+        #ifdef WARNING
+        else
+        {
+          fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
+        }
+        #endif
+
+        break;
+      }
+    }
+
+    if ((envOptions == NULL) && (envDisplay != NULL))
+    {
+      envOptions = malloc(strlen(envDisplay) + 1);
+
+      if (envOptions != NULL)
+      {
+        envOptions = strcpy(envOptions, envDisplay);
+      }
+      #ifdef WARNING
+      else
+      {
+        fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
+      }
+      #endif
+    }
+
+    if (envOptions != NULL)
+    {
+      nxagentParseOptionString(envOptions);
+
+      free(envOptions);
+    }
+
+    for (j = 0; j < argc; j++)
+    {
+      if ((!strcmp(argv[j], "-options") || !strcmp(argv[j], "-option")) && j + 1 < argc)
+      {
+        if (nxagentOptionFile)
+        {
+          nxagentOptionFile = (char *) realloc(nxagentOptionFile, strlen(argv[j + 1]) + 1);
+        }
+        else
+        {
+          nxagentOptionFile = (char *) malloc(strlen(argv[j + 1]) +1);
+        }
+
+        if (nxagentOptionFile != NULL)
+        {
+          nxagentOptionFile = strcpy(nxagentOptionFile, argv[j + 1]);
+        }
+        #ifdef WARNING
+        else
+        {
+          fprintf(stderr, "ddxProcessArgument: WARNING! failed string allocation.\n");
+        }
+        #endif
+
+        break;
+      }
+    }
+
+    if (nxagentOptionFile)
+    {
+      nxagentProcessOptionsFile();
+    }
+  }
+
+  if (!strcmp(argv[i], "-B"))
+  {
+    #ifdef TEST
+    fprintf(stderr, "ddxProcessArgument: Checking the NX binder option.\n");
+    #endif
+
+    if (nxagentCheckBinder(argc, argv, i) > 0)
+    {
+      /*
+       * We are going to run the agent with the
+       * 'binder' option. Go straight to the
+       * proxy loop.
+       */
+
+      #ifdef TEST
+      fprintf(stderr, "ddxProcessArgument: Entering the NX proxy binder loop.\n");
+      #endif
+
+      nxagentBinderLoop();
+
+      /*
+       * This will make an exit.
+       */
+
+      nxagentBinderExit(0);
+    }
+    else
+    {
+      /*
+       * Exit with an error.
+       */
+
+      nxagentBinderExit(1);
+    }
+  }
+
+  if (!strcmp(argv[i], "-display"))
+  {
+    if (++i < argc)
+    {
+      strncpy(nxagentDisplayName, argv[i], 1023);
+
+      nxagentDisplayName[1023] = '\0';
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-id"))
+  {
+    if (++i < argc)
+    {
+      strncpy(nxagentSessionId, argv[i], 255);
+
+      *(nxagentSessionId + 255) = '\0';
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  /*
+   * This had to be '-options' since the beginning
+   * but was '-option' by mistake. Now we have to
+   * handle the backward compatibility.
+   */
+
+  if (!strcmp(argv[i], "-options") || !strcmp(argv[i], "-option"))
+  {
+    if (++i < argc)
+    {
+      int size;
+
+      if (nxagentOptionFile != NULL)
+      {
+        xfree(nxagentOptionFile);
+
+        nxagentOptionFile = NULL;
+      }
+
+      if ((size = strlen(argv[i])) < 1024)
+      {
+        if ((nxagentOptionFile = xalloc(size + 1)) == NULL)
+        {
+          FatalError("malloc failed");
+        }
+
+        strncpy(nxagentOptionFile, argv[i], size);
+
+        nxagentOptionFile[size] = '\0';
+      }
+      else
+      {
+        /*
+         * It is useless to store the file name
+         * that has just been truncated.
+         */
+
+        #ifdef WARNING
+        fprintf(stderr, "ddxProcessArgument: WARNING! Option file name "
+                    "too long. It will be ignored.\n");
+        #endif
+      }
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-full")) {
+    nxagentFullGeneration = True;
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-class")) {
+    if (++i < argc) {
+      if (!strcmp(argv[i], "StaticGray")) {
+        nxagentDefaultClass = StaticGray;
+        nxagentUserDefaultClass = True;
+        return 2;
+      }
+      else if (!strcmp(argv[i], "GrayScale")) {
+        nxagentDefaultClass = GrayScale;
+        nxagentUserDefaultClass = True;
+        return 2;
+      }
+      else if (!strcmp(argv[i], "StaticColor")) {
+        nxagentDefaultClass = StaticColor;
+        nxagentUserDefaultClass = True;
+        return 2;
+      }
+      else if (!strcmp(argv[i], "PseudoColor")) {
+        nxagentDefaultClass = PseudoColor;
+        nxagentUserDefaultClass = True;
+        return 2;
+      }
+      else if (!strcmp(argv[i], "TrueColor")) {
+        nxagentDefaultClass = TrueColor;
+        nxagentUserDefaultClass = True;
+        return 2;
+      }
+      else if (!strcmp(argv[i], "DirectColor")) {
+        nxagentDefaultClass = DirectColor;
+        nxagentUserDefaultClass = True;
+        return 2;
+      }
+    }
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-cc")) {
+    if (++i < argc && sscanf(argv[i], "%i", &nxagentDefaultClass) == 1) {
+      if (nxagentDefaultClass >= 0 && nxagentDefaultClass <= 5) {
+        nxagentUserDefaultClass = True;
+        /* lex the OS layer process it as well, so return 0 */
+      }
+    }
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-depth")) {
+    if (++i < argc && sscanf(argv[i], "%i", &nxagentDefaultDepth) == 1) {
+      if (nxagentDefaultDepth > 0) {
+        nxagentUserDefaultDepth = True;
+        return 2;
+      }
+    }
+    return 0;
+  }
+
+  /*
+   * These options are now useless and are
+   * parsed only for compatibility with
+   * older versions.
+   */
+
+  if (!strcmp(argv[i], "-fast") ||
+          !strcmp(argv[i], "-slow") ||
+              !strcmp(argv[i], "-hint") ||
+                  !strcmp(argv[i], "-sss"))
+  {
+    fprintf(stderr, "Warning: Ignoring deprecated command line option '%s'.\n",
+                argv[i]);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-backingstore"))
+  {
+    if (++i < argc)
+    {
+      if (!strcmp(argv[i], "0"))
+      {
+        nxagentChangeOption(BackingStore, BackingStoreNever);
+      }
+      else
+      {
+        nxagentChangeOption(BackingStore, BackingStoreForce);
+      }
+
+      return 2;
+    }
+
+    return 0;
+  } 
+
+  if (!strcmp(argv[i], "-streaming"))
+  {
+    if (++i < argc)
+    {
+      if (!strcmp(argv[i], "0"))
+      {
+        nxagentChangeOption(Streaming, 0);
+      }
+      else
+      {
+        nxagentChangeOption(Streaming, 1);
+      }
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-defer"))
+  {
+    int level;
+
+    if (++i < argc &&
+            sscanf(argv[i], "%i", &level) == 1 &&
+                level >= 0 && level <= 2)
+    {
+      if (nxagentOption(Shadow) == 0)
+      {
+        nxagentChangeOption(DeferLevel, level);
+
+        /*
+         * The defer level set with the command
+         * line is not changed when the session
+         * is resumed.
+         */
+
+        nxagentLockDeferLevel = 1;
+      }
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-tile"))
+  {
+    int width;
+    int height;
+
+    if (++i < argc &&
+            sscanf(argv[i], "%ix%i", &width, &height) == 2 &&
+                width >= 32 && height >= 32)
+    { 
+      nxagentChangeOption(TileWidth,  width);
+      nxagentChangeOption(TileHeight, height);
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  if (strcmp(argv[i], "-fp") == 0)
+  {
+    if(++i < argc)
+    {
+
+      #ifdef sgi
+
+      userdefinedfontpath = 1;
+
+      #endif
+
+      #ifdef TEST
+      fprintf(stderr, "ddxProcessArgument: User defined font path [%s].\n", argv[i]);
+      #endif
+
+      nxagentUserDefinedFontPath = 1;
+
+      defaultFontPath = argv[i];
+    }
+    else
+    {
+      UseMsg();
+    }
+  }
+
+  if (!strcmp(argv[i], "-geometry"))
+  {
+    if (++i < argc)
+    {
+      if (!strcmp(argv[i],"fullscreen"))
+      {
+        nxagentChangeOption(Fullscreen, True);
+      }
+      else if (!strcmp(argv[i],"ipaq"))
+      {
+        nxagentChangeOption(Fullscreen, True);
+
+        nxagentIpaq = True;
+      }
+      else
+      { 
+        if (nxagentUserGeometry.flag == 0) 
+        {
+          nxagentUserGeometry.flag = XParseGeometry(argv[i], 
+                                                        &nxagentUserGeometry.X, 
+                                                            &nxagentUserGeometry.Y, 
+                                                                &nxagentUserGeometry.Width, 
+                                                                    &nxagentUserGeometry.Height);
+        }
+      }
+
+      if (nxagentUserGeometry.flag || (nxagentOption(Fullscreen) == 1)) return 2;
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-bw"))
+  {
+    int BorderWidth;
+
+    if (++i < argc && sscanf(argv[i], "%i", &BorderWidth) == 1)
+    {
+      nxagentChangeOption(BorderWidth, BorderWidth);
+
+      if (nxagentOption(BorderWidth) >= 0)
+      {
+        nxagentUserBorderWidth = True;
+
+        return 2;
+      }
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-name"))
+  {
+    if (++i < argc)
+    {
+      strncpy(nxagentWindowName, argv[i], 255);
+
+      *(nxagentWindowName + 255) = '\0';
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-scrns")) {
+    if (++i < argc && sscanf(argv[i], "%i", &nxagentNumScreens) == 1) {
+      if (nxagentNumScreens > 0) {
+        if (nxagentNumScreens > MAXSCREENS) {
+          ErrorF("Maximum number of screens is %d.\n", MAXSCREENS);
+          nxagentNumScreens = MAXSCREENS;
+        }
+        return 2;
+      }
+    }
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-install")) {
+    nxagentDoDirectColormaps = True;
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-parent")) {
+    if (++i < argc) {
+      nxagentParentWindow = (XID) strtol (argv[i], (char**)NULL, 0);
+      return 2;
+    }
+  }
+
+  if (!strcmp(argv[i], "-forcenx")) {
+    nxagentForceNXTrans = True;
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-noonce"))
+  {
+      nxagentOnce = False;
+      return 1;
+  }
+
+  if (!strcmp(argv[i], "-kbtype") ||
+          !strcmp(argv[i], "-keyboard"))
+  {
+    if (++i < argc)
+    {
+      int size;
+
+      if (nxagentKeyboard != NULL)
+      {
+        xfree(nxagentKeyboard);
+
+        nxagentKeyboard = NULL;
+      }
+
+      if ((size = strlen(argv[i])) < 256)
+      {
+        if ((nxagentKeyboard = xalloc(size + 1)) == NULL)
+        {
+          FatalError("malloc failed");
+        }
+
+        strncpy(nxagentKeyboard, argv[i], size);
+
+        nxagentKeyboard[size] = '\0';
+      }
+      #ifdef WARNING
+      else
+      {
+        /*
+         * it is useless to remember a kbtype
+         * option that has just been truncated.
+         */
+
+        fprintf(stderr, "ddxProcessArgument: WARNING! Option [%s] too long. "
+                    "It will be ignored.\n", argv[i]);
+      }
+      #endif
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-extensions"))
+  {
+     return 1;
+  }
+
+  #ifdef RENDER
+  if (!strcmp(argv[i], "-norender"))
+  {
+    nxagentRenderEnable = False;
+
+    return 1;
+  }
+  #endif
+
+  if (!strcmp(argv[i], "-nocomposite"))
+  {
+    nxagentChangeOption(Composite, 0);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-nodamage"))
+  {
+    nxagentChangeOption(UseDamage, 0);
+
+    return 1;
+  }
+
+  /*
+   * The original -noreset option, disabling
+   * dispatchExceptionAtReset, is the default.
+   * Use this option to restore the original
+   * behaviour.
+   */
+
+  if (!strcmp(argv[i], "-reset"))
+  {
+    nxagentChangeOption(Reset, True);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-persistent"))
+  {
+    nxagentChangeOption(Persistent, True);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-nopersistent"))
+  {
+    nxagentChangeOption(Persistent, False);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-noshmem"))
+  {
+    nxagentChangeOption(SharedMemory, False);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-shmem"))
+  {
+    nxagentChangeOption(SharedMemory, True);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-noignore"))
+  {
+    nxagentChangeOption(DeviceControl, True);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-nokbreset"))
+  {
+    nxagentChangeOption(ResetKeyboardAtResume, False);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-noxkblock"))
+  {
+    nxagentChangeOption(InhibitXkb, 0);
+
+    return 1;
+  }
+
+  /*
+   * Enable pseudo-rootless mode.
+   */
+
+  if (!strcmp(argv[i], "-R"))
+  {
+    if (nxagentOption(Binder) == UNDEFINED ||
+            nxagentOption(Desktop) == UNDEFINED ||
+                nxagentOption(Rootless) == UNDEFINED)
+    {
+      nxagentChangeOption(Binder, False);
+      nxagentChangeOption(Desktop, False);
+      nxagentChangeOption(Rootless, True);
+    }
+    return 1;
+  }
+
+  /*
+   * Enable the "desktop" mode. This is
+   * the default.
+   */
+
+  if (!strcmp(argv[i], "-D"))
+  {
+    nxagentChangeOption(Binder, False);
+    nxagentChangeOption(Rootless, False);
+    nxagentChangeOption(Desktop, True);
+
+    return 1;
+  }
+
+  /*
+   * Enable the "shadow" mode.
+   */
+
+  if (!strcmp(argv[i], "-S"))
+  {
+    nxagentChangeOption(Shadow, 1);
+    nxagentChangeOption(DeferLevel, 0);
+    nxagentChangeOption(Persistent, 0);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-shadow"))
+  {
+    if (++i < argc)
+    {
+      strncpy(nxagentShadowDisplayName, argv[i], 1023);
+
+      if (strcmp(nxagentShadowDisplayName, "") == 0)
+      {
+        FatalError("Invalid shadow display option");
+      }
+
+      *(nxagentShadowDisplayName + 1023) = '\0';
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+
+  if (!strcmp(argv[i], "-shadowmode"))
+  {
+    if (++i < argc)
+    {
+      if (!strcmp(argv[i], "0"))
+      {
+        nxagentChangeOption(ViewOnly, 1);
+      }
+      else
+      {
+        nxagentChangeOption(ViewOnly, 0);
+      }
+
+      return 2;
+    }
+
+    return 0;
+  }
+
+  /*
+   * Enable the auto-disconnect timeout.
+   */
+
+  if (!strcmp(argv[i], "-timeout"))
+  {
+    int seconds;
+
+    if (++i < argc && sscanf(argv[i], "%i", &seconds) == 1)
+    {
+      if (seconds >= 0)
+      {
+        if (seconds > 0 && seconds < 60)
+        {
+          seconds = 60;
+        }
+
+        nxagentChangeOption(Timeout, seconds);
+
+        return 2;
+      }
+    }
+
+    return 0;
+  }
+
+  /*
+   * The return value for -query, -broadcast and
+   * -indirect must be 0 to let the dix layer pro-
+   * cess these options.
+   */
+
+  if (!strcmp(argv[i], "-query"))
+
+  {
+    nxagentChangeOption(Desktop, True);
+    nxagentChangeOption(Xdmcp, True);
+
+    nxagentMaxAllowedResets = 0;
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-broadcast"))
+
+  {
+    nxagentChangeOption(Desktop, True);
+    nxagentChangeOption(Xdmcp, True);
+
+    nxagentMaxAllowedResets = 0;
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-indirect"))
+  {
+    nxagentChangeOption(Desktop, True);
+    nxagentChangeOption(Xdmcp, True);
+
+    nxagentMaxAllowedResets = 1;
+
+    return 0;
+  }
+
+  if (!strcmp(argv[i], "-noshpix"))
+  {
+    nxagentChangeOption(SharedPixmaps, False);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-shpix"))
+  {
+    nxagentChangeOption(SharedPixmaps, True);
+
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-clipboard"))
+  {
+    if (!strcmp(argv[i+1], "both"))
+    {
+      nxagentChangeOption(Clipboard, ClipboardBoth);
+    }
+    else if (!strcmp(argv[i+1], "client"))
+    {
+      nxagentChangeOption(Clipboard, ClipboardClient);
+    }
+    else if (!strcmp(argv[i+1], "server"))
+    {
+      nxagentChangeOption(Clipboard, ClipboardServer);
+    }
+    else if (!strcmp(argv[i+1], "none"))
+    {
+      nxagentChangeOption(Clipboard, ClipboardNone);
+    }
+    else
+    {
+      nxagentChangeOption(Clipboard, ClipboardBoth);
+    }
+
+    return 2;
+  }
+
+  if (!strcmp(argv[i], "-bs"))
+  {
+    nxagentChangeOption(BackingStore, BackingStoreNever);
+    return 1;
+  }
+
+  if (!strcmp(argv[i], "-verbose"))
+  {
+    nxagentVerbose = 1;
+
+    return 1;
+  }
+
+  return 0;
+}
+
+static void nxagentParseOptions(char *name, char *value)
+{
+  int size, argc;
+
+  char *argv[2] = { NULL, NULL };
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentParseOptions: Processing option '%s' = '%s'.\n",
+              validateString(name), validateString(value));
+  #endif
+
+  if (!strcmp(name, "kbtype") ||
+          !strcmp(name, "keyboard") ||
+              !strcmp(name, "id") ||
+                  !strcmp(name, "display") ||
+                      !strcmp(name, "clipboard") ||
+                          !strcmp(name, "geometry") ||
+                              !strcmp(name, "option") ||
+                                  !strcmp(name, "options") ||
+                                      !strcmp(name, "shadow") ||
+                                          !strcmp(name, "shadowmode") ||
+                                              !strcmp(name, "streaming") ||
+                                                  !strcmp(name, "defer") ||
+                                                      !strcmp(name, "tile"))
+  {
+    argv[1] = value;
+
+    argc = 2;
+  }
+  else if (!strcmp(name, "R") && !strcmp(value, "1"))
+  {
+    argc = 1;
+  }
+  else if (!strcmp(name, "fast") || !strcmp(name, "slow"))
+  {
+    fprintf(stderr, "Warning: Ignoring deprecated option '%s'.\n", name);
+
+    return;
+  }
+  else if (!strcmp(name, "render"))
+  {
+    if (nxagentReconnectTrap == True)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentParseOptions: Ignoring option 'render' at reconnection.\n");
+      #endif
+    }
+    else if (nxagentRenderEnable == UNDEFINED)
+    {
+      if (!strcmp(value, "1"))
+      {
+        nxagentRenderEnable = True;
+      }
+      else if (!strcmp(value, "0"))
+      {
+        nxagentRenderEnable = False;
+      }
+      else
+      {
+        fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'render'.\n",
+                    validateString(value));
+      }
+    }
+
+    return;
+  }
+  else if (!strcmp(name, "fullscreen"))
+  {
+    if (nxagentReconnectTrap == True)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentParseOptions: Ignoring option 'fullscreen' at reconnection.\n");
+      #endif
+    }
+    else if (!strcmp(value, "1"))
+    {
+      nxagentChangeOption(Fullscreen, True);
+    }
+    else if (!strcmp(value, "0"))
+    {
+      nxagentChangeOption(Fullscreen, False);
+    }
+    else
+    {
+      fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'fullscreen'.\n",
+                  validateString(value));
+    }
+
+    return;
+  }
+  else if (!strcmp(name, "shpix"))
+  {
+    if (!strcmp(value, "1"))
+    {
+      nxagentChangeOption(SharedPixmaps, True);
+    }
+    else if (!strcmp(value, "0"))
+    {
+      nxagentChangeOption(SharedPixmaps, False);
+    }
+    else
+    {
+      fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'shpix'.\n",
+                  validateString(value));
+    }
+
+    return;
+  }
+  else if (!strcmp(name, "shmem"))
+  {
+    if (!strcmp(value, "1"))
+    {
+      nxagentChangeOption(SharedMemory, True);
+    }
+    else if (!strcmp(value, "0"))
+    {
+      nxagentChangeOption(SharedMemory, False);
+    }
+    else
+    {
+      fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'shmem'.\n",
+                  validateString(value));
+    }
+
+    return;
+  }
+  else if (!strcmp(name, "composite"))
+  {
+    if (!strcmp(value, "1"))
+    {
+      nxagentChangeOption(Composite, 1);
+    }
+    else if (!strcmp(value, "0"))
+    {
+      nxagentChangeOption(Composite, 0);
+    }
+    else
+    {
+      fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'composite'.\n",
+                  validateString(value));
+    }
+
+    return;
+  }
+  else if (!strcmp(name, "resize"))
+  {
+    if (!strcmp(value, "1"))
+    {
+      nxagentResizeDesktopAtStartup = True;
+    }
+    else if (!strcmp(value, "0"))
+    {
+      nxagentResizeDesktopAtStartup = False;
+    }
+    else
+    {
+      fprintf(stderr, "Warning: Ignoring bad value '%s' for option 'resize'.\n",
+                  validateString(value));
+    }
+
+    return;
+  }
+  else if (!strcmp(name, "backingstore"))
+  {
+    if (!strcmp(value, "0"))
+    {
+      nxagentChangeOption(BackingStore, BackingStoreNever);
+    }
+    else
+    {
+      nxagentChangeOption(BackingStore, BackingStoreForce);
+    }
+
+    return;
+  }
+  else if (!strcmp(name, "menu"))
+  {
+    if (!strcmp(value, "0"))
+    {
+      nxagentChangeOption(Menu, 0);
+    }
+    else
+    {
+      nxagentChangeOption(Menu, 1);
+    }
+
+    return;
+  }
+  else if (strcmp(name, "shadowuid") == 0)
+  {
+    nxagentShadowUid = atoi(value);
+
+    return;
+  }
+  else if (strcmp(name, "clients") == 0)
+  {
+    strcpy(nxagentClientsLogName, value);
+
+    return;
+  }
+  else if (strcmp(name, "client") == 0)
+  {
+    if (strcmp(value, "winnt") == 0 || strcmp(value, "windows") == 0)
+    {
+      nxagentChangeOption(ClientOs, ClientOsWinnt);
+    }
+    else if (strcmp(value, "linux") == 0)
+    {
+      nxagentChangeOption(ClientOs, ClientOsLinux);
+    }
+    else if (strcmp(value, "solaris") == 0)
+    {
+      nxagentChangeOption(ClientOs, ClientOsSolaris);
+    }
+    else if (strcmp(value, "mac") == 0)
+    {
+      nxagentChangeOption(ClientOs, ClientOsMac);
+    }
+
+    return;
+  }
+  else
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentParseOptions: Ignored option [%s] with value [%s].\n",
+                validateString(name), validateString(value));
+    #endif
+
+    return;
+  }
+
+  /*
+   * Before passing the not yet evaluated options
+   * to ddxProcessArgument(), we have to add a dash
+   * as prefix.
+   */
+
+  if ((size = strlen(name) + 1) > 1)
+  {
+    if ((argv[0] = malloc(size + 1)) == NULL)
+    {
+      fprintf(stderr, "Warning: Ignoring option '%s' due to lack of memory.\n",
+                  name);
+
+      return;
+    }
+
+    *argv[0] = '-';
+
+    memcpy(argv[0] + 1, name, size);
+  }
+
+  ddxProcessArgument(argc, argv, 0);
+
+  free(argv[0]);
+}
+
+static void nxagentParseOptionString(char *string)
+{
+  char *value     = NULL;
+  char *option    = NULL;
+  char *delimiter = NULL;
+
+  /*
+   * Remove the port specification.
+   */
+
+  delimiter = rindex(string, ':');
+
+  if (delimiter)
+  {
+    *delimiter = 0;
+  }
+  else
+  {
+    fprintf(stderr, "Warning: Option file doesn't contain a port specification.\n");
+  }
+
+  while ((option = strtok(option ? NULL : string, ",")))
+  {
+    delimiter = rindex(option, '=');
+
+    if (delimiter)
+    {
+      *delimiter = 0;
+      value = delimiter + 1;
+    }
+    else
+    {
+      value = NULL;
+    }
+
+    nxagentParseOptions(option, value);
+  }
+}
+
+void nxagentProcessOptionsFile()
+{
+  FILE *file;
+  char *data;
+
+  int offset;
+  int size;
+
+  int sizeOfFile;
+  int maxFileSize = 1024;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentProcessOptionsFile: Going to process option the file [%s].\n",
+              validateString(nxagentOptionFile));
+  #endif
+
+  if (nxagentOptionFile == NULL)
+  {
+    return;
+  }
+
+  if ((file = fopen(nxagentOptionFile, "r")) == NULL)
+  {
+    fprintf(stderr, "Warning: Couldn't open option file '%s'. Error is '%s'.\n",
+                validateString(nxagentOptionFile), strerror(errno));
+
+    goto nxagentProcessOptionsFileExit;
+  }
+
+  if (fseek(file, 0, SEEK_END) != 0)
+  {
+    fprintf(stderr, "Warning: Couldn't position inside option file '%s'. Error is '%s'.\n",
+                validateString(nxagentOptionFile), strerror(errno));
+
+    goto nxagentProcessOptionsFileClose;
+  }
+
+  if ((sizeOfFile = ftell(file)) == -1)
+  {
+    fprintf(stderr, "Warning: Couldn't get the size of option file '%s'. Error is '%s'.\n",
+                validateString(nxagentOptionFile), strerror(errno));
+
+    goto nxagentProcessOptionsFileClose;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentProcessOptionsFile: Processing option file [%s].\n",
+              validateString(nxagentOptionFile));
+  #endif
+
+  rewind(file);
+
+  if (sizeOfFile > maxFileSize)
+  {
+    fprintf(stderr, "Warning: Maximum file size exceeded for options '%s'.\n",
+                validateString(nxagentOptionFile));
+
+    goto nxagentProcessOptionsFileClose;
+  }
+
+  if ((data = xalloc(sizeOfFile + 1)) == NULL)
+  {
+    fprintf(stderr, "Warning: Memory allocation failed processing file '%s'.\n",
+                validateString(nxagentOptionFile));
+
+    goto nxagentProcessOptionsFileClose;
+  }
+
+  offset = 0;
+  size = 0;
+
+  for (;;)
+  {
+    size_t result = fread(data + offset, 1, sizeOfFile, file);
+
+    if (ferror(file) != 0)
+    {
+      fprintf(stderr, "Warning: Error reading the option file '%s'.\n",
+                validateString(nxagentOptionFile));
+
+      goto nxagentProcessOptionsFileFree;
+    }
+
+    size   += result;
+    offset += result;
+
+    if (feof(file) != 0 || (size == sizeOfFile))
+    {
+      break;
+    }
+  }
+
+  if (size != sizeOfFile)
+  {
+    fprintf(stderr, "Warning: Premature end of option file '%s' while reading.\n",
+              validateString(nxagentOptionFile));
+
+    goto nxagentProcessOptionsFileFree;
+  }
+
+  /*
+   * Truncate the buffer to the first line.
+   */
+
+  for (offset = 0; (offset < sizeOfFile) && (data[offset] != '\n'); offset++);
+
+  data[offset] = 0;
+
+  nxagentParseOptionString(data);
+
+nxagentProcessOptionsFileFree:
+
+  if (data != NULL)
+  {
+    Xfree(data);
+  }
+
+nxagentProcessOptionsFileClose:
+
+  if (fclose(file) != 0)
+  {
+    fprintf(stderr, "Warning: Couldn't close option file '%s'. Error is '%s'.\n",
+                validateString(nxagentOptionFile), strerror(errno));
+  }
+
+nxagentProcessOptionsFileExit:
+
+  return;
+}
+
+/*
+ * FIXME: Transport initialization, shouldn't depend upon
+ *        argv[], because we call it at every reconnection.
+ */
+
+Bool nxagentPostProcessArgs(char* name, Display* dpy, Screen* scr)
+{
+    Bool useNXTrans = False;
+
+    #ifdef WATCH
+
+    fprintf(stderr, "nxagentPostProcessArgs: Watchpoint 2.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+N/A
+*/
+
+    sleep(30);
+
+    #endif
+
+    if ((nxagentOption(Rootless) == 1) && nxagentOption(Fullscreen) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "WARNING: Ignoring fullscreen option for rootless session.\n");
+      #endif
+
+      nxagentChangeOption(Fullscreen, False);
+    }
+
+    /*
+     * Ensure we have a valid name for children dialogs.
+     */
+
+    nxagentGetDialogName();
+
+    /*
+     * Ensure we have a valid name for window name.
+     */
+
+    if (*nxagentWindowName == '\0')
+    {
+      strncpy(nxagentWindowName, "NX", 255);
+
+      *(nxagentWindowName + 255) = '\0';
+    }
+
+    /*
+     * Note that use of NX packed images as well as
+     * render extension could be later disabled due
+     * to the fact that session is running nested
+     * in a nxagent server.
+     */
+
+    if (nxagentForceNXTrans)
+    {
+      useNXTrans = True;
+    }
+    else if ((strncasecmp(name, "nx/", 3) == 0) ||
+                 (strncasecmp(name, "nx:", 3) == 0) ||
+                     (strncasecmp(name, "nx,", 3) == 0) ||
+                         (strcasecmp(name, "nx") == 0))
+    {
+      useNXTrans = True;
+    }
+
+    if (useNXTrans == True)
+    {
+      unsigned int linkType = LINK_TYPE_NONE;
+
+      unsigned int localMajor = 0;
+      unsigned int localMinor = 0;
+      unsigned int localPatch = 0;
+
+      unsigned int remoteMajor = 0;
+      unsigned int remoteMinor = 0;
+      unsigned int remotePatch = 0;
+
+      int splitTimeout  = 0;
+      int motionTimeout = 0;
+
+      int splitMode = 0;
+      int splitSize = 0;
+
+      unsigned int packMethod  = PACK_NONE;
+      unsigned int packQuality = 9;
+
+      int dataLevel   = 0;
+      int streamLevel = 0;
+      int deltaLevel  = 0;
+
+      unsigned int loadCache    = 0;
+      unsigned int saveCache    = 0;
+      unsigned int startupCache = 0;
+
+      unsigned int enableClient = 0;
+      unsigned int enableServer = 0;
+
+      unsigned int clientSegment = 0;
+      unsigned int serverSegment = 0;
+
+      unsigned int clientSize = 0;
+      unsigned int serverSize = 0;
+
+      if (NXGetControlParameters(dpy, &linkType, &localMajor, &localMinor,
+                                     &localPatch, &remoteMajor, &remoteMinor, &remotePatch,
+                                         &splitTimeout, &motionTimeout, &splitMode, &splitSize,
+                                             &packMethod, &packQuality, &dataLevel, &streamLevel,
+                                                 &deltaLevel, &loadCache, &saveCache, &startupCache) == 0)
+      {
+        fprintf(stderr, "Warning: Failed to get the control parameters.\n");
+      }
+
+      nxagentChangeOption(LinkType, linkType);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentPostProcessArgs: Got local version [%d.%d.%d] remote version [%d.%d.%d].\n",
+                  localMajor, localMinor, localPatch, remoteMajor, remoteMinor, remotePatch);
+
+      fprintf(stderr, "nxagentPostProcessArgs: Got split timeout [%d] motion timeout [%d].\n",
+                  splitTimeout, motionTimeout);
+
+      fprintf(stderr, "nxagentPostProcessArgs: Got split mode [%d] split size [%d].\n",
+                  splitMode, splitSize);
+
+      fprintf(stderr, "nxagentPostProcessArgs: Got preferred pack method [%d] and quality [%d].\n",
+                  packMethod, packQuality);
+      #endif
+
+      if (remoteMajor < 2)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentPostProcessArgs: WARNING! Using backward compatible alpha encoding.\n");
+        #endif
+
+        nxagentAlphaCompat = 1;
+      }
+      else
+      {
+        nxagentAlphaCompat = 0;
+      }
+
+      if (nxagentPackMethod == -1)
+      {
+        nxagentPackMethod = packMethod;
+      }
+
+      if (nxagentPackQuality == -1)
+      {
+        nxagentPackQuality = packQuality;
+      }
+
+      /*
+       * Set the minimum size of images being
+       * streamed.
+       */
+
+      if (nxagentSplitThreshold == -1)
+      {
+        nxagentSplitThreshold = splitSize;
+      }
+
+      /*
+       * Let the remote proxy use the shared memory
+       * extension, if supported by the X server.
+       * The client part is not useful and not impl-
+       * emented. The size of the segment is chosen
+       * by the user. The only purpose of the message
+       * is to reserve the XID that will be used by
+       * the remote.
+       */
+
+      enableClient = 0;
+      enableServer = 1;
+
+      if (NXGetShmemParameters(dpy, &enableClient, &enableServer, &clientSegment,
+                                   &serverSegment, &clientSize, &serverSize) == 0)
+      {
+        fprintf(stderr, "Warning: Failed to get the shared memory parameters.\n");
+      }
+
+      if (enableServer == 1)
+      {
+        fprintf(stderr, "Info: Using shared memory parameters %d/%d/%d/%dK.\n",
+                    nxagentOption(SharedMemory), nxagentOption(SharedPixmaps),
+                         enableServer, serverSize / 1024);
+      }
+      else
+      {
+        fprintf(stderr, "Info: Using shared memory parameters %d/%d/0/0K.\n",
+                    nxagentOption(SharedMemory), nxagentOption(SharedPixmaps));
+      }
+
+      /*
+       * We don't need the NoExpose events. Block
+       * them at the proxy side.
+       */
+
+      NXSetExposeParameters(nxagentDisplay, 1, 1, 0);
+    }
+    else
+    {
+      /*
+       * We don't have a proxy on the remote side.
+       */
+
+      nxagentChangeOption(LinkType, LINK_TYPE_NONE);
+    }
+
+    /*
+     * Set the lossless and lossy pack methods
+     * based on the user's preferences and the
+     * selected link type.
+     */
+
+    nxagentSetPackMethod();
+
+    /*
+     * If not set, set the defer level and the
+     * synchronization timeout based on the link
+     * type.
+     */
+
+    nxagentSetDeferLevel();
+
+    /*
+     * Also set the display output buffer size.
+     */
+
+    nxagentSetBufferSize();
+
+    /*
+     * Select the preferred scheduler.
+     */
+
+    nxagentSetScheduler();
+
+    /*
+     * Select the buffer coalescence timeout.
+     */
+
+    nxagentSetCoalescence();
+
+    /*
+     * Set the other defaults.
+     */
+
+    if (nxagentOption(Fullscreen) == UNDEFINED)
+    {
+      nxagentChangeOption(Fullscreen, False);
+    }
+
+    if (nxagentOption(Binder) == UNDEFINED)
+    {
+      nxagentChangeOption(Binder, False);
+    }
+
+    if (nxagentOption(Rootless) == UNDEFINED)
+    {
+      nxagentChangeOption(Rootless, False);
+    }
+
+    if (nxagentOption(Desktop) == UNDEFINED)
+    {
+      nxagentChangeOption(Desktop, True);
+    }
+
+    /*
+     * The enableBackingStore flag is defined
+     * in window.c in the dix.
+     */
+/*
+FIXME: In rootless mode the backing-store support is not functional yet.
+*/
+    if (nxagentOption(Rootless))
+    {
+      enableBackingStore = 0;
+    }
+    else if (nxagentOption(BackingStore) == BackingStoreUndefined ||
+                 nxagentOption(BackingStore) == BackingStoreForce)
+    {
+      enableBackingStore = 1;
+    }
+    else if (nxagentOption(BackingStore) == BackingStoreNever)
+    {
+      enableBackingStore = 0;
+    }
+
+    /*
+     * need to check if this was set on the
+     * command line as this has the priority
+     * over the option file.
+     */
+ 
+    if (nxagentRenderEnable == UNDEFINED)
+    {
+      nxagentRenderEnable = True;
+    }
+    
+    if (nxagentRenderEnable == True)
+    {
+      nxagentAlphaEnabled = True;
+    }
+    else
+    {
+      nxagentAlphaEnabled = False;
+    }
+
+    if ((nxagentOption(Rootless) == 1) && nxagentOption(Xdmcp))
+    {
+      FatalError("PANIC! Cannot start a XDMCP session in rootless mode.\n");
+    }
+
+    /*
+     * We enable server reset only for indirect
+     * XDMCP sessions.
+     */
+
+    if (nxagentOption(Reset) == True && nxagentMaxAllowedResets == 0)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentPostProcessArgs: Disabling the server reset.\n");
+      #endif
+
+      nxagentChangeOption(Reset, False);
+
+      dispatchExceptionAtReset = 0;
+    }
+
+    /*
+     * We skip server reset by default. This should
+     * be equivalent to passing the -noreset option
+     * to a standard XFree86 server.
+     */
+
+    if (nxagentOption(Reset) == False)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentPostProcessArgs: Disabling dispatch of exception at server reset.\n");
+      #endif
+
+      dispatchExceptionAtReset = 0;
+    }
+
+    /*
+     * Check if the user activated the auto-disconect
+     * feature.
+     */
+
+    if (nxagentOption(Timeout) > 0)
+    {
+      fprintf(stderr, "Info: Using auto-disconnect timeout of %d seconds.\n",
+                  nxagentOption(Timeout));
+
+      nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND;
+    }
+
+    #ifdef WATCH
+
+    fprintf(stderr, "nxagentPostProcessArgs: Watchpoint 3.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#16     1		256 bits (0 KB) ->	12 bits (0 KB) ->	256/1 -> 12/1	= 21.333:1
+#233 A  1		256 bits (0 KB) ->	131 bits (0 KB) ->	256/1 -> 131/1	= 1.954:1
+#245 A  2		512 bits (0 KB) ->	19 bits (0 KB) ->	256/1 -> 10/1	= 26.947:1
+*/
+
+    sleep(30);
+
+    #endif
+
+    return useNXTrans;
+}
+
+void ddxUseMsg()
+{
+  ErrorF("-display string        display name of the real server\n");
+  ErrorF("-sync                  synchronize with the real server\n");
+  ErrorF("-full                  utilize full regeneration\n");
+  ErrorF("-class string          default visual class\n");
+  ErrorF("-depth int             default depth\n");
+  ErrorF("-geometry WxH+X+Y      window size and position\n");
+  ErrorF("-bw int                window border width\n");
+  ErrorF("-name string           window name\n");
+  ErrorF("-scrns int             number of screens to generate\n");
+  ErrorF("-install               install colormaps directly\n");
+
+  ErrorF("The NX system adds the following arguments:\n");
+  ErrorF("-forcenx               force use of NX protocol messages assuming communication through nxproxy\n");
+  ErrorF("-timeout int           auto-disconnect timeout in seconds (minimum allowed: 60)\n");
+#ifdef RENDER
+  ErrorF("-norender              disable the use of the render extension\n");
+  ErrorF("-nocomposite           disable the use of the composite extension\n");
+#endif
+  ErrorF("-nopersistent          disable disconnection/reconnection to the X display on SIGHUP\n");
+  ErrorF("-noshmem               disable use of shared memory extension\n");
+  ErrorF("-shmem                 enable use of shared memory extension\n");
+  ErrorF("-noshpix               disable use of shared pixmaps\n");
+  ErrorF("-shpix                 enable use of shared pixmaps\n");
+  ErrorF("-noignore              don't ignore pointer and keyboard configuration changes mandated by clients\n");
+  ErrorF("-nokbreset             don't reset keyboard device if the session is resumed\n");
+  ErrorF("-noxkblock             always allow applications to change layout through XKEYBOARD\n");
+  ErrorF("-tile WxH              size of image tiles (minimum allowed: 32x32)\n");
+  ErrorF("-D                     enable desktop mode\n");
+  ErrorF("-R                     enable rootless mode\n");
+  ErrorF("-S                     enable shadow mode\n");
+  ErrorF("-B                     enable proxy binding mode\n");
+}
+
+static int nxagentGetDialogName()
+{
+  strcpy(nxagentDialogName, "NX");
+
+  *(nxagentDialogName + 255) = '\0';
+
+  if (*nxagentSessionId != '\0')
+  {
+    int length = strlen(nxagentSessionId);
+
+    strcpy(nxagentDialogName, "NX - ");
+
+    if (length > (MD5_LENGTH * 2 + 1) &&
+           *(nxagentSessionId + (length - (MD5_LENGTH * 2 + 1))) == '-')
+    {
+      strncat(nxagentDialogName, nxagentSessionId, length - (MD5_LENGTH * 2 + 1));
+    }
+    else
+    {
+      strncat(nxagentDialogName, nxagentSessionId, 250);
+    }
+
+    *(nxagentSessionId + 255) = '\0';
+
+    return 1;
+  }
+
+  return 0;
+}
+
+void nxagentSetPackMethod(void)
+{
+  unsigned char supportedMethods[NXNumberOfPackMethods];
+  unsigned int entries = NXNumberOfPackMethods;
+
+  int method;
+
+  if (nxagentOption(LinkType) == LINK_TYPE_NONE)
+  {
+    nxagentChangeOption(Streaming, 0);
+
+    nxagentPackMethod   = PACK_NONE;
+    nxagentPackLossless = PACK_NONE;
+
+    nxagentSplitThreshold = 0;
+
+    return;
+  }
+
+  /*
+   * Check if we need to select the lossy
+   * and lossless pack methods based on
+   * the link type.
+   */
+
+  method = nxagentPackMethod;
+
+  if (method == PACK_ADAPTIVE)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetPackMethod: Using adaptive mode for image compression.\n");
+    #endif
+
+    nxagentChangeOption(Adaptive, 1);
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetPackMethod: Not using adaptive mode for image compression.\n");
+    #endif
+
+    nxagentChangeOption(Adaptive, 0);
+  }
+  
+  if (method == PACK_LOSSY || method == PACK_ADAPTIVE)
+  {
+    nxagentPackMethod = PACK_JPEG_16M_COLORS;
+  }
+  else if (method == PACK_LOSSLESS)
+  {
+    switch (nxagentOption(LinkType))
+    {
+      case LINK_TYPE_MODEM:
+      case LINK_TYPE_ISDN:
+      case LINK_TYPE_ADSL:
+      case LINK_TYPE_WAN:
+      {
+        nxagentPackMethod = PACK_BITMAP_16M_COLORS;
+
+        break;
+      }
+      case LINK_TYPE_LAN:
+      {
+        nxagentPackMethod = PACK_RLE_16M_COLORS;
+
+        break;
+      }
+      default:
+      {
+        fprintf(stderr, "Warning: Unknown link type '%d' while setting the pack method.\n",
+                    nxagentOption(LinkType));
+
+        break;
+      }
+    }
+  }
+
+  /*
+   * Query the remote proxy to determine
+   * whether the selected methods are
+   * supported.
+   */
+
+  if (NXGetUnpackParameters(nxagentDisplay, &entries, supportedMethods) == 0 ||
+          entries != NXNumberOfPackMethods)
+  {
+    fprintf(stderr, "Warning: Unable to retrieve the supported pack methods.\n");
+
+    nxagentPackMethod   = PACK_NONE;
+    nxagentPackLossless = PACK_NONE;
+  }
+  else
+  {
+    if (nxagentPackMethod == PACK_BITMAP_16M_COLORS ||
+            nxagentPackMethod == PACK_RLE_16M_COLORS ||
+                nxagentPackMethod == PACK_RGB_16M_COLORS ||
+                    nxagentPackMethod == PACK_NONE)
+    {
+      nxagentPackLossless = nxagentPackMethod;
+    }
+    else
+    {
+      if (nxagentOption(LinkType) == LINK_TYPE_LAN)
+      {
+        nxagentPackLossless = PACK_RLE_16M_COLORS;
+      }
+      else
+      {
+        nxagentPackLossless = PACK_BITMAP_16M_COLORS;
+      }
+    }
+
+    if (supportedMethods[nxagentPackLossless] == 0)
+    {
+      nxagentPackLossless = PACK_NONE;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetPackMethod: Using method [%d] for lossless compression.\n",
+                nxagentPackLossless);
+    #endif
+
+    if (supportedMethods[nxagentPackMethod] == 0)
+    {
+      fprintf(stderr, "Warning: Pack method '%d' not supported by the proxy.\n",
+                  nxagentPackMethod);
+
+      fprintf(stderr, "Warning: Replacing with lossless pack method '%d'.\n",
+                  nxagentPackLossless);
+
+      nxagentPackMethod = nxagentPackLossless;
+    }
+  }
+
+  if (nxagentPackMethod == nxagentPackLossless)
+  {
+    nxagentPackQuality = 9;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetPackMethod: Assuming pack methods [%d] and [%d] with "
+              "quality [%d].\n", nxagentPackMethod, nxagentPackLossless, nxagentPackQuality);
+  #endif
+}
+
+/*
+ * Each defer level adds the following rules to the previous ones:
+ *
+ * Level 0  Eager encoding.
+ *
+ * Level 1  No data is put or copied on pixmaps, marking them always
+ *          as corrupted and synchronizing them on demand, i.e. when
+ *          a copy area to a window is requested, the source is syn-
+ *          chronized before copying it.
+ *
+ * Level 2  The put images over the windows are skipped marking the
+ *          destination as corrupted. The same happens for copy area
+ *          and composite operations, spreading the corrupted regions
+ *          of involved drawables.
+ */
+
+void nxagentSetDeferLevel()
+{
+  int deferLevel;
+  int tileWidth;
+  int tileHeight;
+  int deferTimeout;
+
+  /*
+   * Streaming is only partly implemented
+   * and is not available in this version
+   * of the agent.
+   */
+
+  if (nxagentOption(Streaming) == 1)
+  {
+    fprintf(stderr, "Warning: Streaming of images not available in this agent.\n");
+
+    nxagentChangeOption(Streaming, 0);
+  }
+
+  switch (nxagentOption(LinkType))
+  {
+    case LINK_TYPE_MODEM:
+    {
+      deferLevel = 2;
+
+      tileWidth  = 64;
+      tileHeight = 64;
+
+      deferTimeout = 200;
+
+      break;
+    }
+    case LINK_TYPE_ISDN:
+    {
+      deferLevel = 2;
+
+      tileWidth  = 64;
+      tileHeight = 64;
+
+      deferTimeout = 200;
+
+      break;
+    }
+    case LINK_TYPE_ADSL:
+    {
+      deferLevel = 2;
+
+      deferTimeout = 200;
+
+      tileWidth  = 65536;
+      tileHeight = 65536;
+
+      break;
+    }
+    case LINK_TYPE_WAN:
+    {
+      deferLevel = 1;
+
+      deferTimeout = 200;
+
+      tileWidth  = 65536;
+      tileHeight = 65536;
+
+      break;
+    }
+    case LINK_TYPE_NONE:
+    case LINK_TYPE_LAN:
+    {
+      deferLevel = 0;
+
+      deferTimeout = 200;
+
+      tileWidth  = 65536;
+      tileHeight = 65536;
+
+      break;
+    }
+    default:
+    {
+      fprintf(stderr, "Warning: Unknown link type [%d] processing the defer option.\n",
+                  nxagentOption(LinkType));
+
+      deferLevel = 0;
+
+      tileWidth  = 64;
+      tileHeight = 64;
+
+      deferTimeout = 200;
+
+      break;
+    }
+  }
+
+  /*
+   * Set the defer timeout.
+   */
+
+  if (nxagentOption(Shadow) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Ignoring defer timeout parameter in shadow mode.\n");
+    #endif
+  }
+  else
+  {
+    nxagentChangeOption(DeferTimeout, deferTimeout);
+  }
+
+  /*
+   * Set the defer level.
+   */
+
+  if (nxagentOption(Shadow) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Ignoring defer parameter in shadow mode.\n");
+    #endif
+  }
+  else if (nxagentOption(DeferLevel) != UNDEFINED)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [defer] option "
+                "with value [%d]. Defer timeout is [%ld] ms.\n", nxagentOption(DeferLevel),
+                    nxagentOption(DeferTimeout));
+    #endif
+  }
+  else
+  {
+    nxagentChangeOption(DeferLevel, deferLevel);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Assuming defer level [%d] with timeout of [%ld] ms.\n",
+                nxagentOption(DeferLevel), nxagentOption(DeferTimeout));
+    #endif
+  }
+
+  /*
+   * Set the tile width.
+   */
+
+  if (nxagentOption(TileWidth) != UNDEFINED)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [tile] option "
+                "width value [%d].\n", nxagentOption(TileWidth));
+    #endif
+  }
+  else
+  {
+    nxagentChangeOption(TileWidth, tileWidth);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Assuming tile width [%d].\n",
+                 nxagentOption(TileWidth));
+    #endif
+  }
+
+  /*
+   * Set the tile height.
+   */
+  
+  if (nxagentOption(TileHeight) != UNDEFINED)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Not overriding the [tile] option "
+                "height value [%d].\n", nxagentOption(TileHeight));
+    #endif
+  }
+  else
+  {
+    nxagentChangeOption(TileHeight, tileHeight);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetDeferLevel: Assuming tile height [%d].\n",
+                 nxagentOption(TileHeight));
+    #endif
+  }
+}
+
+void nxagentSetBufferSize()
+{
+  int size;
+
+  switch (nxagentOption(LinkType))
+  {
+    case LINK_TYPE_MODEM:
+    {
+      size = 4096;
+
+      break;
+    }
+    case LINK_TYPE_ISDN:
+    {
+      size = 4096;
+
+      break;
+    }
+    case LINK_TYPE_ADSL:
+    {
+      size = 8192;
+
+      break;
+    }
+    case LINK_TYPE_WAN:
+    {
+      size = 16384;
+
+      break;
+    }
+    case LINK_TYPE_NONE:
+    case LINK_TYPE_LAN:
+    {
+      size = 16384;
+
+      break;
+    }
+    default:
+    {
+      fprintf(stderr, "Warning: Unknown link type '%d' while setting the display buffer size.\n",
+                  nxagentOption(LinkType));
+
+      size = 16384;
+
+      break;
+    }
+  }
+
+  nxagentChangeOption(DisplayBuffer, size);
+
+  nxagentBuffer = size;
+
+  if (NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer) < 0)
+  {
+    fprintf(stderr, "Warning: Can't set the display buffer size to [%d].\n",
+                nxagentBuffer);
+  }
+}
+
+void nxagentSetScheduler()
+{
+  #ifdef DISABLE_SMART_SCHEDULE
+
+  #ifdef SMART_SCHEDULE
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetScheduler: Disabling the smart scheduler.\n");
+  #endif
+
+  nxagentDisableTimer();
+
+  #endif
+
+  #else /* #ifdef DISABLE_SMART_SCHEDULE */
+
+  /*
+   * The smart scheduler is the default.
+   */
+
+  #ifdef SMART_SCHEDULE
+
+  if (nxagentOption(Shadow) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetScheduler: Using the dumb scheduler in shadow mode.\n");
+    #endif
+
+    nxagentDisableTimer();
+  }
+
+  #endif
+
+  #endif /* #ifdef DISABLE_SMART_SCHEDULE */
+}
+
+void nxagentSetCoalescence()
+{
+  int timeout;
+
+  switch (nxagentOption(LinkType))
+  {
+    case LINK_TYPE_MODEM:
+    {
+      timeout = 50;
+
+      break;
+    }
+    case LINK_TYPE_ISDN:
+    {
+      timeout = 20;
+
+      break;
+    }
+    case LINK_TYPE_ADSL:
+    {
+      timeout = 10;
+
+      break;
+    }
+    case LINK_TYPE_WAN:
+    {
+      timeout = 5;
+
+      break;
+    }
+    case LINK_TYPE_NONE:
+    case LINK_TYPE_LAN:
+    {
+      timeout = 0;
+
+      break;
+    }
+    default:
+    {
+      fprintf(stderr, "Warning: Unknown link type '%d' while setting the display coalescence.\n",
+                  nxagentOption(LinkType));
+
+      timeout = 0;
+
+      break;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetCoalescence: Using coalescence timeout of [%d] ms.\n",
+              timeout);
+  #endif
+
+  nxagentChangeOption(DisplayCoalescence, timeout);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
new file mode 100644
index 000000000..43d7ec779
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -0,0 +1,84 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Args_H__
+#define __Args_H__
+
+#define MD5_LENGTH  16
+
+struct UserGeometry{
+  int flag;
+  int X;
+  int Y;
+  unsigned int Width;
+  unsigned int Height;
+};
+
+extern Bool nxagentUseNXTrans;
+
+extern char nxagentSessionId[];
+extern char nxagentDisplayName[];
+extern char nxagentShadowDisplayName[];
+extern char nxagentWindowName[];
+extern char nxagentDialogName[];
+
+extern Bool nxagentFullGeneration;
+extern int nxagentDefaultClass;
+extern Bool nxagentUserDefaultClass;
+extern int nxagentDefaultDepth;
+extern Bool nxagentUserDefaultDepth;
+extern int nxagentX;
+extern int nxagentY;
+extern unsigned int nxagentWidth;
+extern unsigned int nxagentHeight;
+extern struct UserGeometry nxagentUserGeometry;
+extern Bool nxagentUserBorderWidth;
+extern int nxagentNumScreens;
+extern Bool nxagentDoDirectColormaps;
+extern Window nxagentParentWindow;
+extern int nxagentMaxAllowedReset;
+extern Bool nxagentResizeDesktopAtStartup;
+extern Bool nxagentIpaq;
+
+extern int nxagentLockDeferLevel;
+
+Bool nxagentPostProcessArgs(char *name, Display *dpy, Screen *scr);
+void nxagentProcessOptionsFile(void);
+
+void nxagentSetPackMethod(void);
+void nxagentSetDeferLevel(void);
+void nxagentSetBufferSize(void);
+void nxagentSetScheduler(void);
+void nxagentSetCoalescence(void);
+
+extern int nxagentUserDefinedFontPath;
+
+#endif /* __Args_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
new file mode 100644
index 000000000..1f412fd27
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -0,0 +1,785 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "Agent.h"
+
+#include "Xutil.h"
+#include "Xatom.h"
+#include "Xlib.h"
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+#include "NXpack.h"
+
+#include "Atoms.h"
+#include "Args.h"
+#include "Image.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Options.h"
+#include "Agent.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * These values should be moved in
+ * the option repository.
+ */
+
+Bool nxagentWMIsRunning;
+
+static void startWMDetection(void);
+
+static int nxagentInitAtomMap(char **atomNameList, int count, Atom *atomsRet);
+
+#ifdef DEBUG
+static void nxagentPrintAtomMapInfo(char *message);
+#else
+#define nxagentPrintAtomMapInfo(arg)
+#endif
+
+Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
+
+static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
+{
+  "NX_IDENTITY",          /* 0  */
+  "WM_PROTOCOLS",         /* 1  */
+  "WM_DELETE_WINDOW",     /* 2  */
+  "WM_NX_READY",          /* 3  */
+  "MCOPGLOBALS",          /* 4  */
+  "NX_CUT_BUFFER_SERVER", /* 5  */
+  "TARGETS",              /* 6  */
+  "TEXT",                 /* 7  */
+  "NX_AGENT_SIGNATURE",   /* 8  */
+  "NXDARWIN",             /* 9  */
+  "CLIPBOARD",            /* 10 */
+  "TIMESTAMP",            /* 11 */
+  NULL,
+  NULL
+};
+
+static XErrorHandler previousErrorHandler = NULL;
+
+static void catchAndRedirect(Display* dpy, XErrorEvent* X)
+{
+  if (X -> error_code == BadAccess &&
+      X -> request_code == X_ChangeWindowAttributes &&
+      X -> resourceid == DefaultRootWindow(dpy))
+  {
+    nxagentWMIsRunning = TRUE;
+  }
+  else
+  {
+    previousErrorHandler(dpy, X);
+  }
+}
+
+static void startWMDetection()
+{
+  /*
+   * We are trying to detect if is there any client
+   * that is listening for 'WM' events on the root
+   * window.
+   */
+
+  nxagentWMIsRunning = FALSE;
+
+  previousErrorHandler = XSetErrorHandler((XErrorHandler)&catchAndRedirect);
+
+  /*
+   * After this request we need to Sync with
+   * the X server to be sure we get any error
+   * that is generated.
+   */
+
+  XSelectInput(nxagentDisplay,
+                   RootWindow (nxagentDisplay, 0),
+                       SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask);
+}
+
+static void finishWMDetection(Bool verbose)
+{
+  XSetErrorHandler(previousErrorHandler);
+
+  if (nxagentWMIsRunning)
+  {
+    if (verbose == 1)
+    {
+      fprintf(stderr, "Info: Detected window manager running.\n");
+    }
+  }
+  else
+  {
+    if (verbose == 1)
+    {
+      fprintf(stderr, "Info: Not found a window manager running.\n");
+    }
+
+    /*
+     * We are not really interested on root window events.
+     */
+
+    XSelectInput(nxagentDisplay, RootWindow (nxagentDisplay, 0), 0);
+  }
+}
+
+void nxagentWMDetect() 
+{
+  Bool verbose = False;
+  int windowManagerWasRunning = nxagentWMIsRunning;
+
+  startWMDetection();
+
+  XSync(nxagentDisplay, 0);
+
+  if (windowManagerWasRunning != nxagentWMIsRunning)
+  {
+    verbose = False;
+  }
+
+  finishWMDetection(verbose);
+}
+
+int nxagentInitAtoms(WindowPtr pWin)
+{
+  Atom atom;
+
+  /*
+   * Value of nxagentAtoms[8] is "NX_AGENT_SIGNATURE".
+   *
+   * We don't need to save the atom's value. It will
+   * be checked by other agents to find if they are
+   * run nested.
+   */
+
+  atom = MakeAtom(nxagentAtomNames[8], strlen(nxagentAtomNames[8]), 1);
+
+  if (atom == None)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentInitAtoms: PANIC! Could not create [%s] atom.\n",
+                nxagentAtomNames[8]);
+    #endif
+
+    return -1;
+  }
+
+  return 1;
+}
+
+int nxagentQueryAtoms(ScreenPtr pScreen)
+{
+  int i;
+  static unsigned long atomGeneration = 1;
+
+  int num_of_atoms = NXAGENT_NUMBER_OF_ATOMS;
+  char *names[NXAGENT_NUMBER_OF_ATOMS];
+
+  unsigned long int startingTime = GetTimeInMillis();
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentQueryAtoms: Going to create the intern atoms on real display.\n");
+
+  fprintf(stderr, "nxagentQueryAtoms: Starting time is [%ld].\n", startingTime);
+  #endif
+
+  nxagentPrintAtomMapInfo("nxagentQueryAtoms: Entering");
+
+  for (i = 0; i < num_of_atoms; i++)
+  {
+    names[i] = nxagentAtomNames[i];
+
+    nxagentAtoms[i] = None;
+  }
+
+  if (nxagentSessionId[0])
+  {
+    names[num_of_atoms - 1] = nxagentSessionId;
+  }
+  else
+  {
+    num_of_atoms--;
+  }
+
+  startWMDetection();
+
+  nxagentInitAtomMap(names, num_of_atoms, nxagentAtoms);
+
+  /*
+   * We need to be synchronized with the X server
+   * in order to detect the Window Manager, since
+   * after a reset the XInternAtom could be cached
+   * by Xlib.
+   */
+
+  if (atomGeneration != serverGeneration)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentQueryAtoms: The nxagent has been reset with server %ld atom %ld.\n",
+                serverGeneration, atomGeneration);
+
+    fprintf(stderr, "nxagentQueryAtoms: Forcing a sync to detect the window manager.\n");
+    #endif
+
+    atomGeneration = serverGeneration;
+
+    XSync(nxagentDisplay, 0);
+  }
+
+  finishWMDetection(False);
+
+  /*
+   * Value of nxagentAtoms[9] is "NXDARWIN".
+   *
+   * We check if it was created by the NX client.
+   */
+
+  if (nxagentAtoms[9] > nxagentAtoms[0])
+  {
+    nxagentAtoms[9] = None;
+  }
+
+  /*
+   * Value of nxagentAtoms[8] is "NX_AGENT_SIGNATURE".
+   *
+   * This atom is created internally by the agent server at
+   * startup to let other agents determine if they are run
+   * nested. If agent is run nested, in fact, at the time it
+   * will create the NX_AGENT_SIGNATURE atom on the real X
+   * server it will find the existing atom with a value less
+   * than any NX_IDENTITY created but itself.
+   */
+
+  if (nxagentAtoms[8] > nxagentAtoms[0])
+  {
+    nxagentAtoms[8] = None;
+  }
+
+  if (nxagentAtoms[8] != None)
+  {
+    /*
+     * We are running nested in another agent
+     * server.
+     */
+
+    nxagentChangeOption(Nested, 1);
+
+    /*
+     * Avoid the image degradation caused by
+     * multiple lossy encoding.
+     */
+
+    fprintf(stderr, "Warning: Disabling use of lossy encoding in nested mode.\n");
+
+    nxagentPackMethod = nxagentPackLossless;
+  }
+
+  #ifdef TEST
+
+  for (i = 0; i < num_of_atoms; i++)
+  {
+    fprintf(stderr, "nxagentQueryAtoms: Created intern atom [%s] with id [%ld].\n",
+                names[i], nxagentAtoms[i]);
+  }
+
+  #endif
+
+  nxagentChangeOption(DisplayLatency, GetTimeInMillis() - startingTime);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentQueryAtoms: Ending time is [%ld] reference latency is [%d] Ms.\n",
+              GetTimeInMillis(), nxagentOption(DisplayLatency));
+  #endif
+
+  nxagentPrintAtomMapInfo("nxagentQueryAtoms: Exiting");
+
+  return 1;
+}
+
+#define NXAGENT_ATOM_MAP_SIZE_INCREMENT 256
+
+typedef struct {
+    Atom local;
+    Atom remote;
+    char *string;
+    int  length;
+} AtomMap;
+
+static AtomMap *privAtomMap = NULL;
+static unsigned int privAtomMapSize = 0;
+static unsigned int privLastAtom = 0;
+
+static void nxagentExpandCache(void);
+static void nxagentWriteAtom(Atom, Atom, char*, Bool);
+static AtomMap* nxagentFindAtomByRemoteValue(Atom);
+static AtomMap* nxagentFindAtomByLocalValue(Atom);
+static AtomMap* nxagentFindAtomByName(char*, unsigned);
+
+static void nxagentExpandCache(void)
+{
+  privAtomMapSize += NXAGENT_ATOM_MAP_SIZE_INCREMENT;
+
+  privAtomMap = realloc(privAtomMap, privAtomMapSize * sizeof(AtomMap));
+
+  if (privAtomMap == NULL)
+  {
+    FatalError("nxagentExpandCache: realloc failed\n");
+  }
+}
+
+/*
+ * Check if there is space left on the map
+ * and manage the possible consequent allocation,
+ * then cache the atom-couple.
+ */
+
+static void nxagentWriteAtom(Atom local, Atom remote, char *string, Bool duplicate)
+{
+  char *s;
+
+  /*
+   * We could remove this string duplication if
+   * we know for sure that the server will not
+   * reset, since only at reset the dix layer
+   * free all the atom names.
+   */
+
+  if (duplicate)
+  {
+    s = strdup(string);
+
+    #ifdef WARNING
+    if (s == NULL)
+    {
+      fprintf(stderr, "nxagentWriteAtom: Malloc failed.\n");
+    }
+    #endif
+  }
+  else
+  {
+    s = string;
+  }
+
+  if (privLastAtom == privAtomMapSize)
+  {
+    nxagentExpandCache();
+  }
+
+  privAtomMap[privLastAtom].local = local;
+  privAtomMap[privLastAtom].remote = remote;
+  privAtomMap[privLastAtom].string = s;
+  privAtomMap[privLastAtom].length = strlen(s);
+
+  privLastAtom++;
+}
+
+/*
+ * FIXME: We should clean up the atom map
+ * at nxagent reset, in order to cancel 
+ * all the local atoms but still mantaining 
+ * the Xserver values and the atom names.
+ */
+
+void nxagentResetAtomMap()
+{
+  unsigned i;
+
+  nxagentPrintAtomMapInfo("nxagentResetAtomMap: Entering");
+
+  for (i = 0; i < privLastAtom; i++)
+  {
+    privAtomMap[i].local = None;
+  }
+
+  nxagentPrintAtomMapInfo("nxagentResetAtomMap: Exiting");
+}
+
+/*
+ * Init map.
+ * Initializing the atomNameList all in one.
+ */
+
+static int nxagentInitAtomMap(char **atomNameList, int count, Atom *atomsRet)
+{
+  XlibAtom *atom_list;
+  char **name_list;
+  unsigned int i;
+  int ret_value = 0;
+  int list_size = count + privLastAtom;
+
+  nxagentPrintAtomMapInfo("nxagentInitAtomMap: Entering");
+
+  atom_list = malloc((list_size) * sizeof(*atom_list));
+  name_list = malloc((list_size) * sizeof(char*));
+
+  if ((atom_list == NULL) || (name_list == NULL))
+  {
+    FatalError("nxagentInitAtomMap: malloc failed\n");
+  }
+
+  for (i = 0; i < count; i++)
+  {
+    name_list[i] = atomNameList[i];
+    atom_list[i] = None;
+  }
+  
+  for (i = 0; i < privLastAtom; i++)
+  {
+    name_list[count + i] = privAtomMap[i].string;
+    atom_list[count + i] = None;
+  }
+
+  /*
+   * Ask X-Server for ours Atoms
+   * ... if successfull cache them too.
+   */
+
+  ret_value = XInternAtoms(nxagentDisplay, name_list, list_size, False, atom_list);
+
+  if (ret_value == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentInitAtomMap: WARNING! XInternAtoms request failed.\n");
+    #endif
+
+    free(atom_list);
+    free(name_list);
+
+    return 0;
+  }
+
+  for (i = 0; i < list_size; i++)
+  {
+    AtomMap *aMap = nxagentFindAtomByName(name_list[i], strlen(name_list[i]));
+
+    if (aMap == NULL)
+    {
+      Atom local = MakeAtom(name_list[i], strlen(name_list[i]), True);
+
+      if (ValidAtom(local))
+      {
+        nxagentWriteAtom(local, atom_list[i], name_list[i], False);
+      }
+      else
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentInitAtomMap: WARNING MakeAtom failed.\n");
+        #endif
+      }
+    }
+    else
+    {
+      aMap -> remote = atom_list[i];
+
+      if (i < count && aMap -> local == None)
+      {
+        aMap -> local = MakeAtom(name_list[i], strlen(name_list[i]), True);
+      }
+    }
+
+    if (i < count)
+    {
+      atomsRet[i] = atom_list[i];
+    }
+  }
+
+  free(atom_list);
+  free(name_list);
+
+  nxagentPrintAtomMapInfo("nxagentInitAtomMap: Exiting");
+
+  return 1;
+}
+
+/*
+ * If the nxagent has been resetted,
+ * the local value of the atoms stored
+ * in cache could have the value None, 
+ * do not call this function with None.
+ */
+
+static AtomMap* nxagentFindAtomByLocalValue(Atom local)
+{
+  unsigned i;
+
+  if (!ValidAtom(local))
+  {
+    return NULL;
+  }
+
+  for (i = 0; i < privLastAtom; i++)
+  {
+    if (local == privAtomMap[i].local)
+    {
+      return (privAtomMap + i);
+    }
+  }
+
+  return NULL;
+}
+
+static AtomMap* nxagentFindAtomByRemoteValue(Atom remote)
+{
+  unsigned i;
+
+  if (remote == None || remote == BAD_RESOURCE)
+  {
+    return NULL;
+  }
+
+  for (i = 0; i < privLastAtom; i++)
+  {
+    if (remote == privAtomMap[i].remote)
+    {
+      return (privAtomMap + i);
+    }
+  }
+
+  return NULL;
+}
+
+static AtomMap* nxagentFindAtomByName(char *string, unsigned int length)
+{
+  unsigned i;
+
+  for (i = 0; i < privLastAtom; i++)
+  {
+    if ((length == privAtomMap[i].length) && 
+            (strcmp(string, privAtomMap[i].string) == 0))
+    {
+      return (privAtomMap + i);
+    }
+  }
+
+  return NULL;
+}
+
+/*
+ * Convert local atom's name to X-server value.
+ * Reading them from map, if they have been already cached or
+ * really asking to X-server and caching them.
+ * FIXME: I don't really know if is better to allocate
+ *        an automatic variable like ret_value and write it, instead of make all
+ *        these return!, perhaps this way the code is a little bit easyer to read.
+ *        I think this and the 2 .*Find.* are the only functions to look for performances.
+ */
+
+Atom nxagentMakeAtom(char *string, unsigned int length, Bool Makeit)
+{
+  Atom local;
+  AtomMap *current;
+
+  /*
+   * Surely MakeAtom is faster than
+   * our nxagentFindAtomByName.
+   */
+
+  local = MakeAtom(string, length, Makeit);
+
+  if (!ValidAtom(local))
+  {
+    return None;
+  }
+
+  if (local <= XA_LAST_PREDEFINED)
+  {
+    return local;
+  }
+
+  if ((current = nxagentFindAtomByLocalValue(local)))
+  {
+    /*
+     * Found cached by value.
+     */
+
+    return current->remote;
+  }
+
+  if ((current = nxagentFindAtomByName(string, length)))
+  {
+    /*
+     * Found Cached by name.
+     * It means that nxagent has been resetted,
+     * but not the xserver so we still have cached its atoms.
+     */
+
+    current->local = local;
+
+    return current->remote;
+  }
+
+  /*
+   * We really have to ask Xserver for it.
+   */
+
+  {
+    Atom remote;
+
+    remote = XInternAtom(nxagentDisplay, string, !Makeit);
+
+    if (remote == None)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentMakeAtom: WARNING XInternAtom failed.\n");
+      #endif
+
+      return None;
+    }
+
+    nxagentWriteAtom(local, remote, string, True);
+
+    return remote;
+  }
+}
+
+Atom nxagentLocalToRemoteAtom(Atom local)
+{
+  AtomMap *current;
+  char    *string;
+  Atom    remote;
+
+  if (!ValidAtom(local))
+  {
+    return None;
+  }
+
+  if (local <= XA_LAST_PREDEFINED)
+  {
+    return local;
+  }
+
+  if ((current = nxagentFindAtomByLocalValue(local)))
+  {
+    return current->remote;
+  }
+
+  string = NameForAtom(local);
+
+  remote = XInternAtom(nxagentDisplay, string, False);
+
+  if (remote == None)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentLocalToRemoteAtom: WARNING XInternAtom failed.\n");
+    #endif
+
+    return None;
+  }
+
+  nxagentWriteAtom(local, remote, string, True);
+
+  return remote;
+}
+
+Atom nxagentRemoteToLocalAtom(Atom remote)
+{
+  AtomMap *current;
+  char    *string;
+  Atom    local;
+
+  if (remote == None || remote == BAD_RESOURCE)
+  {
+    return None;
+  }
+
+  if (remote <= XA_LAST_PREDEFINED)
+  {
+    return remote;
+  }
+
+  if ((current = nxagentFindAtomByRemoteValue(remote)))
+  {
+    if (!ValidAtom(current->local))
+    {
+      local = MakeAtom(current->string, current->length, True);
+
+      if (ValidAtom(local))
+      {
+        current->local = local;
+      }
+      else
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentRemoteToLocalAtom: WARNING MakeAtom failed.\n");
+        #endif
+
+        current->local = None;
+      }
+    }
+
+    return current->local;
+  }
+
+  if ((string = XGetAtomName(nxagentDisplay, remote)))
+  {
+    local = MakeAtom(string, strlen(string), True);
+
+    if (!ValidAtom(local))
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentRemoteToLocalAtom: WARNING MakeAtom failed.\n");
+      #endif
+
+      local = None;
+    }
+
+    nxagentWriteAtom(local, remote, string, True);
+
+    XFree(string);
+
+    return local;
+  }
+
+  #ifdef WARNING
+  fprintf(stderr, "nxagentRemoteToLocalAtom: WARNING failed to get name from remote atom.\n");
+  #endif
+
+  return None;
+}
+
+#ifdef DEBUG
+
+static void nxagentPrintAtomMapInfo(char *message)
+{
+  unsigned i;
+
+  fprintf(stderr, "--------------- Atom map in context [%s] ----------------------\n", message);
+  fprintf(stderr, "nxagentPrintAtomMapInfo: Map at [%p] size [%d] number of entry [%d] auto increment [%d].\n",
+              (void*) privAtomMap, privLastAtom, privAtomMapSize, NXAGENT_ATOM_MAP_SIZE_INCREMENT);
+
+  for (i = 0; i < privLastAtom; i++)
+  {
+    fprintf(stderr, "[%5.1d] local: %6.1lu - remote: %6.1lu - [%p] %s\n", i,
+                privAtomMap[i].local,
+                    privAtomMap[i].remote,
+                        privAtomMap[i].string, validateString(privAtomMap[i].string));
+  }
+
+  fprintf(stderr, "---------------------------------------------\n");
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
new file mode 100644
index 000000000..0dd75de43
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -0,0 +1,65 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Atoms_H__
+#define __Atoms_H__
+
+#include "X.h"
+#include "../../include/window.h"
+#include "screenint.h"
+
+#define NXAGENT_NUMBER_OF_ATOMS  13
+
+extern Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
+
+extern Bool nxagentWMIsRunning;
+
+/*
+ * Create the required atoms internally
+ * to the agent server.
+ */
+
+int nxagentInitAtoms(WindowPtr pWin);
+
+/*
+ * Query and create all the required atoms
+ * on the remote X server using a single
+ * round trip.
+ */
+
+int nxagentQueryAtoms(ScreenPtr pScreen);
+
+/*
+ * Create the atoms on the remote X server
+ * and cache the couple local-remote atoms.
+ */
+
+Atom nxagentMakeAtom(char *, unsigned, Bool);
+
+/*
+ * Converts local atoms in remote atoms and
+ * viceversa.
+ */
+
+Atom nxagentRemoteToLocalAtom(Atom);
+Atom nxagentLocalToRemoteAtom(Atom);
+
+void nxagentResetAtomMap(void);
+
+void nxagentWMDetect(void);
+
+#endif /* __Atoms_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.c b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
new file mode 100644
index 000000000..cfea2cc77
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
@@ -0,0 +1,177 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "NX.h"
+
+#include "Binder.h"
+#include "Options.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+int nxagentCheckBinder(int argc, char *argv[], int i)
+{
+  if (++i < argc)
+  {
+    char *display;
+    char *found;
+
+    int port;
+
+    display = argv[i];
+
+    /*
+     * Check if a display specification follows
+     * the -B switch.
+     */
+
+    found = rindex(display, ':');
+
+    if (found == NULL || *(found + 1) == '\0' ||
+            isdigit(*(found + 1)) == 0)
+    {
+      fprintf(stderr, "Error: Can't identify the display port in string '%s'.\n",
+                  display);
+
+      return 0;
+    }
+
+    port = atoi(found + 1);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCheckBinder: Identified agent display port [%d].\n",
+                port);
+    #endif
+
+    /*
+     * The NX options must be specified in the DISPLAY
+     * environment. Check if the display specified on
+     * the command line matches the NX virtual display.
+     */
+
+    display = getenv("DISPLAY");
+
+    if (display == NULL || *display == '\0')
+    {
+      fprintf(stderr, "Error: No DISPLAY environment found.\n");
+
+      return 0;
+    }
+
+    found = rindex(display, ':');
+
+    if (found == NULL || *(found + 1) == '\0' ||
+            isdigit(*(found + 1)) == 0 || atoi(found + 1) != port)
+    {
+      fprintf(stderr, "Error: The NX display doesn't match the agent display :%d.\n",
+                  port);
+
+      return 0;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCheckBinder: Identified NX display port [%d].\n",
+                atoi(found + 1));
+    #endif
+
+    /*
+     * Save the proxy options. They will be later
+     * used to create the transport.
+     */
+
+    nxagentChangeOption(Rootless, False);
+    nxagentChangeOption(Desktop, False);
+    nxagentChangeOption(Binder, True);
+
+    /*
+     * FIXME: This now points to the buffer that was
+     * returned by getenv(). It is to be decided how
+     * to handle the values of type string in the
+     * Options repository.
+     */
+     
+    nxagentChangeOption(BinderOptions, display);
+
+    return 2;
+  }
+
+  fprintf(stderr, "Error: No display port specified in command.\n");
+
+  return 0;
+}
+
+int nxagentBinderLoop()
+{
+  struct timeval timeout;
+
+  char *options = nxagentOption(BinderOptions);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentBinderLoop: Creating the NX transport.\n");
+  #endif
+
+  if (NXTransCreate(NX_FD_ANY, NX_MODE_CLIENT, options) < 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentBinderLoop: PANIC! Error creating the NX transport.\n");
+    #endif
+
+    return -1;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentBinderLoop: Yielding control to the NX entry point.\n");
+  #endif
+
+  while (NXTransRunning(NX_FD_ANY))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentBinderLoop: Going to run a new NX proxy loop.\n");
+    #endif
+
+    timeout.tv_sec  = 10;
+    timeout.tv_usec = 0;
+
+    NXTransContinue(&timeout);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentBinderLoop: Completed execution of the NX loop.\n");
+    #endif
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentBinderLoop: Exiting the NX proxy binder loop.\n");
+  #endif
+
+  return 1;
+}
+
+void nxagentBinderExit(int code)
+{
+  NXTransExit(code);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.h b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
new file mode 100644
index 000000000..928db74fb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
@@ -0,0 +1,27 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Binder_H__
+#define __Binder_H__
+
+int nxagentCheckBinder(int argc, char *argv[], int i);
+
+int nxagentBinderLoop(void);
+
+void nxagentBinderExit(int code);
+
+#endif /* __Binder_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
new file mode 100644
index 000000000..1a63ce5b6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -0,0 +1,5815 @@
+ChangeLog:
+
+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 string comparison in the font replacement routine.
+
+- 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/nx-X11/programs/Xserver/hw/nxagent/COPYING b/nx-X11/programs/Xserver/hw/nxagent/COPYING
new file mode 100644
index 000000000..d511905c1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/COPYING
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
new file mode 100644
index 000000000..7e86a03d2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -0,0 +1,526 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * Used in handling of karma on lost focus.
+ */
+
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+
+#include "NX.h"
+
+#include "Xatom.h"
+#include "dixstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "osdep.h"
+
+/*
+ * NX specific includes and definitions.
+ */
+
+#include "Agent.h"
+#include "Args.h"
+#include "Display.h"
+#include "Client.h"
+#include "Dialog.h"
+#include "Handlers.h"
+#include "Events.h"
+#include "Drawable.h"
+
+/*
+ * Need to include this after the stub
+ * definition of GC in Agent.h.
+ */
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Returns the last signal delivered
+ * to the process.
+ */
+
+extern int _X11TransSocketCheckSignal(void);
+
+/*
+ * Time in milliseconds of first iteration
+ * through the dispatcher.
+ */
+
+unsigned long nxagentStartTime = -1;
+
+/*
+ * If defined, add a function checking if we
+ * need a null timeout after a client wakeup.
+ */
+
+#undef CHECK_RESTARTED_CLIENTS
+
+#ifdef CHECK_RESTARTED_CLIENTS
+
+void nxagentCheckRestartedClients(struct timeval **timeout);
+
+#endif
+
+/*
+ * Allow attaching private members to the client.
+ */
+
+int nxagentClientPrivateIndex;
+
+/*
+ * The master nxagent holds in nxagentShadowCounter
+ * the number of shadow nxagents connected to itself.
+ */
+
+int nxagentShadowCounter = 0;
+
+void nxagentInitClientPrivates(ClientPtr client)
+{
+  if (nxagentClientPriv(client))
+  {
+    nxagentClientPriv(client) -> clientState = 0;
+    nxagentClientPriv(client) -> clientBytes = 0;
+    nxagentClientPriv(client) -> clientHint  = UNKNOWN;
+  }
+}
+
+/*
+ * Guess the running application based on the
+ * properties attached to its main window.
+ */
+
+void nxagentGuessClientHint(ClientPtr client, Atom property, char *data)
+{
+  #ifdef TEST
+  fprintf(stderr, "++++++nxagentGuessClientHint: Client [%d] setting property [%s] as [%s].\n",
+              client -> index, validateString(NameForAtom(property)), validateString(data));
+  #endif
+
+  if (nxagentClientPriv(client) -> clientHint == UNKNOWN)
+  {
+    if (property == XA_WM_CLASS && strcmp(data, "nxclient") == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "++++++nxagentGuessClientHint: Detected nxclient as [%d].\n", client -> index);
+      #endif
+
+      nxagentClientHint(client) = NXCLIENT_WINDOW;
+    }
+  }
+
+  if (nxagentClientPriv(client) -> clientHint == NXCLIENT_WINDOW)
+  {
+    if (property == MakeAtom("WM_WINDOW_ROLE", 14, True) &&
+            strncmp(data, "msgBox", 6) == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "++++++nxagentGuessClientHint: Detected nxclient dialog as [%d].\n", client -> index);
+      #endif
+
+      nxagentClientHint(client) = NXCLIENT_DIALOG;
+    }
+  }
+}
+
+void nxagentGuessShadowHint(ClientPtr client, Atom property)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentGuessShadowHint: Client [%d] setting property [%s].\n",
+              client -> index,
+                  validateString(NameForAtom(property)));
+  #endif
+
+  if (nxagentClientPriv(client) -> clientHint == UNKNOWN)
+  {
+    if (strcmp(validateString(NameForAtom(property)), "_NX_SHADOW") == 0)
+    {
+      #ifdef TEST
+       fprintf(stderr, "nxagentGuessShadowHint: nxagentShadowCounter [%d].\n",
+                   nxagentShadowCounter);
+
+       fprintf(stderr, "nxagentGuessShadowHint: Detected shadow nxagent as client [%d].\n",
+                   client -> index);
+
+      #endif
+
+      nxagentClientHint(client) = NXAGENT_SHADOW;
+
+      nxagentShadowCounter++;
+
+      #ifdef TEST
+       fprintf(stderr, "nxagentGuessShadowHint: nxagentShadowCounter [%d].\n",
+                  nxagentShadowCounter);
+      #endif
+
+      /*
+       * From this moment on we ignore the visibility
+       * checks to keep the windows updated.
+       */
+
+      nxagentChangeOption(IgnoreVisibility, 1);
+    }
+  }
+}
+
+void nxagentCheckIfShadowAgent(ClientPtr client)
+{
+
+  if (nxagentClientPriv(client) -> clientHint == NXAGENT_SHADOW)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCheckIfShadowAgent: nxagentShadowCounter [%d].\n",
+                nxagentShadowCounter);
+
+    fprintf(stderr, "nxagentCheckIfShadowAgent: Shadow nxagent as client [%d] detached.\n",
+                client -> index);
+
+    fprintf(stderr, "nxagentCheckIfShadowAgent: Decreasing nxagentShadowCounter.\n");
+    #endif
+
+    /*
+     * We decrease nxagentShadowCounter.
+     */
+
+    nxagentShadowCounter--;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCheckIfShadowAgent: nxagentShadowCounter [%d].\n",
+                nxagentShadowCounter);
+    #endif
+
+
+    if (nxagentShadowCounter == 0)
+    {
+      /*
+       * The last shadow nxagent has been detached
+       * from master nxagent.
+       * The master nxagent could do some action
+       * here.
+       */
+
+       #ifdef TEST
+       fprintf(stderr, "nxagentCheckIfShadowAgent: The last shadow nxagent has been detached.\n");
+       #endif
+
+      nxagentChangeOption(IgnoreVisibility, 0);
+    }
+  }
+}
+
+void nxagentWakeupByReconnect()
+{
+  int i;
+
+  #ifdef TEST
+  fprintf(stderr, "++++++nxagentWakeupByReconnect: Going to wakeup all clients.\n");
+  #endif
+
+  for (i = 1; i < currentMaxClients; i++)
+  {
+    if (clients[i] != NULL)
+    {
+      nxagentWakeupByReset(clients[i]);
+    }
+  }
+}
+
+void nxagentWakeupByReset(ClientPtr client)
+{
+  #ifdef TEST
+  fprintf(stderr, "++++++nxagentWakeupByReset: Going to check client id [%d].\n",
+              client -> index);
+  #endif
+
+  if (nxagentNeedWakeup(client))
+  {
+    #ifdef TEST
+    fprintf(stderr, "++++++nxagentWakeupByReset: Going to wakeup client id [%d].\n",
+                client -> index);
+    #endif
+
+    if (client -> index < MAX_CONNECTIONS)
+    {
+      if (nxagentNeedWakeupBySplit(client))
+      {
+        nxagentWakeupBySplit(client);
+      }
+    }
+  }
+
+  if (client -> index < MAX_CONNECTIONS)
+  {
+    #ifdef TEST
+    fprintf(stderr, "++++++nxagentWakeupByReset: Going to reset bytes received for client id [%d].\n",
+                client -> index);
+    #endif
+
+    nxagentClientBytes(client) = 0;
+  }
+}
+
+/*
+ * Wait for any event.
+ */
+
+#define WAIT_ALL_EVENTS
+ 
+#ifndef WAIT_ALL_EVENTS
+
+static Bool nxagentWaitWakeupBySplitPredicate(Display *display, XEvent *event, XPointer ptr)
+{
+  return (event -> type == ClientMessage &&
+              (event -> xclient.data.l[0] == NXNoSplitNotify ||
+                  event -> xclient.data.l[0] == NXStartSplitNotify ||
+                      event -> xclient.data.l[0] == NXCommitSplitNotify ||
+                          event -> xclient.data.l[0] == NXEndSplitNotify ||
+                              event -> xclient.data.l[0] == NXEmptySplitNotify) &&
+                                  event -> xclient.window == 0 && event -> xclient.message_type == 0 &&
+                                      event -> xclient.format == 32);
+}
+
+#endif
+
+#define USE_FINISH_SPLIT
+
+void nxagentWaitWakeupBySplit(ClientPtr client)
+{
+  #ifdef TEST
+
+  if (nxagentNeedWakeupBySplit(client) == 0)
+  {
+    fprintf(stderr, "++++++nxagentWaitWakeupBySplit: WARNING! The client [%d] is already awake.\n",
+                client -> index);
+  }
+
+  fprintf(stderr, "++++++nxagentWaitWakeupBySplit: Going to wait for the client [%d].\n",
+              client -> index);
+  #endif
+
+  /*
+   * Be sure we intercept an I/O error
+   * as well as an interrupt.
+   */
+
+  #ifdef USE_FINISH_SPLIT
+
+  NXFinishSplit(nxagentDisplay, client -> index);
+
+  #endif
+
+  NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+  for (;;)
+  {
+    /*
+     * Can we handle all the possible events here
+     * or we need to select only the split events?
+     * Handling all the possible events would pre-
+     * empt the queue and make a better use of the
+     * link.
+     */
+
+    #ifdef WAIT_ALL_EVENTS
+
+    nxagentDispatchEvents(NULL);
+
+    #else
+
+    nxagentDispatchEvents(nxagentWaitWakeupBySplitPredicate);
+
+    #endif
+
+    if (nxagentNeedWakeupBySplit(client) == 0 ||
+            NXDisplayError(nxagentDisplay) == 1)
+    {
+      #ifdef TEST
+
+      if (nxagentNeedWakeupBySplit(client) == 0)
+      {
+        fprintf(stderr, "++++++nxagentWaitWakeupBySplit: Client [%d] can now run.\n",
+                    client -> index);
+      }
+      else
+      {
+        fprintf(stderr, "++++++nxagentWaitWakeupBySplit: WARNING! Display error "
+                    "detected waiting for restart.\n");
+      }
+
+      #endif
+ 
+      return;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "++++++nxagentWaitWakeupBySplit: Yielding control to the NX transport.\n");
+    #endif
+
+    nxagentWaitEvents(nxagentDisplay, NULL);
+  }
+}
+
+int nxagentSuspendBySplit(ClientPtr client)
+{
+/*
+FIXME: Should record a serial number for the client, so that
+       the client is not restarted because of an end of split
+       of a previous client with the same index.
+*/
+  if (client -> index < MAX_CONNECTIONS)
+  {
+    if (nxagentNeedWakeup(client) == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "++++++nxagentSuspendBySplit: Suspending client [%d] with agent sequence [%ld].\n",
+                  client -> index, NextRequest(nxagentDisplay) - 1);
+      #endif
+
+      if (client -> clientGone == 0)
+      {
+        #ifdef TEST
+        fprintf(stderr, "++++++nxagentSuspendBySplit: Client [%d] suspended.\n", client -> index);
+        #endif
+
+        IgnoreClient(client);
+      }
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "++++++nxagentSuspendBySplit: WARNING! Client [%d] already ignored with state [%x].\n",
+                  client -> index, nxagentClientPriv(client) -> clientState);
+    }
+    #endif
+
+    nxagentClientPriv(client) -> clientState |= SleepingBySplit;
+
+    return 1;
+  }
+
+  #ifdef WARNING
+  fprintf(stderr, "++++++nxagentSuspendBySplit: WARNING! Invalid client [%d] provided to function.\n",
+              client -> index);
+  #endif
+
+  return -1;
+}
+
+int nxagentWakeupBySplit(ClientPtr client)
+{
+/*
+FIXME: Should record a serial number for the client, so that
+       the client is not restarted because of the end of the
+       split for a previous client with the same index.
+*/
+  if (client -> index < MAX_CONNECTIONS)
+  {
+    nxagentClientPriv(client) -> clientState &= ~SleepingBySplit;
+
+    if (nxagentNeedWakeup(client) == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "++++++nxagentWakeupBySplit: Resuming client [%d] with agent sequence [%ld].\n",
+                  client -> index, NextRequest(nxagentDisplay) - 1);
+      #endif
+
+      if (client -> clientGone == 0)
+      {
+        AttendClient(client);
+      }
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "++++++nxagentWakeupBySplit: WARNING! Client [%d] still suspended with state [%x].\n",
+                  client -> index, nxagentClientPriv(client) -> clientState);
+    }
+    #endif
+
+    return 1;
+  }
+
+  #ifdef WARNING
+  fprintf(stderr, "++++++nxagentWakeupBySplit: WARNING! Invalid client [%d] provided to function.\n",
+              client -> index);
+  #endif
+
+  return -1;
+}
+
+#ifdef CHECK_RESTARTED_CLIENTS
+
+void nxagentCheckRestartedClients(struct timeval **timeout)
+{
+  static struct timeval zero;
+
+  int i;
+
+  /*
+   * If any of the restarted clients had requests
+   * in input we'll need to enter the select with
+   * a null timeout, or we will block until any
+   * other client becomes available.
+   */
+
+  for (i = 1; i < currentMaxClients; i++)
+  {
+    if (clients[i] != NULL && clients[i] -> osPrivate != NULL &&
+           nxagentNeedWakeup(clients[i]) == 0)
+    {
+      int fd = ((OsCommPtr) clients[i] -> osPrivate) -> fd;
+
+      if (FD_ISSET(fd, &ClientsWithInput))
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentBlockHandler: WARNING! Client [%d] with fd [%d] has input.\n",
+                    clients[i] -> index, fd);
+        #endif
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentBlockHandler: Setting a null timeout with former timeout [%ld] Ms.\n",
+                    (*timeout) -> tv_sec * 1000 + (*timeout) -> tv_usec / 1000);
+        #endif
+
+        if (*timeout != NULL)
+        {
+          (*timeout) -> tv_sec  = 0;
+          (*timeout) -> tv_usec = 0;
+        }
+        else
+        {
+          zero.tv_sec  = 0;
+          zero.tv_usec = 0;
+
+          *timeout = &zero;
+        }
+      }
+    }
+  }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
new file mode 100644
index 000000000..5f9fa1ebb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -0,0 +1,119 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Client_H__
+#define __Client_H__
+
+#define MAX_CONNECTIONS 256
+
+/*
+ * The master nxagent holds in nxagentShadowCounter
+ * the number of shadow nxagents connected to itself.
+ */
+
+extern int nxagentShadowCounter;
+
+enum ClientHint
+{
+  UNKNOWN = 0,
+  NXCLIENT_WINDOW,
+  NXCLIENT_DIALOG,
+  NXAGENT_SHADOW
+};
+
+typedef struct _PrivClientRec
+{
+  int clientState;
+  long clientBytes;
+  enum ClientHint clientHint;
+
+} PrivClientRec;
+
+extern int nxagentClientPrivateIndex;
+
+#define nxagentClientPriv(pClient) \
+  ((PrivClientRec *)((pClient)->devPrivates[nxagentClientPrivateIndex].ptr))
+
+void nxagentInitClientPrivates(ClientPtr);
+
+#define nxagentClientAddBytes(pClient, size)	\
+  (nxagentClientPriv(pClient) -> clientBytes += (size))
+
+#define nxagentClientBytes(pClient)	\
+    (nxagentClientPriv(pClient) -> clientBytes)
+
+#define nxagentClientHint(pClient) \
+    (nxagentClientPriv(pClient) -> clientHint)
+
+#define nxagentClientIsDialog(pClient) \
+    (nxagentClientHint(pClient) == NXCLIENT_DIALOG)
+
+/*
+ * The actual reason why the client
+ * is sleeping.
+ */
+
+#define SleepingBySplit  1
+
+#define nxagentNeedWakeup(client) \
+               ((nxagentClientPriv(client) -> \
+                      clientState) != 0)
+
+#define nxagentNeedWakeupBySplit(client) \
+               (((nxagentClientPriv(client) -> \
+                      clientState) & SleepingBySplit) != 0)
+
+void nxagentGuessClientHint(ClientPtr, Atom, char*);
+
+void nxagentGuessShadowHint(ClientPtr, Atom);
+
+void nxagentCheckIfShadowAgent(ClientPtr);
+
+/*
+ * Suspend or restart the agent's
+ * client.
+ */
+
+int nxagentSuspendBySplit(ClientPtr client);
+int nxagentWakeupBySplit(ClientPtr client);
+
+/*
+ * Wait until the given client is
+ * restarted.
+ */
+
+void nxagentWaitWakeupBySplit(ClientPtr client);
+
+/*
+FIXME: This must be moved to Drawable.h.
+*/
+void nxagentWaitDrawable(DrawablePtr pDrawable);
+
+/*
+ * Wakeup all the sleeping clients.
+ */
+
+void nxagentWakeupByReconnect(void);
+
+/*
+ * Reset the client state before
+ * closing it down.
+ */
+
+void nxagentWakeupByReset(ClientPtr client);
+
+#endif /* __Client_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
new file mode 100644
index 000000000..b581540cb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -0,0 +1,1557 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#define NEED_EVENTS
+
+#include "X.h"
+#include "Xproto.h"
+#include "Xatom.h"
+#include "selection.h"
+#include "windowstr.h"
+
+#include "Windows.h"
+#include "Atoms.h"
+#include "Agent.h"
+#include "Args.h"
+#include "Trap.h"
+#include "Rootless.h"
+#include "Clipboard.h"
+
+/*
+ * Use asyncronous get property replies.
+ */
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * These are defined in the dispatcher.
+ */
+
+extern int NumCurrentSelections;
+extern Selection *CurrentSelections;
+
+int nxagentLastClipboardClient = -1;
+
+static int agentClipboardStatus;
+static int clientAccum;
+
+Atom serverCutProperty;
+static Atom clientCutProperty;
+static Window serverWindow;
+
+static const int nxagentPrimarySelection = 0;
+static const int nxagentClipboardSelection = 1;
+static const int nxagentMaxSelections = 2;
+
+typedef struct _SelectionOwner
+{
+    Atom selection;
+    ClientPtr client;
+    Window window;
+    WindowPtr windowPtr;
+    Time lastTimeChanged;
+
+} SelectionOwner;
+
+static SelectionOwner *lastSelectionOwner;
+static Atom nxagentLastRequestedSelection;
+static Atom nxagentClipboardAtom;
+static Atom nxagentTimestampAtom;
+
+/*
+ * Needed to handle the notify selection event to
+ * be sent to client once the selection property
+ * has been retrieved from the real X server.
+ */
+
+typedef enum
+{
+  SelectionStageNone,
+  SelectionStageQuerySize,
+  SelectionStageWaitSize,
+  SelectionStageQueryData,
+  SelectionStageWaitData
+} ClientSelectionStage;
+
+static WindowPtr     lastClientWindowPtr;
+static ClientPtr     lastClientClientPtr;
+static Window        lastClientRequestor;
+static Atom          lastClientProperty;
+static Atom          lastClientSelection;
+static Atom          lastClientTarget;
+static Time          lastClientTime;
+static Time          lastClientReqTime;
+static unsigned long lastClientPropertySize;
+
+static ClientSelectionStage lastClientStage;
+
+static Window lastServerRequestor;
+static Atom   lastServerProperty;
+static Atom   lastServerTarget;
+static Time   lastServerTime;
+
+static Atom serverTARGETS;
+static Atom serverTEXT;
+static Atom clientTARGETS;
+static Atom clientTEXT;
+static Atom clientCOMPOUND_TEXT;
+
+static char szAgentTARGETS[] = "TARGETS";
+static char szAgentTEXT[] = "TEXT";
+static char szAgentCOMPOUND_TEXT[] = "COMPOUND_TEXT";
+static char szAgentNX_CUT_BUFFER_CLIENT[] = "NX_CUT_BUFFER_CLIENT";
+
+extern Display *nxagentDisplay;
+
+Bool nxagentValidServerTargets(Atom target);
+void nxagentSendSelectionNotify(Atom property);
+void nxagentTransferSelection(int resource);
+void nxagentCollectPropertyEvent(int resource);
+void nxagentResetSelectionOwner(void);
+WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin);
+void nxagentNotifyConvertFailure(ClientPtr client, Window requestor,
+                                     Atom selection, Atom target, Time time);
+int nxagentSendNotify(xEvent *event);
+
+/*
+ * This is from NXproperty.c.
+ */
+
+int GetWindowProperty(WindowPtr pWin, Atom property, long longOffset, long longLength,
+                          Bool delete, Atom type, Atom *actualType, int *format,
+                              unsigned long *nItems, unsigned long *bytesAfter,
+                                  unsigned char **propData);
+
+Bool nxagentValidServerTargets(Atom target)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentValidServerTargets: Got called.\n");
+  #endif
+
+  if (target == XA_STRING) return True;
+  if (target == serverTEXT) return True;
+
+  return False;
+}
+
+void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow)
+{
+  int i;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentClearClipboard: Called with client [%p] window [%p].\n",
+              (void *) pClient, (void *) pWindow);
+  #endif
+
+  /*
+   * Only for PRIMARY and CLIPBOARD selections.
+   */
+
+  for (i = 0; i < nxagentMaxSelections; i++)
+  {
+    if ((pClient != NULL && lastSelectionOwner[i].client == pClient) ||
+            (pWindow != NULL && lastSelectionOwner[i].windowPtr == pWindow))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentClearClipboard: Resetting state with client [%p] window [%p].\n",
+                  (void *) pClient, (void *) pWindow);
+      #endif
+
+      lastSelectionOwner[i].client = NULL;
+      lastSelectionOwner[i].window = None;
+      lastSelectionOwner[i].windowPtr = NULL;
+      lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+
+      lastClientWindowPtr = NULL;
+      lastClientStage = SelectionStageNone;
+
+      lastServerRequestor = None;
+    }
+  }
+ 
+  if (pWindow == lastClientWindowPtr)
+  {
+    lastClientWindowPtr = NULL;
+    lastClientStage = SelectionStageNone;
+  }
+
+}
+
+void nxagentClearSelection(XEvent *X)
+{
+  xEvent x;
+
+  int i = 0;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentClearSelection: Got called.\n");
+  #endif
+
+  if (agentClipboardStatus != 1 ||
+          nxagentOption(Clipboard) == ClipboardServer)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentClearSelection: SelectionClear event.\n");
+  #endif
+
+  while ((i < nxagentMaxSelections) &&
+            (lastSelectionOwner[i].selection != X->xselectionclear.selection))
+  {
+    i++;
+  }
+
+  if (i < nxagentMaxSelections)
+  {
+    if (lastSelectionOwner[i].client != NULL)
+    {
+      x.u.u.type = SelectionClear;
+      x.u.selectionClear.time = GetTimeInMillis();
+      x.u.selectionClear.window = lastSelectionOwner[i].window;
+      x.u.selectionClear.atom = CurrentSelections[i].selection;
+
+      (void) TryClientEvents(lastSelectionOwner[i].client, &x, 1,
+                             NoEventMask, NoEventMask,
+                             NullGrab);
+    }
+
+    CurrentSelections[i].window = WindowTable[0]->drawable.id;
+    CurrentSelections[i].client = NullClient;
+
+    lastSelectionOwner[i].client = NULL;
+    lastSelectionOwner[i].window = None;
+    lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+  }
+
+  lastClientWindowPtr = NULL;
+  lastClientStage = SelectionStageNone;
+}
+
+void nxagentRequestSelection(XEvent *X)
+{
+  int result;
+  int i = 0;
+  XSelectionEvent eventSelection;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentRequestSelection: Got called.\n");
+  #endif
+
+  if (agentClipboardStatus != 1)
+  {
+    return;
+  }
+
+  if (!nxagentValidServerTargets(X->xselectionrequest.target) ||
+         (lastServerRequestor != None) ||
+             ((X->xselectionrequest.selection != lastSelectionOwner[nxagentPrimarySelection].selection) &&
+                 (X->xselectionrequest.selection != lastSelectionOwner[nxagentClipboardSelection].selection)))
+  {
+/*
+FIXME: Do we need this?
+
+    char *strTarget;
+
+    strTarget = XGetAtomName(nxagentDisplay, X->xselectionrequest.target);
+
+    fprintf(stderr, "SelectionRequest event aborting sele=[%s] target=[%s]\n",
+                validateString(NameForAtom(X->xselectionrequest.selection)),
+                    validateString(NameForAtom(X->xselectionrequest.target)));
+
+    fprintf(stderr, "SelectionRequest event aborting sele=[%s] ext target=[%s] Atom size is [%d]\n",
+                validateString(NameForAtom(X->xselectionrequest.selection)), strTarget, sizeof(Atom));
+
+    if (strTarget != NULL)
+    {
+      XFree(strTarget);
+    }
+*/
+    eventSelection.property = None;
+
+    if (X->xselectionrequest.target == serverTARGETS)
+    {
+      Atom xa_STRING = XA_STRING;
+      result = XChangeProperty (nxagentDisplay,
+                                X->xselectionrequest.requestor,
+                                X->xselectionrequest.property,
+                                X->xselectionrequest.target,
+                                sizeof(Atom)*8,
+                                PropModeReplace,
+                                (unsigned char*)&xa_STRING,
+                                1);
+      eventSelection.property = X->xselectionrequest.property;
+    }
+
+    if (X->xselectionrequest.target == nxagentTimestampAtom)
+    {
+      while ((i < NumCurrentSelections) &&
+                lastSelectionOwner[i].selection != X->xselectionrequest.selection) i++;
+
+      if (i < NumCurrentSelections)
+      {
+        result = XChangeProperty(nxagentDisplay,
+                                 X->xselectionrequest.requestor,
+                                 X->xselectionrequest.property,
+                                 X->xselectionrequest.target,
+                                 32,
+                                 PropModeReplace,
+                                 (unsigned char *) &lastSelectionOwner[i].lastTimeChanged,
+                                 1);
+        eventSelection.property = X->xselectionrequest.property;
+      }
+    }
+
+    eventSelection.type = SelectionNotify;
+    eventSelection.send_event = True;
+    eventSelection.display = nxagentDisplay;
+    eventSelection.requestor = X->xselectionrequest.requestor;
+    eventSelection.selection = X->xselectionrequest.selection;
+    eventSelection.target = X->xselectionrequest.target;
+    eventSelection.time = X->xselectionrequest.time;
+
+    result = XSendEvent(nxagentDisplay,
+                        eventSelection.requestor,
+                        False,
+                        0L,
+                        (XEvent *) &eventSelection);
+
+    #ifdef DEBUG
+    if (result == BadValue || result == BadWindow)
+    {
+      fprintf(stderr, "nxagentRequestSelection: WARNING! XSendEvent failed.\n");
+    }
+    else
+    {
+      fprintf(stderr, "nxagentRequestSelection: XSendEvent sent to window [0x%lx].\n",
+                  eventSelection.requestor);
+    }
+    #endif
+
+    return;
+  }
+
+  /*
+   * This is necessary in nxagentGetClipboardWindow.
+   */
+
+  nxagentLastRequestedSelection = X->xselectionrequest.selection;
+
+  while ((i < nxagentMaxSelections) &&
+            (lastSelectionOwner[i].selection != X->xselectionrequest.selection))
+  {
+    i++;
+  }
+
+  if (i < nxagentMaxSelections)
+  {
+    if ((lastClientWindowPtr != NULL) && (lastSelectionOwner[i].client != NULL))
+    {
+      XConvertSelection(nxagentDisplay, CurrentSelections[i].selection,
+                            X->xselectionrequest.target, serverCutProperty,
+                                serverWindow, lastClientTime);
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentRequestSelection: Sent XConvertSelection.\n");
+      #endif
+    }
+    else
+    {
+      if (lastSelectionOwner[i].client != NULL && 
+             nxagentOption(Clipboard) != ClipboardClient)
+      {
+        xEvent x;
+
+        lastServerProperty = X->xselectionrequest.property;
+        lastServerRequestor = X->xselectionrequest.requestor;
+        lastServerTarget = X->xselectionrequest.target;
+        lastServerTime = X->xselectionrequest.time;
+
+        x.u.u.type = SelectionRequest;
+        x.u.selectionRequest.time = GetTimeInMillis();
+        x.u.selectionRequest.owner = lastSelectionOwner[i].window;
+
+        /*
+         * Fictitious window.
+         */
+
+        x.u.selectionRequest.requestor = WindowTable[0]->drawable.id;
+
+        /*
+         * Don't send the same window, some programs are
+         * clever and verify cut and paste operations
+         * inside the same window and don't Notify at all.
+         *
+         * x.u.selectionRequest.requestor = lastSelectionOwnerWindow;
+         */
+
+        x.u.selectionRequest.selection = CurrentSelections[i].selection;
+
+        /*
+         * x.u.selectionRequest.target = X->xselectionrequest.target;
+         */
+
+        x.u.selectionRequest.target = XA_STRING;
+        x.u.selectionRequest.property = clientCutProperty;
+
+        (void) TryClientEvents(lastSelectionOwner[i].client, &x, 1,
+                               NoEventMask, NoEventMask /* CantBeFiltered */,
+                               NullGrab);
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentRequestSelection: Executed TryClientEvents with clientCutProperty.\n");
+        #endif
+      }
+      else
+      {
+        /*
+         * Probably we must to send a Notify
+         * to requestor with property None.
+         */
+
+        eventSelection.type = SelectionNotify;
+        eventSelection.send_event = True;
+        eventSelection.display = nxagentDisplay;
+        eventSelection.requestor = X->xselectionrequest.requestor;
+        eventSelection.selection = X->xselectionrequest.selection;
+        eventSelection.target = X->xselectionrequest.target;
+        eventSelection.property = None;
+        eventSelection.time = X->xselectionrequest.time;
+
+        result = XSendEvent(nxagentDisplay,
+                            eventSelection.requestor,
+                            False,
+                            0L,
+                            (XEvent *) &eventSelection);
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentRequestSelection: Executed XSendEvent with property None.\n");
+        #endif
+      }
+    }
+  }
+}
+
+void nxagentSendSelectionNotify(Atom property)
+{
+  xEvent x;
+
+  #ifdef DEBUG
+  fprintf (stderr, "nxagentSendSelectionNotify: Sending event to client [%d].\n",
+               lastClientClientPtr -> index);
+  #endif
+
+  x.u.u.type = SelectionNotify;
+
+  x.u.selectionNotify.time = lastClientTime;
+  x.u.selectionNotify.requestor = lastClientRequestor;
+  x.u.selectionNotify.selection = lastClientSelection;
+  x.u.selectionNotify.target = lastClientTarget;
+
+  x.u.selectionNotify.property = property;
+
+  TryClientEvents(lastClientClientPtr, &x, 1, NoEventMask,
+                      NoEventMask , NullGrab);
+
+  return;
+}
+
+void nxagentTransferSelection(int resource)
+{
+  int result;
+
+  if (lastClientClientPtr -> index != resource)
+  {
+    #ifdef DEBUG
+    fprintf (stderr, "nxagentTransferSelection: WARNING! Inconsistent resource [%d] with current client [%d].\n",
+                 resource, lastClientClientPtr -> index);
+    #endif
+
+    nxagentSendSelectionNotify(None);
+
+    lastClientWindowPtr = NULL;
+    lastClientStage = SelectionStageNone;
+
+    return;
+  }
+
+  switch (lastClientStage)
+  {
+    case SelectionStageQuerySize:
+    {
+      /*
+       * Don't get data yet, just get size. We skip
+       * this stage in current implementation and
+       * go straight to the data.
+       */
+
+      nxagentLastClipboardClient = NXGetCollectPropertyResource(nxagentDisplay);
+
+      if (nxagentLastClipboardClient == -1)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentTransferSelection: WARNING! Asyncronous GetProperty queue full.\n");
+        #endif
+
+        result = -1;
+      }
+      else
+      {
+        result = NXCollectProperty(nxagentDisplay,
+                                   nxagentLastClipboardClient,
+                                   serverWindow,
+                                   serverCutProperty,
+                                   0,
+                                   0,
+                                   False,
+                                   AnyPropertyType);
+      }
+
+      if (result == -1)
+      {
+        #ifdef DEBUG
+        fprintf (stderr, "nxagentTransferSelection: Aborting selection notify procedure for client [%d].\n",
+                     lastClientClientPtr -> index);
+        #endif
+
+        nxagentSendSelectionNotify(None);
+
+        lastClientWindowPtr = NULL;
+        lastClientStage = SelectionStageNone;
+
+        return;
+      }
+
+      #ifdef DEBUG
+      fprintf (stderr, "nxagentTransferSelection: Setting stage to [%d] for client [%d].\n",
+                   SelectionStageWaitSize, lastClientClientPtr -> index);
+      #endif
+
+      lastClientStage = SelectionStageWaitSize;
+
+      break;
+    }
+    case SelectionStageQueryData:
+    {
+      /*
+       * Request the selection data now.
+       */
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentTransferSelection: Getting property content from remote server.\n");
+      #endif
+
+      nxagentLastClipboardClient = NXGetCollectPropertyResource(nxagentDisplay);
+
+      if (nxagentLastClipboardClient == -1)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentTransferSelection: WARNING! Asyncronous GetProperty queue full.\n");
+        #endif
+
+        result = -1;
+      }
+      else
+      {
+        result = NXCollectProperty(nxagentDisplay,
+                                   nxagentLastClipboardClient,
+                                   serverWindow,
+                                   serverCutProperty,
+                                   0,
+                                   lastClientPropertySize,
+                                   False,
+                                   AnyPropertyType);
+      }
+
+      if (result == -1)
+      {
+        #ifdef DEBUG
+        fprintf (stderr, "nxagentTransferSelection: Aborting selection notify procedure for client [%d].\n",
+                     lastClientClientPtr -> index);
+        #endif
+
+        nxagentSendSelectionNotify(None);
+
+        lastClientWindowPtr = NULL;
+        lastClientStage = SelectionStageNone;
+
+        return;
+      }
+
+      #ifdef DEBUG
+      fprintf (stderr, "nxagentTransferSelection: Setting stage to [%d] for client [%d].\n",
+                   SelectionStageWaitData, lastClientClientPtr -> index);
+      #endif
+
+      lastClientStage = SelectionStageWaitData;
+
+      break;
+    }
+    default:
+    {
+      #ifdef DEBUG
+      fprintf (stderr, "nxagentTransferSelection: WARNING! Inconsistent state [%d] for client [%d].\n",
+                   lastClientStage, lastClientClientPtr -> index);
+      #endif
+
+      break;
+    }
+  }
+}
+
+void nxagentCollectPropertyEvent(int resource)
+{
+  Atom                  atomReturnType;
+  int                   resultFormat;
+  unsigned long         ulReturnItems;
+  unsigned long         ulReturnBytesLeft;
+  unsigned char         *pszReturnData = NULL;
+  int                   result;
+
+  /*
+   * We have received the notification so
+   * we can safely retrieve data from the
+   * client structure.
+   */
+
+  result = NXGetCollectedProperty(nxagentDisplay,
+                                  resource,
+                                  &atomReturnType,
+                                  &resultFormat,
+                                  &ulReturnItems,
+                                  &ulReturnBytesLeft,
+                                  &pszReturnData);
+
+  nxagentLastClipboardClient = -1;
+
+  if (result == 0)
+  {
+    #ifdef DEBUG
+    fprintf (stderr, "nxagentCollectPropertyEvent: Failed to get reply data for client [%d].\n",
+                 lastClientClientPtr -> index);
+    #endif
+
+    nxagentSendSelectionNotify(None);
+
+    lastClientWindowPtr = NULL;
+    lastClientStage = SelectionStageNone;
+
+    if (pszReturnData != NULL)
+    {
+      XFree(pszReturnData);
+    }
+
+    return;
+  }
+
+  switch (lastClientStage)
+  {
+    case SelectionStageWaitSize:
+    {
+      #ifdef DEBUG
+      fprintf (stderr, "nxagentCollectPropertyEvent: Got size notify event for client [%d].\n",
+                   lastClientClientPtr -> index);
+      #endif
+
+      if (ulReturnBytesLeft == 0)
+      {
+        #ifdef DEBUG
+        fprintf (stderr, "nxagentCollectPropertyEvent: Aborting selection notify procedure for client [%d].\n",
+                     lastClientClientPtr -> index);
+        #endif
+
+        nxagentSendSelectionNotify(None);
+
+        lastClientWindowPtr = NULL;
+        lastClientStage = SelectionStageNone;
+
+        if (pszReturnData != NULL)
+        {
+          Xfree(pszReturnData);
+        }
+
+        return;
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentCollectPropertyEvent: Got property size from remote server.\n");
+      #endif
+
+      /*
+       * Request the selection data now.
+       */
+
+      lastClientPropertySize = ulReturnBytesLeft;
+      lastClientStage = SelectionStageQueryData;
+
+      nxagentTransferSelection(resource);
+
+      break;
+    }
+    case SelectionStageWaitData:
+    {
+      #ifdef DEBUG
+      fprintf (stderr, "nxagentCollectPropertyEvent: Got data notify event for client [%d].\n",
+                   lastClientClientPtr -> index);
+      #endif
+
+      if (ulReturnBytesLeft != 0)
+      {
+        #ifdef DEBUG
+        fprintf (stderr, "nxagentCollectPropertyEvent: Aborting selection notify procedure for client [%d].\n",
+                     lastClientClientPtr -> index);
+        #endif
+
+        nxagentSendSelectionNotify(None);
+
+        lastClientWindowPtr = NULL;
+        lastClientStage = SelectionStageNone;
+
+        if (pszReturnData != NULL)
+        {
+          Xfree(pszReturnData);
+        }
+
+        return;
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentCollectPropertyEvent: Got property content from remote server.\n");
+      #endif
+
+      ChangeWindowProperty(lastClientWindowPtr,
+                           lastClientProperty,
+                           lastClientTarget,
+                           resultFormat, PropModeReplace,
+                           ulReturnItems, pszReturnData, 1);
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentCollectPropertyEvent: Selection property [%s] changed to [%s]\n",
+                   validateString(NameForAtom(lastClientProperty)), pszReturnData);
+      #endif
+
+      nxagentSendSelectionNotify(lastClientProperty);
+
+      /*
+       * Enable further requests from clients.
+       */
+
+      lastClientWindowPtr = NULL;
+      lastClientStage = SelectionStageNone;
+
+      break;
+    }
+    default:
+    {
+      #ifdef DEBUG
+      fprintf (stderr, "nxagentCollectPropertyEvent: WARNING! Inconsistent state [%d] for client [%d].\n",
+                   lastClientStage, lastClientClientPtr -> index);
+      #endif
+
+      break;
+    }
+  }
+
+  XFree(pszReturnData);
+  pszReturnData = NULL;
+}
+
+void nxagentNotifySelection(XEvent *X)
+{
+  int result;
+
+  XSelectionEvent eventSelection;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentNotifySelection: Got called.\n");
+  #endif
+
+  if (agentClipboardStatus != 1)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentNotifySelection: SelectionNotify event.\n");
+  #endif
+
+  if (lastClientWindowPtr != NULL)
+  {
+    if ((lastClientStage == SelectionStageNone) && (X->xselection.property == serverCutProperty))
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentNotifySelection: Starting selection transferral for client [%d].\n",
+                  lastClientClientPtr -> index);
+      #endif
+
+      /*
+       * The state machine is able to work in two phases. In the first
+       * phase we get the size of property data, in the second we get
+       * the actual data. We save a round-trip by requesting a prede-
+       * termined amount of data in a single GetProperty and by discar-
+       * ding the remaining part. This is not the optimal solution (we
+       * could get the remaining part if it doesn't fit in a single
+       * reply) but, at least with text, it should work in most situa-
+       * tions.
+       */
+
+      lastClientStage = SelectionStageQueryData;
+      lastClientPropertySize = 262144;
+
+      nxagentTransferSelection(lastClientClientPtr -> index);
+    }
+    else
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentNotifySelection: WARNING! Resetting selection transferral for client [%d].\n",
+                  lastClientClientPtr -> index);
+      #endif
+
+      nxagentSendSelectionNotify(None);
+
+      lastClientWindowPtr = NULL;
+      lastClientStage = SelectionStageNone;
+    }
+
+    return;
+  }
+  else
+  {
+    int i = 0;
+
+    while ((i < nxagentMaxSelections) && (lastSelectionOwner[i].selection != X->xselection.selection))
+    {
+      i++;
+    }
+
+    if (i < nxagentMaxSelections)
+    {
+      if ((lastSelectionOwner[i].client != NULL) &&
+             (lastSelectionOwner[i].windowPtr != NULL) &&
+                 (X->xselection.property == clientCutProperty))
+      {
+        Atom            atomReturnType;
+        int             resultFormat;
+        unsigned long   ulReturnItems;
+        unsigned long   ulReturnBytesLeft;
+        unsigned char   *pszReturnData = NULL;
+
+        result = GetWindowProperty(lastSelectionOwner[i].windowPtr, clientCutProperty, 0, 0, False,
+                                       AnyPropertyType, &atomReturnType, &resultFormat,
+                                           &ulReturnItems, &ulReturnBytesLeft, &pszReturnData);
+
+        if (result == BadAlloc || result == BadAtom ||
+                result == BadMatch || result == BadValue ||
+                    result == BadWindow)
+        {
+          fprintf (stderr, "Client GetProperty failed error =");
+          lastServerProperty = None;
+          switch (result)
+          {
+            case BadAtom:
+                 fprintf (stderr, "BadAtom\n");
+                 break;
+            case BadValue:
+                 fprintf (stderr, "BadValue\n");
+                 break;
+            case BadWindow:
+                 fprintf (stderr, "BadWindow\n");
+                 break;
+          }
+        }
+        else
+        {
+          result = GetWindowProperty(lastSelectionOwner[i].windowPtr, clientCutProperty, 0,
+                                         ulReturnBytesLeft, False, AnyPropertyType, &atomReturnType,
+                                             &resultFormat, &ulReturnItems, &ulReturnBytesLeft,
+                                                 &pszReturnData);
+
+          if (result == BadAlloc || result == BadAtom ||
+                  result == BadMatch || result == BadValue ||
+                      result == BadWindow)
+          {
+            fprintf (stderr, "SelectionNotify - XChangeProperty failed\n");
+
+            lastServerProperty = None;
+          }
+          else
+          {
+            result = XChangeProperty(nxagentDisplay,
+                                     lastServerRequestor,
+                                     lastServerProperty,
+                                     lastServerTarget,
+                                     8,
+                                     PropModeReplace,
+                                     pszReturnData,
+                                     ulReturnItems);
+          }
+
+          /*
+           * if (pszReturnData)
+           * {
+           *   free(pszReturnData);
+           *   pszReturnData=NULL;
+           * }
+           */
+
+        }
+
+        eventSelection.type = SelectionNotify;
+        eventSelection.send_event = True;
+        eventSelection.display = nxagentDisplay;
+        eventSelection.requestor = lastServerRequestor;
+
+        eventSelection.selection = X->xselection.selection;
+
+        /*
+         * eventSelection.target = X->xselection.target;
+         */
+
+        eventSelection.target = lastServerTarget;
+        eventSelection.property = lastServerProperty;
+        eventSelection.time = lastServerTime;
+
+        /*
+         * eventSelection.time = CurrentTime;
+         * eventSelection.time = lastServerTime;
+         */
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentNotifySelection: Sending event to requestor.\n");
+        #endif
+
+        result = XSendEvent(nxagentDisplay,
+                             eventSelection.requestor,
+                             False,
+                             0L,
+                             (XEvent *) &eventSelection);
+
+        if (result == BadValue || result == BadWindow)
+        {
+          fprintf (stderr, "SelectionRequest - XSendEvent failed\n");
+        }
+
+        lastServerRequestor = None; /* allow further request */
+      }
+    }
+  }
+}
+
+/*
+ * Acquire selection so we don't get selection
+ * requests from real X clients.
+ */
+
+void nxagentResetSelectionOwner()
+{
+  int i;
+
+  if (lastServerRequestor != None)
+  {
+    #ifdef TEST
+    fprintf (stderr, "nxagentResetSelectionOwner: WARNING! Requestor window [0x%lx] already found.\n",
+                 lastServerRequestor);
+    #endif
+
+    return;
+  }
+
+  /*
+   * Only for PRIMARY and CLIPBOARD selections.
+   */
+
+  for (i = 0; i < nxagentMaxSelections; i++)
+  {
+    XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime);
+
+    fprintf (stderr, "nxagentResetSelectionOwner: Reset clipboard state.\n");
+
+    lastSelectionOwner[i].client = NULL;
+    lastSelectionOwner[i].window = None;
+    lastSelectionOwner[i].windowPtr = NULL;
+    lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+  }
+
+  lastClientWindowPtr = NULL;
+  lastClientStage = SelectionStageNone;
+
+  lastServerRequestor = None;
+
+  return;
+}
+
+void nxagentSetSelectionOwner(Selection *pSelection)
+{
+  int i;
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentSetSelectionOwner: Got called.\n");
+  #endif
+
+  if (agentClipboardStatus != 1)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentSetSelectionOwner: Setting selection owner to window [0x%lx].\n",
+              serverWindow);
+  #endif
+
+  #ifdef TEST
+  if (lastServerRequestor != None)
+  {
+    fprintf (stderr, "nxagentSetSelectionOwner: WARNING! Requestor window [0x%lx] already found.\n",
+                 lastServerRequestor);
+  }
+  #endif
+
+  /*
+   * Only for PRIMARY and CLIPBOARD selections.
+   */
+
+  for (i = 0; i < nxagentMaxSelections; i++)
+  {
+    if (pSelection->selection == CurrentSelections[i].selection)
+    {
+      XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, serverWindow, CurrentTime);
+
+      lastSelectionOwner[i].client = pSelection->client;
+      lastSelectionOwner[i].window = pSelection->window;
+      lastSelectionOwner[i].windowPtr = pSelection->pWin;
+      lastSelectionOwner[i].lastTimeChanged = GetTimeInMillis();
+    }
+  }
+
+  lastClientWindowPtr = NULL;
+  lastClientStage = SelectionStageNone;
+
+  lastServerRequestor = None;
+
+/*
+FIXME
+
+   if (XGetSelectionOwner(nxagentDisplay,pSelection->selection)==serverWindow)
+   {
+      fprintf (stderr, "NXdispatch: SetSelectionOwner OK\n");
+
+      lastSelectionOwnerSelection = pSelection;
+      lastSelectionOwnerClient = pSelection->client;
+      lastSelectionOwnerWindow = pSelection->window;
+      lastSelectionOwnerWindowPtr = pSelection->pWin;
+
+      lastClientWindowPtr = NULL;
+      lastClientStage     = SelectionStageNone;
+
+      lastServerRequestor = None;
+   }
+   else fprintf (stderr, "nxagentSetSelectionOwner: SetSelectionOwner failed\n");
+*/
+}
+
+void nxagentNotifyConvertFailure(ClientPtr client, Window requestor,
+                                     Atom selection, Atom target, Time time)
+{
+  xEvent x;
+
+/*
+FIXME: Why this pointer can be not a valid
+       client pointer?
+*/
+  if (clients[client -> index] != client)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentNotifyConvertFailure: WARNING! Invalid client pointer.");
+    #endif
+
+    return;
+  }
+
+  x.u.u.type = SelectionNotify;
+  x.u.selectionNotify.time = time;
+  x.u.selectionNotify.requestor = requestor;
+  x.u.selectionNotify.selection = selection;
+  x.u.selectionNotify.target = target;
+  x.u.selectionNotify.property = None;
+
+  (void) TryClientEvents(client, &x, 1, NoEventMask,
+                           NoEventMask , NullGrab);
+}
+
+int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
+                                Window requestor, Atom property, Atom target, Time time)
+{
+  char *strTarget;
+  int i;
+
+  if (agentClipboardStatus != 1 ||
+           nxagentOption(Clipboard) == ClipboardServer)
+  {
+    return 0;
+  }
+
+  /*
+   * There is a client owner on the agent side, let normal stuff happen.
+   */
+
+  /*
+   * Only for PRIMARY and CLIPBOARD selections.
+   */
+
+  for (i = 0; i < nxagentMaxSelections; i++)
+  {
+    if ((selection == CurrentSelections[i].selection) &&
+           (lastSelectionOwner[i].client != NULL))
+    {
+      return 0;
+    }
+  }
+
+  if (lastClientWindowPtr != NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentConvertSelection: lastClientWindowPtr != NULL.\n");
+    #endif
+
+    if ((GetTimeInMillis() - lastClientReqTime) > 5000)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentConvertSelection: timeout expired on last request, "
+                        "notifying failure to client\n");
+      #endif
+
+      nxagentNotifyConvertFailure(lastClientClientPtr, lastClientRequestor,
+                                     lastClientSelection, lastClientTarget, lastClientTime);
+
+      lastClientWindowPtr = NULL;
+      lastClientStage = SelectionStageNone;
+    }
+    else
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentConvertSelection: got request "
+                        "before timeout expired on last request, notifying failure to client\n");
+      #endif
+
+      nxagentNotifyConvertFailure(client, requestor, selection, target, time);
+
+      return 1;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentConvertSelection: client [%d] ask for sel [%s] "
+              "on window [%lx] prop [%s] target [%s].\n",
+                  client -> index, validateString(NameForAtom(selection)), requestor,
+                      validateString(NameForAtom(property)), validateString(NameForAtom(target)));
+  #endif
+
+  strTarget = NameForAtom(target);
+
+  if (strTarget == NULL)
+  {
+    return 1;
+  }
+
+  if (target == clientTARGETS)
+  {
+    Atom xa_STRING[3];
+    xEvent x;
+
+    xa_STRING[0] = XA_STRING;
+    xa_STRING[1] = clientTEXT;
+    xa_STRING[2] = clientCOMPOUND_TEXT;
+
+    ChangeWindowProperty(pWin,
+                         property,
+                         target,
+                         sizeof(Atom)*8,
+                         PropModeReplace,
+                         3,
+                         &xa_STRING, 1);
+
+    x.u.u.type = SelectionNotify;
+    x.u.selectionNotify.time = time;
+    x.u.selectionNotify.requestor = requestor;
+    x.u.selectionNotify.selection = selection;
+    x.u.selectionNotify.target = target;
+    x.u.selectionNotify.property = property;
+
+    (void) TryClientEvents(client, &x, 1, NoEventMask,
+                           NoEventMask , NullGrab);
+
+    return 1;
+  }
+
+  if (target == MakeAtom("TIMESTAMP", 9, 1))
+  {
+    xEvent x;
+    int i = 0;
+
+    while ((i < NumCurrentSelections) &&
+              CurrentSelections[i].selection != selection) i++;
+
+    if (i < NumCurrentSelections)
+    {
+      ChangeWindowProperty(pWin,
+                           property,
+                           target,
+                           32,
+                           PropModeReplace,
+                           1,
+                           (unsigned char *) &lastSelectionOwner[i].lastTimeChanged,
+                           1);
+
+      x.u.u.type = SelectionNotify;
+      x.u.selectionNotify.time = time;
+      x.u.selectionNotify.requestor = requestor;
+      x.u.selectionNotify.selection = selection;
+      x.u.selectionNotify.target = target;
+      x.u.selectionNotify.property = property;
+  
+      (void) TryClientEvents(client, &x, 1, NoEventMask,
+                             NoEventMask , NullGrab);
+  
+      return 1;
+
+    }
+  }
+
+  if (lastClientClientPtr == client && (GetTimeInMillis() - lastClientReqTime < 5000))
+  {
+    /*
+     * The same client made consecutive requests
+     * of clipboard contents with less than 5
+     * seconds time interval between them.
+     */
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentConvertSelection: Consecutives request from client [%p] selection [%ld] "
+                "elapsed time [%lu] clientAccum [%d]\n", (void *) client, selection,
+                    GetTimeInMillis() - lastClientReqTime, clientAccum);
+    #endif
+
+    clientAccum++;
+  }
+  else
+  {
+    if (lastClientClientPtr != client)
+    {
+      clientAccum = 0;
+    }
+  }
+
+  if ((target == clientTEXT) || (target == XA_STRING) || (target == clientCOMPOUND_TEXT))
+  {
+    lastClientWindowPtr = pWin;
+    lastClientStage = SelectionStageNone;
+    lastClientRequestor = requestor;
+    lastClientClientPtr = client;
+    lastClientTime = time;
+    lastClientProperty = property;
+    lastClientSelection = selection;
+    lastClientTarget = target;
+
+    lastClientReqTime = (GetTimeInMillis() - lastClientReqTime) > 5000 ?
+                          GetTimeInMillis() : lastClientReqTime;
+
+    if (selection == MakeAtom("CLIPBOARD", 9, 0))
+    {
+      selection = lastSelectionOwner[nxagentClipboardSelection].selection;
+    }
+
+    XConvertSelection(nxagentDisplay, selection, XA_STRING, serverCutProperty,
+                         serverWindow, CurrentTime);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentConvertSelection: Sent XConvertSelection with target=[%s], property [%s]\n",
+                validateString(NameForAtom(target)), validateString(NameForAtom(property)));
+    #endif
+
+    return 1;
+  }
+  else
+  {
+    xEvent x;
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentConvertSelection: Xserver generates a SelectionNotify event "
+               "to the requestor with property None.\n");
+    #endif
+
+    x.u.u.type = SelectionNotify;
+    x.u.selectionNotify.time = time;
+    x.u.selectionNotify.requestor = requestor;
+    x.u.selectionNotify.selection = selection;
+    x.u.selectionNotify.target = target;
+    x.u.selectionNotify.property = None;
+    (void) TryClientEvents(client, &x, 1, NoEventMask, NoEventMask , NullGrab);
+    return 1;
+  }
+  return 0;
+}
+
+int nxagentSendNotify(xEvent *event)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentSendNotify: Got called.\n");
+  #endif
+
+  if (agentClipboardStatus != 1)
+  {
+    return 0;
+  }
+
+  if (event->u.selectionNotify.property == clientCutProperty)
+  {
+    XSelectionEvent x;
+    int result;
+
+    /*
+     * Setup selection notify event to real server.
+     */
+
+    x.type = SelectionNotify;
+    x.send_event = True;
+    x.display = nxagentDisplay;
+    x.requestor = serverWindow;
+
+    /*
+     * On real server, the right CLIPBOARD atom is
+     * XInternAtom(nxagentDisplay, "CLIPBOARD", 1).
+     */
+
+    if (event->u.selectionNotify.selection == MakeAtom("CLIPBOARD", 9, 0))
+    {
+      x.selection = lastSelectionOwner[nxagentClipboardSelection].selection;
+    }
+    else
+    {
+      x.selection = event->u.selectionNotify.selection;
+    }
+
+    x.target = event->u.selectionNotify.target;
+    x.property = event->u.selectionNotify.property;
+    x.time = CurrentTime;
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentSendNotify: Propagating clientCutProperty.\n");
+    #endif
+
+    result = XSendEvent (nxagentDisplay, x.requestor, False,
+                             0L, (XEvent *) &x);
+
+    if (result == BadValue || result == BadWindow)
+    {
+       fprintf (stderr, "nxagentSendNotify: XSendEvent failed.\n");
+    }
+
+    return 1;
+  }
+
+  return 0;
+}
+
+WindowPtr nxagentGetClipboardWindow(Atom property, WindowPtr pWin)
+{
+  int i = 0;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentGetClipboardWindow: Got called.\n");
+  #endif
+
+  while ((i < nxagentMaxSelections) &&
+            (lastSelectionOwner[i].selection != nxagentLastRequestedSelection))
+  {
+    i++;
+  }
+
+  if ((i < nxagentMaxSelections) && (property == clientCutProperty) &&
+          (lastSelectionOwner[i].windowPtr != NULL))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentGetClipboardWindow: Returning last clipboard owner window.\n");
+    #endif
+
+    return lastSelectionOwner[i].windowPtr;
+  }
+  else
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentGetClipboardWindow: Returning original target window.\n");
+    #endif
+
+    return pWin;
+  }
+
+}
+
+int nxagentInitClipboard(WindowPtr pWin)
+{
+  int i;
+  Window iWindow = nxagentWindow(pWin);
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentInitClipboard: Got called.\n");
+  #endif
+
+  if (lastSelectionOwner != NULL)
+  {
+    xfree(lastSelectionOwner);
+    lastSelectionOwner = NULL;
+  }
+
+  lastSelectionOwner = (SelectionOwner *) xalloc(2 * sizeof(SelectionOwner));
+
+  if (lastSelectionOwner == NULL)
+  {
+    FatalError("nxagentInitClipboard: Failed to allocate memory for the clipboard selections.\n");
+  }
+
+  nxagentClipboardAtom = nxagentAtoms[10];   /* CLIPBOARD */
+  nxagentTimestampAtom = nxagentAtoms[11];   /* TIMESTAMP */
+
+  lastSelectionOwner[nxagentPrimarySelection].selection = XA_PRIMARY;
+  lastSelectionOwner[nxagentPrimarySelection].client = NullClient;
+  lastSelectionOwner[nxagentPrimarySelection].window = WindowTable[0]->drawable.id;
+  lastSelectionOwner[nxagentPrimarySelection].windowPtr = NULL;
+  lastSelectionOwner[nxagentPrimarySelection].lastTimeChanged = GetTimeInMillis();
+
+  lastSelectionOwner[nxagentClipboardSelection].selection = nxagentClipboardAtom;
+  lastSelectionOwner[nxagentClipboardSelection].client = NullClient;
+  lastSelectionOwner[nxagentClipboardSelection].window = WindowTable[0]->drawable.id;
+  lastSelectionOwner[nxagentClipboardSelection].windowPtr = NULL;
+  lastSelectionOwner[nxagentClipboardSelection].lastTimeChanged = GetTimeInMillis();
+
+  #ifdef NXAGENT_TIMESTAMP
+  {
+    extern unsigned long startTime;
+
+    fprintf(stderr, "nxagentInitClipboard: Initializing start [%d] milliseconds.\n",
+            GetTimeInMillis() - startTime);
+  }
+  #endif
+
+  agentClipboardStatus = 0;
+  serverWindow = iWindow;
+
+  /*
+   * Local property to hold pasted data.
+   */
+
+  serverCutProperty = nxagentAtoms[5];  /* NX_CUT_BUFFER_SERVER */
+  serverTARGETS = nxagentAtoms[6];  /* TARGETS */
+  serverTEXT = nxagentAtoms[7];  /* TEXT */
+
+  if (serverCutProperty == None)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentInitClipboard: PANIC! Could not create NX_CUT_BUFFER_SERVER atom\n");
+    #endif
+
+    return -1;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitClipboard: Setting owner of selection [%s][%d] on window 0x%lx\n",
+              "NX_CUT_BUFFER_SERVER", (int) serverCutProperty, iWindow);
+  #endif
+
+  XSetSelectionOwner(nxagentDisplay, serverCutProperty, iWindow, CurrentTime);
+
+  if (nxagentSessionId[0])
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentInitClipboard: setting the ownership of %s to %lx"
+                " and registering for PropertyChangeMask events\n",
+                    validateString(XGetAtomName(nxagentDisplay, nxagentAtoms[10])), iWindow);
+    #endif
+
+    XSetSelectionOwner(nxagentDisplay, nxagentAtoms[10], iWindow, CurrentTime);
+    pWin -> eventMask |= PropertyChangeMask;
+    nxagentChangeWindowAttributes(pWin, CWEventMask);
+  }
+
+  if (nxagentReconnectTrap)
+  {
+    /*
+     * Only for PRIMARY and CLIPBOARD selections.
+     */
+
+    for (i = 0; i < nxagentMaxSelections; i++)
+    {
+      if (lastSelectionOwner[i].client && lastSelectionOwner[i].window)
+      {
+        XSetSelectionOwner(nxagentDisplay, lastSelectionOwner[i].selection, iWindow, CurrentTime);
+      }
+    }
+  }
+  else
+  {
+    lastSelectionOwner[nxagentPrimarySelection].client = NULL;
+    lastSelectionOwner[nxagentClipboardSelection].client = NULL;
+
+    lastServerRequestor = None;
+
+    lastClientWindowPtr = NULL;
+    lastClientStage = SelectionStageNone;
+    lastClientReqTime = GetTimeInMillis();
+
+    clientCutProperty = MakeAtom(szAgentNX_CUT_BUFFER_CLIENT,
+                                         strlen(szAgentNX_CUT_BUFFER_CLIENT), 1);
+    clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True);
+    clientTEXT = MakeAtom(szAgentTEXT, strlen(szAgentTEXT), True);
+    clientCOMPOUND_TEXT = MakeAtom(szAgentCOMPOUND_TEXT, strlen(szAgentCOMPOUND_TEXT), True);
+
+    if (clientCutProperty == None)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentInitClipboard: PANIC! "
+                  "Could not create NX_CUT_BUFFER_CLIENT atom.\n");
+      #endif
+
+      return -1;
+    }
+  }
+
+  agentClipboardStatus = 1;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentInitClipboard: Clipboard initialization completed.\n");
+  #endif
+
+  #ifdef NXAGENT_TIMESTAMP
+  {
+    extern unsigned long startTime;
+
+    fprintf(stderr, "nxagentInitClipboard: initializing ends [%d] milliseconds.\n",
+                GetTimeInMillis() - startTime);
+  }
+  #endif
+
+  return 1;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
new file mode 100644
index 000000000..e4bcbf65e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -0,0 +1,46 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Clipboard_H__
+#define __Clipboard_H__
+
+/*
+ * Create the NX_CUT_BUFFER_CLIENT atom and
+ * initialize the required property to exchange
+ * data with the X server.
+ */
+
+extern int nxagentInitClipboard(WindowPtr pWindow);
+
+/*
+ * Called whenever a client or a window is
+ * destroyed to let the clipboard code to
+ * release any pointer to the referenced
+ * structures.
+ */
+
+extern void nxagentClearClipboard(ClientPtr pClient, WindowPtr pWindow);
+
+extern void nxagentSetSelectionOwner(Selection *pSelection);
+extern int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
+                                      Window requestor, Atom property, Atom target, Time time);
+
+void nxagentClearSelection();
+void nxagentRequestSelection();
+void nxagentNotifySelection();
+
+#endif /* __Clipboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
new file mode 100644
index 000000000..75758679f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -0,0 +1,577 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "../../include/window.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "resource.h"
+
+#include "Agent.h"
+
+
+#include "Display.h"
+#include "Screen.h"
+#include "Colormap.h"
+#include "Visual.h"
+#include "Windows.h"
+#include "Args.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+static ColormapPtr InstalledMaps[MAXSCREENS];
+
+static Bool nxagentInstalledDefaultColormap = False;
+
+Bool nxagentReconnectAllColormap(void *p0);
+
+Bool nxagentCreateColormap(ColormapPtr pCmap)
+{
+  VisualPtr pVisual;
+  XColor *colors;
+  int i, ncolors;
+  Pixel red, green, blue;
+  Pixel redInc, greenInc, blueInc;
+
+  Visual *visual;
+  int class;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateColormap: Going to create new colormap.\n");
+  #endif
+
+  pVisual = pCmap->pVisual;
+  ncolors = pVisual->ColormapEntries;
+
+  pCmap->devPriv = (pointer)xalloc(sizeof(nxagentPrivColormap));
+
+  if (((visual = nxagentVisual(pVisual))) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreateColormap: WARNING: Visual not found. Using default visual.\n");
+    #endif
+
+    visual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+    class = nxagentVisuals[nxagentDefaultVisualIndex].class;
+  }
+  else
+  {
+    class = pVisual->class;
+  }
+
+
+  nxagentColormapPriv(pCmap)->colormap =
+    XCreateColormap(nxagentDisplay,
+                    nxagentDefaultWindows[pCmap->pScreen->myNum],
+                    visual,
+                    (class & DynamicClass) ?
+                    AllocAll : AllocNone);
+
+  switch (class) {
+  case StaticGray: /* read only */
+    colors = (XColor *)xalloc(ncolors * sizeof(XColor));
+    for (i = 0; i < ncolors; i++)
+      colors[i].pixel = i;
+    XQueryColors(nxagentDisplay, nxagentColormap(pCmap), colors, ncolors);
+    for (i = 0; i < ncolors; i++) {
+      pCmap->red[i].co.local.red = colors[i].red;
+      pCmap->red[i].co.local.green = colors[i].red;
+      pCmap->red[i].co.local.blue = colors[i].red;
+    }
+    xfree(colors);
+    break;
+
+  case StaticColor: /* read only */
+    colors = (XColor *)xalloc(ncolors * sizeof(XColor));
+    for (i = 0; i < ncolors; i++)
+      colors[i].pixel = i;
+    XQueryColors(nxagentDisplay, nxagentColormap(pCmap), colors, ncolors);
+    for (i = 0; i < ncolors; i++) {
+      pCmap->red[i].co.local.red = colors[i].red;
+      pCmap->red[i].co.local.green = colors[i].green;
+      pCmap->red[i].co.local.blue = colors[i].blue;
+    }
+    xfree(colors);
+    break;
+
+  case TrueColor: /* read only */
+    colors = (XColor *)xalloc(ncolors * sizeof(XColor));
+    red = green = blue = 0L;
+    redInc = lowbit(pVisual->redMask);
+    greenInc = lowbit(pVisual->greenMask);
+    blueInc = lowbit(pVisual->blueMask);
+    for (i = 0; i < ncolors; i++) {
+      colors[i].pixel = red | green | blue;
+      red += redInc;
+      if (red > pVisual->redMask) red = 0L;
+      green += greenInc;
+      if (green > pVisual->greenMask) green = 0L;
+      blue += blueInc;
+      if (blue > pVisual->blueMask) blue = 0L;
+    }
+    XQueryColors(nxagentDisplay, nxagentColormap(pCmap), colors, ncolors);
+    for (i = 0; i < ncolors; i++) {
+      pCmap->red[i].co.local.red = colors[i].red;
+      pCmap->green[i].co.local.green = colors[i].green;
+      pCmap->blue[i].co.local.blue = colors[i].blue;
+    }
+    xfree(colors);
+    break;
+
+  case GrayScale: /* read and write */
+    break;
+
+  case PseudoColor: /* read and write */
+    break;
+
+  case DirectColor: /* read and write */
+    break;
+  }
+
+  return True;
+}
+
+void nxagentDestroyColormap(ColormapPtr pCmap)
+{
+  XFreeColormap(nxagentDisplay, nxagentColormap(pCmap));
+  xfree(pCmap->devPriv);
+}
+
+#define SEARCH_PREDICATE \
+  (nxagentWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
+
+static int nxagentCountInstalledColormapWindows(WindowPtr pWin, pointer ptr)
+{
+  nxagentInstalledColormapWindows *icws = (nxagentInstalledColormapWindows *) ptr;
+
+  int i;
+
+  for (i = 0; i < icws->numCmapIDs; i++)
+    if (SEARCH_PREDICATE) {
+      icws->numWindows++;
+      return WT_DONTWALKCHILDREN;
+    }
+
+  return WT_WALKCHILDREN;
+}
+
+static int nxagentGetInstalledColormapWindows(WindowPtr pWin, pointer ptr)
+{
+  nxagentInstalledColormapWindows *icws = (nxagentInstalledColormapWindows *)ptr;
+  int i;
+
+  for (i = 0; i < icws->numCmapIDs; i++)
+    if (SEARCH_PREDICATE) {
+      icws->windows[icws->index++] = nxagentWindow(pWin);
+      return WT_DONTWALKCHILDREN;
+    }
+
+  return WT_WALKCHILDREN;
+}
+
+static Window *nxagentOldInstalledColormapWindows = NULL;
+static int nxagentNumOldInstalledColormapWindows = 0;
+
+static Bool nxagentSameInstalledColormapWindows(Window *windows, int numWindows)
+{
+  if (nxagentNumOldInstalledColormapWindows != numWindows)
+    return False;
+
+  if (nxagentOldInstalledColormapWindows == windows)
+    return True;
+
+  if (nxagentOldInstalledColormapWindows == NULL || windows == NULL)
+    return False;
+
+  if (memcmp(nxagentOldInstalledColormapWindows, windows,
+	   numWindows * sizeof(Window)))
+    return False;
+
+  return True;
+}
+
+void nxagentSetInstalledColormapWindows(ScreenPtr pScreen)
+{
+  nxagentInstalledColormapWindows icws;
+  int numWindows;
+
+  icws.cmapIDs = (Colormap *)xalloc(pScreen->maxInstalledCmaps *
+				    sizeof(Colormap));
+  icws.numCmapIDs = nxagentListInstalledColormaps(pScreen, icws.cmapIDs);
+  icws.numWindows = 0;
+  WalkTree(pScreen, nxagentCountInstalledColormapWindows, (pointer)&icws);
+  if (icws.numWindows) {
+    icws.windows = (Window *)xalloc((icws.numWindows + 1) * sizeof(Window));
+    icws.index = 0;
+    WalkTree(pScreen, nxagentGetInstalledColormapWindows, (pointer)&icws);
+    icws.windows[icws.numWindows] = nxagentDefaultWindows[pScreen->myNum];
+    numWindows = icws.numWindows + 1;
+  }
+  else {
+    icws.windows = NULL;
+    numWindows = 0;
+  }
+
+  xfree(icws.cmapIDs);
+
+  if (!nxagentSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
+    if (nxagentOldInstalledColormapWindows)
+      xfree(nxagentOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+    {
+      int i;
+      Window64 *windows = (Window64 *)xalloc(numWindows * sizeof(Window64));
+
+      for(i = 0; i < numWindows; ++i)
+	  windows[i] = icws.windows[i];
+      XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+			    windows, numWindows);
+      xfree(windows);
+    }
+#else
+    XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+			  icws.windows, numWindows);
+#endif
+
+    nxagentOldInstalledColormapWindows = icws.windows;
+    nxagentNumOldInstalledColormapWindows = icws.numWindows;
+
+#ifdef DUMB_WINDOW_MANAGERS
+    /*
+      This code is for dumb window managers.
+      This will only work with default local visual colormaps.
+      */
+    if (icws.numWindows)
+      {
+	WindowPtr pWin;
+	Visual *visual;
+	ColormapPtr pCmap;
+
+	pWin = nxagentWindowPtr(icws.windows[0]);
+	visual = nxagentVisualFromID(pScreen, wVisual(pWin));
+
+	if (visual == nxagentDefaultVisual(pScreen))
+	  pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin),
+					      RT_COLORMAP);
+	else
+	  pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
+					      RT_COLORMAP);
+
+	XSetWindowColormap(nxagentDisplay,
+			   nxagentDefaultWindows[pScreen->myNum],
+			   nxagentColormap(pCmap));
+      }
+#endif /* DUMB_WINDOW_MANAGERS */
+  }
+  else
+    if (icws.windows) xfree(icws.windows);
+}
+
+void nxagentSetScreenSaverColormapWindow(ScreenPtr pScreen)
+{
+  if (nxagentOldInstalledColormapWindows)
+    xfree(nxagentOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+  {
+    Window64 window;
+
+    window = nxagentScreenSaverWindows[pScreen->myNum];
+    XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+			  &window, 1);
+    nxagentScreenSaverWindows[pScreen->myNum] = window;
+  }
+#else
+  XSetWMColormapWindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+			&nxagentScreenSaverWindows[pScreen->myNum], 1);
+#endif /* _XSERVER64 */
+
+  nxagentOldInstalledColormapWindows = NULL;
+  nxagentNumOldInstalledColormapWindows = 0;
+
+  nxagentDirectUninstallColormaps(pScreen);
+}
+
+void nxagentDirectInstallColormaps(ScreenPtr pScreen)
+{
+  int i, n;
+  Colormap pCmapIDs[MAXCMAPS];
+
+  if (!nxagentDoDirectColormaps) return;
+
+  n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+  for (i = 0; i < n; i++) {
+    ColormapPtr pCmap;
+
+    pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
+    if (pCmap)
+      XInstallColormap(nxagentDisplay, nxagentColormap(pCmap));
+  }
+}
+
+void nxagentDirectUninstallColormaps(ScreenPtr pScreen)
+{
+  int i, n;
+  Colormap pCmapIDs[MAXCMAPS];
+
+  if (!nxagentDoDirectColormaps) return;
+
+  n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+  for (i = 0; i < n; i++) {
+    ColormapPtr pCmap;
+
+    pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
+    if (pCmap)
+      XUninstallColormap(nxagentDisplay, nxagentColormap(pCmap));
+  }
+}
+
+void nxagentInstallColormap(ColormapPtr pCmap)
+{
+  int index;
+  ColormapPtr pOldCmap;
+
+  index = pCmap->pScreen->myNum;
+  pOldCmap = InstalledMaps[index];
+
+  if(pCmap != pOldCmap)
+    {
+      nxagentDirectUninstallColormaps(pCmap->pScreen);
+
+      /* Uninstall pInstalledMap. Notify all interested parties. */
+      if(pOldCmap != (ColormapPtr)None)
+	WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
+
+      InstalledMaps[index] = pCmap;
+      WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
+
+      nxagentSetInstalledColormapWindows(pCmap->pScreen);
+      nxagentDirectInstallColormaps(pCmap->pScreen);
+    }
+}
+
+void nxagentUninstallColormap(ColormapPtr pCmap)
+{
+  int index;
+  ColormapPtr pCurCmap;
+
+  index = pCmap->pScreen->myNum;
+  pCurCmap = InstalledMaps[index];
+
+  if(pCmap == pCurCmap)
+    {
+      if ((unsigned int)pCmap->mid != pCmap->pScreen->defColormap)
+        {
+	  pCurCmap = (ColormapPtr)LookupIDByType(pCmap->pScreen->defColormap,
+						 RT_COLORMAP);
+	  (*pCmap->pScreen->InstallColormap)(pCurCmap);
+        }
+    }
+}
+
+int nxagentListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIds)
+{
+  if (nxagentInstalledDefaultColormap)
+  {
+    *pCmapIds = InstalledMaps[pScreen->myNum]->mid;
+
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+void nxagentStoreColors(ColormapPtr pCmap, int nColors, xColorItem *pColors)
+{
+  if (pCmap->pVisual->class & DynamicClass)
+#ifdef _XSERVER64
+  {
+    int i;
+    XColor *pColors64 = (XColor *)xalloc(nColors * sizeof(XColor) );
+
+    for(i = 0; i < nColors; ++i)
+    {
+      pColors64[i].pixel = pColors[i].pixel;
+      pColors64[i].red = pColors[i].red;
+      pColors64[i].green = pColors[i].green;
+      pColors64[i].blue = pColors[i].blue;
+      pColors64[i].flags = pColors[i].flags;
+    }
+    XStoreColors(nxagentDisplay, nxagentColormap(pCmap), pColors64, nColors);
+    xfree(pColors64);
+  }
+#else
+    XStoreColors(nxagentDisplay, nxagentColormap(pCmap),
+		 (XColor *)pColors, nColors);
+#endif
+}
+
+void nxagentResolveColor(unsigned short *pRed, unsigned short *pGreen,
+                             unsigned short *pBlue, VisualPtr pVisual)
+{
+  int shift;
+  unsigned int lim;
+
+  shift = 16 - pVisual->bitsPerRGBValue;
+  lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+  if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
+    {
+      /* rescale to rgb bits */
+      *pRed = ((*pRed >> shift) * 65535) / lim;
+      *pGreen = ((*pGreen >> shift) * 65535) / lim;
+      *pBlue = ((*pBlue >> shift) * 65535) / lim;
+    }
+  else if (pVisual->class == GrayScale)
+    {
+      /* rescale to gray then rgb bits */
+      *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+      *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+    }
+  else if (pVisual->class == StaticGray)
+    {
+      unsigned int limg;
+
+      limg = pVisual->ColormapEntries - 1;
+      /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
+      *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+      *pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
+      *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+    }
+  else
+    {
+      unsigned limr, limg, limb;
+
+      limr = pVisual->redMask >> pVisual->offsetRed;
+      limg = pVisual->greenMask >> pVisual->offsetGreen;
+      limb = pVisual->blueMask >> pVisual->offsetBlue;
+      /* rescale to [0..limN] then [0..65535] then rgb bits */
+      *pRed = ((((((*pRed * (limr + 1)) >> 16) *
+		  65535) / limr) >> shift) * 65535) / lim;
+      *pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
+		    65535) / limg) >> shift) * 65535) / lim;
+      *pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
+		   65535) / limb) >> shift) * 65535) / lim;
+    }
+}
+
+Bool nxagentCreateDefaultColormap(ScreenPtr pScreen)
+{
+  VisualPtr   pVisual;
+  ColormapPtr pCmap;
+  unsigned short zero = 0, ones = 0xFFFF;
+  Pixel wp, bp;
+
+  for (pVisual = pScreen->visuals;
+       pVisual->vid != pScreen->rootVisual;
+       pVisual++);
+
+  if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
+		     (pVisual->class & DynamicClass) ? AllocNone : AllocAll, 0)
+      != Success)
+    return False;
+
+  wp = pScreen->whitePixel;
+  bp = pScreen->blackPixel;
+  if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
+       Success) ||
+      (AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) !=
+       Success))
+    return FALSE;
+  pScreen->whitePixel = wp;
+  pScreen->blackPixel = bp;
+  (*pScreen->InstallColormap)(pCmap);
+
+  nxagentInstalledDefaultColormap = True;
+
+  return True;
+}
+
+static void nxagentReconnectColormap(pointer p0, XID x1, pointer p2)
+{
+  ColormapPtr pCmap = (ColormapPtr)p0;
+  Bool* pBool = (Bool*)p2;
+  VisualPtr pVisual;
+
+  #ifdef NXAGENT_RECONNECT_COLORMAP_DEBUG
+  fprintf(stderr, "nxagentReconnectColormap: %p\n", pCmap);
+  #endif
+
+  if (!*pBool || !pCmap)
+    return;
+
+  pVisual = pCmap -> pVisual;
+
+  nxagentColormapPriv(pCmap)->colormap =
+      XCreateColormap(nxagentDisplay,
+          nxagentDefaultWindows[pCmap->pScreen->myNum],
+              nxagentVisual(pVisual),
+                  (pVisual->class & DynamicClass) ?
+                      AllocAll : AllocNone);
+
+  #ifdef NXAGENT_RECONNECT_COLORMAP_DEBUG
+  fprintf(stderr, "nxagentReconnectColormap: %p - ID %xl\n",
+              pCmap, nxagentColormap(pCmap));
+  #endif
+}
+
+Bool nxagentReconnectAllColormap(void *p0)
+{
+  int flexibility;
+  int cid;
+  Bool success = True;
+  flexibility = *(int*)p0;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_COLORMAP_DEBUG)
+  fprintf(stderr, "nxagentReconnectAllColormap\n");
+  #endif
+
+  for (cid = 0; (cid < MAXCLIENTS) && success; cid++)
+  {
+    if (clients[cid] && success)
+    {
+      FindClientResourcesByType(clients[cid], RT_COLORMAP, nxagentReconnectColormap, &success);
+    }
+  }
+
+  return success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
new file mode 100644
index 000000000..b0cb2dc5e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
@@ -0,0 +1,84 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Color_H__
+#define __Color_H__
+
+#define DUMB_WINDOW_MANAGERS
+
+#define MAXCMAPS 1
+#define MINCMAPS 1
+
+typedef struct {
+  Colormap colormap;
+} nxagentPrivColormap;
+
+typedef struct {
+  int numCmapIDs;
+  Colormap *cmapIDs;
+  int numWindows;
+  Window *windows;
+  int index;
+} nxagentInstalledColormapWindows;
+
+#define nxagentColormapPriv(pCmap) \
+  ((nxagentPrivColormap *)((pCmap)->devPriv))
+
+#define nxagentColormap(pCmap) (nxagentColormapPriv(pCmap)->colormap)
+
+#define nxagentPixel(pixel) (pixel)
+
+Bool nxagentCreateColormap(ColormapPtr pCmap);
+
+void nxagentDestroyColormap(ColormapPtr pCmap);
+
+void nxagentSetInstalledColormapWindows(ScreenPtr pScreen);
+
+void nxagentSetScreenSaverColormapWindow(ScreenPtr pScreen);
+
+void nxagentDirectInstallColormaps(ScreenPtr pScreen);
+
+void nxagentDirectUninstallColormaps(ScreenPtr pScreen);
+
+void nxagentInstallColormap(ColormapPtr pCmap);
+
+void nxagentUninstallColormap(ColormapPtr pCmap);
+
+int nxagentListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIds);
+
+void nxagentStoreColors(ColormapPtr pCmap, int nColors, xColorItem *pColors);
+
+void nxagentResolveColor(unsigned short *pRed, unsigned short *pGreen,
+                             unsigned short *pBlue, VisualPtr pVisual);
+
+Bool nxagentCreateDefaultColormap(ScreenPtr pScreen);
+
+#endif /* __Color_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
new file mode 100644
index 000000000..9bdbac1b1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
@@ -0,0 +1,209 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "Agent.h"
+#include "Screen.h"
+#include "Display.h"
+#include "Options.h"
+#include "Windows.h"
+
+#undef  NXAGENT_UPGRADE
+
+#ifndef NXAGENT_UPGRADE
+
+#include "NXcomposite.h"
+
+#else
+
+#include "composite.h"
+
+#endif
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Set if the composite extension is supported
+ * by the remote display.
+ */
+
+int nxagentCompositeEnable = UNDEFINED;
+
+void nxagentCompositeExtensionInit()
+{
+  /*
+   * Set the flag only if the initialization
+   * completes.
+   */
+
+  nxagentCompositeEnable = 0;
+
+  if (nxagentOption(Composite) == 1)
+  {
+    int eventBase, errorBase;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositeExtensionInit: Checking if the composite extension is supported.\n");
+    #endif
+
+    if (XCompositeQueryExtension(nxagentDisplay, &eventBase, &errorBase) == 1)
+    {
+      /*
+       * At the moment we don't need to care
+       * the version of the extension.
+       */
+
+      #ifdef TEST
+
+      int major = -1;
+      int minor = -1;
+
+      XCompositeQueryVersion(nxagentDisplay, &major, &minor);
+
+      fprintf(stderr, "nxagentCompositeExtensionInit: The remote display supports version [%d] "
+                  "minor [%d].\n", major, minor);
+
+      if (major < 0 || minor < 2)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentCompositeExtensionInit: WARNING! Potentially incompatible version "
+                    "[%d] minor [%d] detected.\n", major, minor);
+        #endif
+      }
+
+      #endif
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentCompositeExtensionInit: Enabling the use of the composite extension.\n");
+      #endif
+
+      nxagentCompositeEnable = 1;
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentCompositeExtensionInit: Composite extension not supported on this display.\n");
+    }
+    #endif
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentRenderExtensionInit: Use of the composite extension not enabled.\n");
+  }
+  #endif
+}
+
+void nxagentRedirectDefaultWindows()
+{
+  int i;
+
+  if (nxagentOption(Rootless) == 1 ||
+          nxagentCompositeEnable == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentRedirectDefaultWindows: Not redirecting default "
+                "windows with rootless mode [%d] and composite [%d].\n",
+                    nxagentOption(Rootless), nxagentCompositeEnable);
+    #endif
+
+    return;
+  }
+
+  for (i = 0; i < screenInfo.numScreens; i++)
+  {
+    WindowPtr pWin = WindowTable[i];
+
+    ScreenPtr pScreen = pWin -> drawable.pScreen;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentRedirectDefaultWindows: WARNING! Redirecting default window id [%ld] "
+                "to off-screen memory.\n", (long int)nxagentDefaultWindows[pScreen->myNum]);
+    #endif
+
+    /*
+     * When trying to redirect only the top level window,
+     * and not the subwindows, we incur in a strange be-
+     * haviour. The top level is unmapped, mapped, unmap-
+     * ped and then reparented. This at first makes the
+     * agent think that the window manager is gone, then
+     * the agent window disappears. To make thinks even
+     * more weird, this happens only at reconnection.
+     */
+ 
+    XCompositeRedirectSubwindows(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                                     CompositeRedirectAutomatic);
+  }
+}
+
+void nxagentRedirectWindow(WindowPtr pWin)
+{
+  if (nxagentOption(Rootless) == 0 ||
+          nxagentCompositeEnable == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentRedirectWindow: Not redirecting window id [%ld] "
+                "to off-screen memory with rootless mode [%d] and composite [%d].\n",
+                    nxagentWindow(pWin), nxagentOption(Rootless),
+                        nxagentCompositeEnable);
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRedirectWindow: WARNING! Redirecting window id [%ld] "
+              "to off-screen memory.\n", (long int)nxagentWindow(pWin));
+  #endif
+
+  XCompositeRedirectWindow(nxagentDisplay, nxagentWindow(pWin),
+                               CompositeRedirectAutomatic);
+
+  nxagentWindowPriv(pWin) -> isRedirected = 1;
+}
+
+void nxagentUnredirectWindow(WindowPtr pWin)
+{
+  if (nxagentWindowPriv(pWin) -> isRedirected == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentRedirectWindow: Disabling redirection of window id [%ld] "
+                "to off-screen memory.\n", nxagentWindow(pWin));
+    #endif
+
+    XCompositeUnredirectWindow(nxagentDisplay, nxagentWindow(pWin),
+                                   CompositeRedirectAutomatic);
+
+    nxagentWindowPriv(pWin) -> isRedirected = 0;
+  }
+  #ifdef WARNING
+  else
+  {
+    fprintf(stderr, "nxagentUnredirectWindow: WARNING! The window id [%ld] "
+                "was not redirected.\n", (long int)nxagentWindow(pWin));
+  }
+  #endif
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.h b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
new file mode 100644
index 000000000..5ec1e9888
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
@@ -0,0 +1,51 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Composite_H__
+#define __Composite_H__
+
+/*
+ * Set if the extension is present and
+ * its use is enabled.
+ */
+
+extern int nxagentCompositeEnable;
+
+/*
+ * Query the composite extension on the
+ * remote display and set the flag if
+ * it is supported.
+ */
+
+void nxagentCompositeExtensionInit(void);
+
+/*
+ * Let the X server redirect the window
+ * on the off-screen memory.
+ */
+
+void nxagentRedirectDefaultWindows(void);
+
+/*
+ * Enable or disabel the redirection of
+ * the given window.
+ */
+
+void nxagentRedirectWindow(WindowPtr pWin);
+void nxagentUnredirectWindow(WindowPtr pWin);
+
+#endif /* __Composite_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
new file mode 100644
index 000000000..3ca29fa5e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
@@ -0,0 +1,601 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "inputstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Options.h"
+#include "Screen.h"
+#include "Cursor.h"
+#include "Image.h"
+#include "Visual.h"
+#include "Keyboard.h"
+#include "Args.h"
+#include "Windows.h"
+#include "Events.h"
+#include "Render.h"
+#include "Client.h"
+
+#include "windowstr.h"
+#include "resource.h"
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Defined in Display.c. There are huge
+ * problems mixing the GC definition in
+ * Xlib with the server code. This must
+ * be reworked.
+ */
+
+extern XlibGC nxagentBitmapGC;
+
+/*
+ * From NXevents.c.
+ */
+
+extern CursorPtr GetSpriteCursor(void);
+
+void nxagentConstrainCursor(ScreenPtr pScreen, BoxPtr pBox)
+{
+  #ifdef TEST
+
+  int width, height;
+
+  width  = nxagentOption(RootWidth);
+  height = nxagentOption(RootHeight);
+
+  if (pBox->x1 <= 0 && pBox->y1 <= 0 &&
+          pBox->x2 >= width && pBox->y2 >= height)
+  {
+    fprintf(stderr, "nxagentConstrainCursor: Called with box [%d,%d,%d,%d]. "
+                "Skipping the operation.\n", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentConstrainCursor: WARNING! Called with box [%d,%d,%d,%d].\n",
+                pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+  }
+
+  #endif
+}
+
+void nxagentCursorLimits(ScreenPtr pScreen, CursorPtr pCursor,
+                             BoxPtr pHotBox, BoxPtr pTopLeftBox)
+{
+  *pTopLeftBox = *pHotBox;
+}
+
+Bool nxagentDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+
+  /*
+   * Don't define the root cursor
+   * so that nxagent root window
+   * inherits the parent's cursor.
+   */
+
+  Cursor cursor;
+
+  cursor = (pCursor != rootCursor) ? nxagentCursor(pCursor, pScreen): None;
+
+  if (nxagentOption(Rootless) == False)
+  {
+    XDefineCursor(nxagentDisplay,
+                      nxagentInputWindows[pScreen -> myNum],
+                          cursor);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentDisplayCursor: Called for cursor at [%p] with private [%p].\n",
+                (void *) pCursor, pCursor->devPriv[pScreen->myNum]);
+    #endif
+  }
+
+  return True;
+}
+
+Bool nxagentRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+  XImage *image;
+  Pixmap source, mask;
+  XColor fg_color, bg_color;
+  unsigned long valuemask;
+  XGCValues values;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRealizeCursor: Called for cursor at [%p].\n", (void *) pCursor);
+  #endif
+
+  valuemask = GCFunction |
+              GCPlaneMask |
+              GCForeground |
+              GCBackground |
+              GCClipMask;
+
+  values.function = GXcopy;
+  values.plane_mask = AllPlanes;
+  values.foreground = 1L;
+  values.background = 0L;
+  values.clip_mask = None;
+
+  XChangeGC(nxagentDisplay, nxagentBitmapGC, valuemask, &values);
+
+  source = XCreatePixmap(nxagentDisplay,
+                         nxagentDefaultWindows[pScreen->myNum],
+                         pCursor->bits->width,
+                         pCursor->bits->height,
+                         1);
+
+  mask = XCreatePixmap(nxagentDisplay,
+                       nxagentDefaultWindows[pScreen->myNum],
+                       pCursor->bits->width,
+                       pCursor->bits->height,
+                       1);
+
+  image = XCreateImage(nxagentDisplay,
+                       nxagentDefaultVisual(pScreen),
+                       1, XYBitmap, 0,
+                       (char *)pCursor->bits->source,
+                       pCursor->bits->width,
+                       pCursor->bits->height,
+                       BitmapPad(nxagentDisplay), 0);
+
+  /*
+   * If we used nxagentImageNormalize() here,
+   * we'd swap our own cursor data in place.
+   * Change byte_order and bitmap_bit_order
+   * in the image struct to let Xlib do the
+   * swap for us.
+   */
+
+  image -> byte_order = IMAGE_BYTE_ORDER;
+  image -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+  NXCleanImage(image);
+
+  XPutImage(nxagentDisplay, source, nxagentBitmapGC, image,
+                0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+  XFree(image);
+
+  image = XCreateImage(nxagentDisplay,
+                       nxagentDefaultVisual(pScreen),
+                       1, XYBitmap, 0,
+                       (char *)pCursor->bits->mask,
+                       pCursor->bits->width,
+                       pCursor->bits->height,
+                       BitmapPad(nxagentDisplay), 0);
+
+  image -> byte_order = IMAGE_BYTE_ORDER;
+  image -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+  NXCleanImage(image);
+
+  XPutImage(nxagentDisplay, mask, nxagentBitmapGC, image,
+            0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+  XFree(image);
+
+  fg_color.red = pCursor->foreRed;
+  fg_color.green = pCursor->foreGreen;
+  fg_color.blue = pCursor->foreBlue;
+
+  bg_color.red = pCursor->backRed;
+  bg_color.green = pCursor->backGreen;
+  bg_color.blue = pCursor->backBlue;
+
+  pCursor->devPriv[pScreen->myNum] = (pointer) xalloc(sizeof(nxagentPrivCursor));
+
+  nxagentCursorPriv(pCursor, pScreen)->cursor =
+         XCreatePixmapCursor(nxagentDisplay, source, mask, &fg_color,
+                                 &bg_color, pCursor->bits->xhot, pCursor->bits->yhot);
+
+  nxagentCursorUsesRender(pCursor, pScreen) = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRealizeCursor: Set cursor private at [%p] cursor is [%ld].\n",
+              (void *) nxagentCursorPriv(pCursor, pScreen),
+                  nxagentCursorPriv(pCursor, pScreen) -> cursor);
+  #endif
+
+  XFreePixmap(nxagentDisplay, source);
+  XFreePixmap(nxagentDisplay, mask);
+
+  return True;
+}
+
+Bool nxagentUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+  if (nxagentCursorUsesRender(pCursor, pScreen))
+  {
+    PicturePtr pPicture = nxagentCursorPicture(pCursor, pScreen);
+
+    FreePicture(pPicture, pPicture -> id);
+  }
+
+  if (nxagentCursor(pCursor, pScreen) != None)
+  {
+    XFreeCursor(nxagentDisplay, nxagentCursor(pCursor, pScreen));
+
+    nxagentCursor(pCursor, pScreen) = None;
+  }
+
+  xfree(nxagentCursorPriv(pCursor, pScreen));
+
+  return True;
+}
+
+void nxagentRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
+                              Bool displayed)
+{
+  XColor fg_color, bg_color;
+
+  fg_color.red = pCursor->foreRed;
+  fg_color.green = pCursor->foreGreen;
+  fg_color.blue = pCursor->foreBlue;
+
+  bg_color.red = pCursor->backRed;
+  bg_color.green = pCursor->backGreen;
+  bg_color.blue = pCursor->backBlue;
+
+  XRecolorCursor(nxagentDisplay,
+                 nxagentCursor(pCursor, pScreen),
+                 &fg_color, &bg_color);
+}
+
+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;
+}
+
+void nxagentReconnectCursor(pointer p0, XID x1, pointer p2)
+{
+  Bool* pBool = (Bool*)p2;
+  CursorPtr pCursor = (CursorPtr) p0;
+
+  AnimCurPtr ac;
+  int j;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectCursor:  pCursor at [%p]\n", pCursor);
+  #endif
+
+  #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+  fprintf(stderr, "nxagentReconnectCursor:  pCursor at [%p]\n", pCursor);
+  #endif
+
+  if (!*pBool || !pCursor)
+  {
+    return;
+  }
+
+  if (nxagentCursorPriv(pCursor, nxagentDefaultScreen) == 0)
+  {
+    if (nxagentIsAnimCursor(pCursor))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentReconnectCursor: nxagentIsAnimCursor   pCursor at [%p]\n", pCursor);
+      #endif
+
+      ac = nxagentGetAnimCursor(pCursor);
+
+      for (j = 0; j < ac->nelt; j++)
+      {
+        nxagentReconnectCursor (ac->elts[j].pCursor, x1, p2);
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentReconnectCursor: Iteration [%d]   pCursor at [%p]\n", j, ac->elts[j].pCursor);
+        #endif
+      }
+    }
+  }
+
+  else
+  {
+    if (nxagentCursorUsesRender(pCursor, nxagentDefaultScreen))
+    {
+      PicturePtr pPicture = nxagentCursorPicture(pCursor, nxagentDefaultScreen);
+      int ret = 1;
+
+      nxagentReconnectPicture(pPicture, 0, &ret);
+
+      nxagentRenderRealizeCursor(nxagentDefaultScreen, pCursor);
+    }
+    else
+    {
+      xfree(nxagentCursorPriv(pCursor, nxagentDefaultScreen));
+      if (!nxagentRealizeCursor(nxagentDefaultScreen, pCursor))
+      {
+        fprintf(stderr, "nxagentReconnectCursor: nxagentRealizeCursor failed\n");
+        *pBool = False;
+      }
+    }
+  }
+
+  #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+  fprintf(stderr, "nxagentReconnectCursor: %p - ID %lx\n", pCursor, nxagentCursor(pCursor, nxagentDefaultScreen));
+  #endif
+}
+
+/*
+ * The parameter is ignored at the moment.
+ */
+
+void nxagentReDisplayCurrentCursor()
+{
+  CursorPtr pCursor = GetSpriteCursor();
+
+  if (pCursor &&
+          nxagentCursorPriv(pCursor, nxagentDefaultScreen) &&
+              nxagentCursor(pCursor, nxagentDefaultScreen))
+  {
+    nxagentDisplayCursor(nxagentDefaultScreen, pCursor);
+  }
+}
+
+Bool nxagentReconnectAllCursor(void *p0)
+{
+  int i;
+  Bool r = True;
+
+  GrabPtr grab = inputInfo.pointer -> grab;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_CURSOR_DEBUG)
+  fprintf(stderr, "nxagentReconnectAllCursor\n");
+  #endif
+
+  for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], RT_CURSOR, nxagentReconnectCursor, &r);
+
+      #ifdef WARNING
+
+      if (r == False)
+      {
+        fprintf(stderr, "nxagentReconnectAllCursor: WARNING! Failed to recreate "
+                    "cursor for client [%d].\n", i);
+      }
+
+      #endif
+    }
+  }
+
+  if (grab)
+  {
+    nxagentReconnectCursor(grab -> cursor, 0, &r);
+  }
+
+  return r;
+}
+
+void nxagentDisconnectCursor(pointer p0, XID x1, pointer p2)
+{
+  Bool* pBool = (Bool *) p2;
+  CursorPtr pCursor = (CursorPtr) p0;
+
+  AnimCurPtr ac;
+  int j;
+
+  if (!*pBool || !pCursor)
+  {
+    return;
+  }
+
+  if (nxagentCursorPriv(pCursor, nxagentDefaultScreen) == 0)
+  {
+    if (nxagentIsAnimCursor(pCursor))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDisconnectCursor: nxagentIsAnimCursor   pCursor at [%p]\n", pCursor);
+      #endif
+
+      ac = nxagentGetAnimCursor(pCursor);
+
+      for (j = 0; j < ac->nelt; j++)
+      {
+        nxagentDisconnectCursor (ac->elts[j].pCursor, x1, p2);
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDisconnectCursor: Iteration [%d]   pCursor at [%p]\n", j, ac->elts[j].pCursor);
+        #endif
+      }
+    }
+    return;
+  }
+
+  #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+  fprintf(stderr, "nxagentDisconnectCursor: %p - ID %lx\n",
+          pCursor,
+          nxagentCursor(pCursor, nxagentDefaultScreen));
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectCursor: Called with bool [%d].\n", *pBool);
+
+  fprintf(stderr, "nxagentDisconnectCursor: Pointer to cursor is [%p] with counter [%d].\n",
+              (void *) pCursor, pCursor -> refcnt);
+
+  fprintf(stderr, "nxagentDisconnectCursor: Dummy screen is at [%p].\n",
+              (void *) nxagentDefaultScreen);
+
+  fprintf(stderr, "nxagentDisconnectCursor: Cursor private is at [%p].\n",
+              (void *) nxagentCursorPriv(pCursor, nxagentDefaultScreen));
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectCursor: Dummy screen number is [%d].\n",
+              nxagentDefaultScreen -> myNum);
+
+  fprintf(stderr, "nxagentDisconnectCursor: Cursor is [%ld].\n",
+              nxagentCursor(pCursor, nxagentDefaultScreen));
+  #endif
+
+  nxagentCursor(pCursor, nxagentDefaultScreen) = None;
+
+  if (nxagentCursorUsesRender(pCursor, nxagentDefaultScreen))
+  {
+    PicturePtr pPicture = nxagentCursorPicture(pCursor, nxagentDefaultScreen);
+    int        ret = 1;
+
+    #if defined(NXAGENT_RECONNECT_CURSOR_DEBUG) || defined(NXAGENT_RECONNECT_PICTURE_DEBUG)
+    fprintf(stderr, "nxagentDisconnectCursor: disconnecting attached picture %p\n", pPicture);
+    #endif
+
+    nxagentDisconnectPicture(pPicture, 0, &ret);
+  }
+}
+
+Bool nxagentDisconnectAllCursor()
+{
+  int i;
+  Bool r = True;
+
+  GrabPtr grab = inputInfo.pointer -> grab;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectAllCursor: Going to iterate through cursor resources.\n");
+  #endif
+
+  for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], RT_CURSOR, nxagentDisconnectCursor, &r);
+
+      #ifdef WARNING
+
+      if (r == False)
+      {
+        fprintf(stderr, "nxagentDisconnectAllCursor: WARNING! Failed to disconnect "
+                    "cursor for client [%d].\n", i);
+      }
+
+      #endif
+    }
+  }
+
+  if (grab)
+  {
+    nxagentDisconnectCursor(grab -> cursor, 0, &r);
+  }
+
+  return r;
+}
+
+
+#ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+
+void nxagentPrintCursorInfo(CursorPtr pCursor, char msg[])
+{
+  fprintf(stderr, "%s: %p - ID %lx - ref count %d\n",
+           msg, pCursor, nxagentCursor(pCursor, nxagentDefaultScreen), pCursor->refcnt);
+}
+
+void nxagentListCursor(void *p0, void *p1, void *p2)
+{
+  CursorPtr pCursor = (CursorPtr)p0;
+
+  nxagentPrintCursorInfo(pCursor, "CursorDebug:");
+}
+
+void nxagentListCursors(void)
+{
+  int i;
+  Bool r;
+
+  for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], RT_CURSOR, nxagentListCursor, &r);
+
+      #ifdef WARNING
+
+      if (r == False)
+      {
+        fprintf(stderr, "nxagentListCursors: WARNING! Failed to list "
+                    "cursor for client [%d].\n", i);
+      }
+
+      #endif
+    }
+  }
+
+  return True;
+}
+
+#endif /* NXAGENT_RECONNECT_CURSOR_DEBUG */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
new file mode 100644
index 000000000..ea1bb30f3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
@@ -0,0 +1,106 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Cursor_H__
+#define __Cursor_H__
+
+#include "cursorstr.h"
+#include "picturestr.h"
+
+typedef struct {
+  Cursor cursor;
+  PicturePtr picture;
+  int uses_render;
+  int x;
+  int y;
+} nxagentPrivCursor;
+
+/*
+ * _AnimCurElt and _AnimCur already defined in animcur.c.
+ */
+
+typedef struct _AnimCurElt {
+    CursorPtr   pCursor;
+    CARD32      delay;
+} AnimCurElt;
+
+typedef struct _AnimCur {
+    int         nelt;
+    AnimCurElt  *elts;
+} AnimCurRec, *AnimCurPtr;
+
+CursorBitsPtr nxagentAnimCursorBits;
+
+#define nxagentIsAnimCursor(c)        ((c)->bits == nxagentAnimCursorBits)
+#define nxagentGetAnimCursor(c)       ((AnimCurPtr) ((c) + 1))
+
+#define nxagentCursorPriv(pCursor, pScreen) \
+  ((nxagentPrivCursor *)((pCursor)->devPriv[pScreen->myNum]))
+
+#define nxagentCursor(pCursor, pScreen) \
+  (nxagentCursorPriv(pCursor, pScreen)->cursor)
+
+#define nxagentCursorPicture(pCursor, pScreen) \
+  (nxagentCursorPriv(pCursor, pScreen)->picture)
+
+#define nxagentCursorUsesRender(pCursor, pScreen) \
+  (nxagentCursorPriv(pCursor, pScreen)->uses_render)
+
+#define nxagentCursorXOffset(pCursor, pScreen) \
+  (nxagentCursorPriv(pCursor, pScreen)->x)
+
+#define nxagentCursorYOffset(pCursor, pScreen) \
+  (nxagentCursorPriv(pCursor, pScreen)->y)
+
+void nxagentConstrainCursor(ScreenPtr pScreen, BoxPtr pBox);
+
+void nxagentCursorLimits(ScreenPtr pScreen, CursorPtr pCursor,
+                             BoxPtr pHotBox, BoxPtr pTopLeftBox);
+
+Bool nxagentDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+Bool nxagentRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+Bool nxagentUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+void nxagentRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor,
+                              Bool displayed);
+
+Bool nxagentSetCursorPosition(ScreenPtr pScreen, int x, int y,
+                                  Bool generateEvent);
+
+void nxagentDisconnectCursor(pointer p0, XID x1, pointer p2);
+void nxagentReconnectCursor(pointer p0, XID x1, pointer p2);
+void nxagentReDisplayCurrentCursor(void);
+Bool nxagentReconnectAllCursor(void *p0);
+Bool nxagentDisconnectAllCursor(void);
+
+#endif /* __Cursor_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
new file mode 100644
index 000000000..c1db78344
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
@@ -0,0 +1,563 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "scrnintstr.h"
+#include "Agent.h"
+
+#include <X11/Xlib.h>
+
+#include "opaque.h"
+
+#include "Args.h"
+#include "Display.h"
+#include "Dialog.h"
+
+#include "NX.h"
+#include "NXlib.h"
+#include "NXalert.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+int nxagentKillDialogPid = 0;
+int nxagentSuspendDialogPid = 0;
+int nxagentRootlessDialogPid = 0;
+int nxagentPulldownDialogPid = 0;
+int nxagentFontsReplacementDialogPid = 0;
+int nxagentEnableRandRModeDialogPid = 0;
+int nxagentDisableRandRModeDialogPid = 0;
+int nxagentEnableDeferModePid = 0;
+int nxagentDisableDeferModePid = 0;
+int nxagentDisableXkbPid = 0;
+
+static int nxagentFailedReconnectionDialogPid = 0;
+
+char nxagentPulldownWindow[16];
+
+char nxagentFailedReconnectionMessage[256];
+
+void nxagentResetDialog(int pid)
+{
+  if (pid == nxagentRootlessDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting rootless dialog pid [%d].\n", nxagentRootlessDialogPid);
+    #endif
+
+    nxagentRootlessDialogPid = 0;
+  }
+  else if (pid == nxagentPulldownDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting pulldown dialog pid [%d].\n", nxagentPulldownDialogPid);
+    #endif
+
+    nxagentPulldownDialogPid = 0;
+  }
+  else if (pid == nxagentFontsReplacementDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentFontsReplacementDialog: Resetting fonts replacement dialog pid [%d].\n", 
+                nxagentFontsReplacementDialogPid);
+    #endif
+
+    nxagentFontsReplacementDialogPid = 0;
+  }
+  else if (pid == nxagentKillDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting kill dialog pid [%d].\n", nxagentKillDialogPid);
+    #endif
+
+    nxagentKillDialogPid = 0;
+  }
+  else if (pid == nxagentSuspendDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting suspend dialog pid [%d].\n", nxagentSuspendDialogPid);
+    #endif
+
+    nxagentSuspendDialogPid = 0;
+  }
+  else if (pid == nxagentFailedReconnectionDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting Failed Reconnection dialog pid [%d].\n",
+                nxagentFailedReconnectionDialogPid);
+    #endif
+
+    nxagentFailedReconnectionDialogPid = 0;
+  }
+  else if (pid == nxagentEnableRandRModeDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting RandR mode dialog pid [%d].\n",
+                nxagentEnableRandRModeDialogPid);
+    #endif
+
+    nxagentEnableRandRModeDialogPid = 0;
+  }
+  else if (pid == nxagentDisableRandRModeDialogPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting NoRandR mode dialog pid [%d].\n",
+                nxagentDisableRandRModeDialogPid);
+    #endif
+
+    nxagentDisableRandRModeDialogPid = 0;
+  }
+  else if (pid == nxagentEnableDeferModePid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting enable defer mode dialog pid [%d].\n",
+                nxagentEnableDeferModePid);
+    #endif
+
+    nxagentEnableDeferModePid = 0;
+  }
+  else if (pid == nxagentDisableDeferModePid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting disable defer mode dialog pid [%d].\n",
+                nxagentDisableDeferModePid);
+    #endif
+
+    nxagentDisableDeferModePid = 0;
+  }
+  else if (pid == nxagentDisableXkbPid)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentResetDialog: Resetting disable XKB dialog pid [%d].\n",
+                nxagentDisableXkbPid);
+    #endif
+
+    nxagentDisableXkbPid = 0;
+  }
+}
+
+void nxagentLaunchDialog(DialogType dialogType)
+{
+  char dialogDisplay[256];
+  sigset_t set, oldSet;
+  int *pid;
+  char *type;
+  char *message;
+  int local;
+  const char *window = NULL;
+
+  switch (dialogType)
+  {
+    case DIALOG_KILL_SESSION:
+    {
+      message = DIALOG_KILL_SESSION_MESSAGE;
+      type = DIALOG_KILL_SESSION_TYPE;
+      local = DIALOG_KILL_SESSION_LOCAL;
+      pid = &nxagentKillDialogPid;
+
+      break;
+    }
+    case DIALOG_SUSPEND_SESSION:
+    {
+      message = DIALOG_SUSPEND_SESSION_MESSAGE;
+      type = DIALOG_SUSPEND_SESSION_TYPE;
+      local = DIALOG_SUSPEND_SESSION_LOCAL;
+      pid = &nxagentSuspendDialogPid;
+
+      break;
+    }
+    case DIALOG_ROOTLESS:
+    {
+      message = DIALOG_ROOTLESS_MESSAGE;
+      type = DIALOG_ROOTLESS_TYPE;
+      local = DIALOG_ROOTLESS_LOCAL;
+      pid = &nxagentRootlessDialogPid;
+
+      break;
+    }
+    case DIALOG_PULLDOWN:
+    {
+      message = DIALOG_PULLDOWN_MESSAGE;
+      type = DIALOG_PULLDOWN_TYPE;
+      local = DIALOG_PULLDOWN_LOCAL;
+      pid = &nxagentPulldownDialogPid;
+      window = nxagentPulldownWindow;
+
+      break;
+    }
+    case DIALOG_FONT_REPLACEMENT:
+    {
+      message = DIALOG_FONT_REPLACEMENT_MESSAGE;
+      type = DIALOG_FONT_REPLACEMENT_TYPE;
+      local = DIALOG_FONT_REPLACEMENT_LOCAL;
+      pid = &nxagentFontsReplacementDialogPid;
+
+      break;
+    }
+    case DIALOG_FAILED_RECONNECTION:
+    {
+      message = DIALOG_FAILED_RECONNECTION_MESSAGE;
+      type = DIALOG_FAILED_RECONNECTION_TYPE;
+      local = DIALOG_FAILED_RECONNECTION_LOCAL;
+      pid = &nxagentFailedReconnectionDialogPid;
+
+      break;
+    }
+    case DIALOG_ENABLE_DESKTOP_RESIZE_MODE:
+    {
+      message = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_MESSAGE;
+      type = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_TYPE;
+      local = DIALOG_ENABLE_DESKTOP_RESIZE_MODE_LOCAL;
+      pid = &nxagentEnableRandRModeDialogPid;
+
+      break;
+    }
+    case DIALOG_DISABLE_DESKTOP_RESIZE_MODE:
+    {
+      message = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_MESSAGE;
+      type = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_TYPE;
+      local = DIALOG_DISABLE_DESKTOP_RESIZE_MODE_LOCAL;
+      pid = &nxagentDisableRandRModeDialogPid;
+
+      break;
+    }
+    case DIALOG_ENABLE_DEFER_MODE:
+    {
+      message = DIALOG_ENABLE_DEFER_MODE_MESSAGE;
+      type = DIALOG_ENABLE_DEFER_MODE_TYPE;
+      local = DIALOG_ENABLE_DEFER_MODE_LOCAL;
+      pid = &nxagentEnableDeferModePid;
+
+      break;
+    }
+    case DIALOG_DISABLE_DEFER_MODE:
+    {
+      message = DIALOG_DISABLE_DEFER_MODE_MESSAGE;
+      type = DIALOG_DISABLE_DEFER_MODE_TYPE;
+      local = DIALOG_DISABLE_DEFER_MODE_LOCAL;
+      pid = &nxagentDisableDeferModePid;
+
+      break;
+    }
+    case DIALOG_DISABLE_XKB:
+    {
+      message = DIALOG_DISABLE_XKB_MESSAGE;
+      type = DIALOG_DISABLE_XKB_TYPE;
+      local = DIALOG_DISABLE_XKB_LOCAL;
+      pid = &nxagentDisableXkbPid;
+
+      break;
+    }
+    default:
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentLaunchDialog: Unknown Dialog type [%d].\n", dialogType);
+      #endif
+
+      return;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentLaunchDialog: Launching dialog type [%d] message [%s].\n", type, message);
+  #endif
+
+  if (dialogType == DIALOG_FAILED_RECONNECTION)
+  {
+    strncpy(dialogDisplay, nxagentDisplayName, 255);
+  }
+  else
+  {
+    strcpy(dialogDisplay, ":");
+    strncat(dialogDisplay, display, 254);
+  }
+
+  *(dialogDisplay + 255) = '\0';
+
+  /*
+   * We don't want to receive SIGCHLD
+   * before we store the child pid.
+   */
+
+  sigemptyset(&set);
+
+  sigaddset(&set, SIGCHLD);
+
+  sigprocmask(SIG_BLOCK, &set, &oldSet);
+
+  *pid = NXTransDialog(nxagentDialogName, message, window,
+                           type, local, dialogDisplay);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentLaunchDialog: Launched dialog %s with pid [%d] on display %s.\n",
+              DECODE_DIALOG_TYPE(dialogType), *pid, dialogDisplay);
+  #endif
+
+  *dialogDisplay = '\0';
+
+  /*
+   * Restore the previous set of
+   * blocked signal. 
+   */
+
+  sigprocmask(SIG_SETMASK, &oldSet, NULL);
+}
+
+void nxagentPulldownDialog(Window wid)
+{
+  snprintf(nxagentPulldownWindow, 15, "%ld", (long int) wid);
+  nxagentPulldownWindow[15] = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPulldownDialog: Going to launch pulldown "
+              "dialog on window [%s].\n", nxagentPulldownWindow);
+  #endif
+
+  nxagentLaunchDialog(DIALOG_PULLDOWN);
+
+  nxagentPulldownWindow[0] = 0;
+}
+
+void nxagentFailedReconnectionDialog(int alert, char *error)
+{
+  if (alert == 0)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFailedReconnectionDialog: WARNING! No valid alert provided. "
+                "Using the default.\n");
+    #endif
+
+    alert = FAILED_RESUME_DISPLAY_ALERT;
+  }
+
+  if (NXDisplayError(nxagentDisplay) == 0 &&
+          NXTransRunning(NX_FD_ANY) == 1)
+  {
+    NXTransAlert(alert, NX_ALERT_REMOTE);
+
+    /*
+     * Make it possible to interrupt the
+     * loop with a signal.
+     */
+
+    while (NXDisplayError(nxagentDisplay) == 0 &&
+               NXTransRunning(NX_FD_ANY) == 1)
+    {
+      struct timeval timeout;
+
+      timeout.tv_sec  = 30;
+      timeout.tv_usec = 0;
+
+      NXTransContinue(&timeout);
+    }
+  }
+  else
+  {
+    int pid;
+    int status;
+    int options = 0;
+
+    snprintf(nxagentFailedReconnectionMessage, 255, "Reconnection failed: %s", error);
+
+    *(nxagentFailedReconnectionMessage + 255) = '\0';
+
+    nxagentLaunchDialog(DIALOG_FAILED_RECONNECTION);
+
+    while ((pid = waitpid(nxagentFailedReconnectionDialogPid, &status, options)) == -1 &&
+               errno == EINTR);
+
+    if (pid == -1)
+    {
+      if (errno == ECHILD)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentFailedReconnectionDialog: Got ECHILD waiting for child [%d].\n",
+                    nxagentFailedReconnectionDialogPid);
+        #endif
+
+        nxagentFailedReconnectionDialogPid = 0;
+      }
+      else
+      {
+        fprintf(stderr, "nxagentFailedReconnectionDialog: PANIC! Got unexpected error [%s] waiting "
+                    "for child [%d].\n", strerror(errno), nxagentFailedReconnectionDialogPid);
+      }
+    }
+    else if (pid > 0)
+    {
+      if (WIFSTOPPED(status))
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentFailedReconnectionDialog: Child process [%d] was stopped "
+                    "with signal [%d].\n", pid, (WSTOPSIG(status)));
+        #endif
+      }
+      else
+      {
+        #ifdef WARNING
+
+        if (WIFEXITED(status))
+        {
+          fprintf(stderr, "nxagentFailedReconnectionDialog: Child process [%d] exited "
+                      "with status [%d].\n", pid, (WEXITSTATUS(status)));
+        }
+        else if (WIFSIGNALED(status))
+        {
+          fprintf(stderr, "nxagentFailedReconnectionDialog: Child process [%d] died "
+                      "because of signal [%d].\n", pid, (WTERMSIG(status)));
+        }
+
+        #endif
+
+        nxagentResetDialog(pid);
+      }
+    }
+    #ifdef WARNING
+    else if (pid == 0)
+    {
+      fprintf(stderr, "nxagentFailedReconnectionDialog: No own child process exited.\n");
+    }
+    #endif
+  }
+}
+
+void nxagentTerminateDialog(DialogType type)
+{
+  int pid;
+
+  switch (type)
+  {
+    case DIALOG_KILL_SESSION:
+    {
+      pid = nxagentKillDialogPid;
+
+      break;
+    }
+    case DIALOG_SUSPEND_SESSION:
+    {
+      pid = nxagentSuspendDialogPid;
+
+      break;
+    }
+    case DIALOG_ROOTLESS:
+    {
+      pid = nxagentRootlessDialogPid;
+
+      break;
+    }
+    case DIALOG_PULLDOWN:
+    {
+      pid = nxagentPulldownDialogPid;
+
+      break;
+    }
+    case DIALOG_FONT_REPLACEMENT:
+    {
+      pid = nxagentFontsReplacementDialogPid;
+
+      break;
+    }
+    case DIALOG_FAILED_RECONNECTION:
+    {
+      pid = nxagentFailedReconnectionDialogPid;
+
+      break;
+    }
+    case DIALOG_ENABLE_DESKTOP_RESIZE_MODE:
+    {
+      pid = nxagentEnableRandRModeDialogPid;
+
+      break;
+    }
+    case DIALOG_DISABLE_DESKTOP_RESIZE_MODE:
+    {
+      pid = nxagentDisableRandRModeDialogPid;
+
+      break;
+    }
+    case DIALOG_ENABLE_DEFER_MODE:
+    {
+      pid = nxagentEnableDeferModePid;
+
+      break;
+    }
+    case DIALOG_DISABLE_DEFER_MODE:
+    {
+      pid = nxagentDisableDeferModePid;
+
+      break;
+    }
+    case DIALOG_DISABLE_XKB:
+    {
+      pid = nxagentDisableXkbPid;
+
+      break;
+    }
+    default:
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentTerminateDialog: Unknown dialog type [%d].\n", type);
+      #endif
+
+      return;
+    }
+  }
+
+  if (pid > 0)
+  {
+    if (kill(pid, SIGTERM) == -1)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentTerminateDialog: Failed to terminate dialog pid [%d]: %s.\n",
+                  pid, strerror(errno));
+      #endif
+    }
+  }
+  #ifdef DEBUG
+  else
+  {
+    fprintf(stderr, "nxagentTerminateDialog: Dialog type [%d] is not running.\n",
+                type);
+  }
+  #endif
+}
+
+void nxagentTerminateDialogs()
+{
+  DialogType type;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentTerminateDialogs: Terminating all the running dialogs.\n");
+  #endif
+
+  for (type = DIALOG_FIRST_TAG; type < DIALOG_LAST_TAG; type++)
+  {
+    nxagentTerminateDialog(type);
+  }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
new file mode 100644
index 000000000..135cd2df3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -0,0 +1,223 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Dialog_H__
+#define __Dialog_H__
+
+#include "X11/X.h"
+
+typedef enum
+{
+  DIALOG_FIRST_TAG,
+  DIALOG_KILL_SESSION = DIALOG_FIRST_TAG,
+  DIALOG_SUSPEND_SESSION,
+  DIALOG_ROOTLESS,
+  DIALOG_PULLDOWN,
+  DIALOG_FONT_REPLACEMENT,
+  DIALOG_ENABLE_DESKTOP_RESIZE_MODE,
+  DIALOG_DISABLE_DESKTOP_RESIZE_MODE,
+  DIALOG_FAILED_RECONNECTION,
+  DIALOG_ENABLE_DEFER_MODE,
+  DIALOG_DISABLE_DEFER_MODE,
+  DIALOG_DISABLE_XKB,
+  DIALOG_LAST_TAG
+
+} DialogType;
+
+extern int nxagentKillDialogPid;
+extern int nxagentSuspendDialogPid;
+extern int nxagentRootlessDialogPid;
+extern int nxagentPulldownDialogPid;
+extern int nxagentFontsReplacement;
+extern int nxagentEnableRandRModeDialogPid;
+extern int nxagentDisableRandRModeDialogPid;
+extern int nxagentEnableDeferModePid;
+extern int nxagentDisableDeferModePid;
+extern int nxagentDisableXkbPid;
+
+extern char nxagentFailedReconnectionMessage[];
+
+extern char nxagentPulldownWindow[];
+
+extern void nxagentLaunchDialog(DialogType type);
+extern void nxagentResetDialog(int pid);
+extern void nxagentTerminateDialog(DialogType type);
+extern void nxagentFailedReconnectionDialog(int alert, char *error);
+extern void nxagentPulldownDialog(Window);
+extern void nxagentTerminateDialogs(void);
+
+#define nxagentNoDialogIsRunning \
+    (nxagentSuspendDialogPid == 0 && \
+         nxagentKillDialogPid == 0 && \
+             nxagentEnableRandRModeDialogPid == 0 && \
+                 nxagentDisableRandRModeDialogPid == 0 && \
+                     nxagentEnableDeferModePid == 0 && \
+                         nxagentDisableDeferModePid == 0 && \
+                             nxagentDisableXkbPid == 0)
+
+#define DECODE_DIALOG_TYPE(type) \
+            ((type) == DIALOG_KILL_SESSION ? "DIALOG_KILL_SESSION" : \
+             (type) == DIALOG_SUSPEND_SESSION ? "DIALOG_SUSPEND_SESSION" : \
+             (type) == DIALOG_ROOTLESS ? "DIALOG_ROOTLESS" : \
+             (type) == DIALOG_PULLDOWN ? "DIALOG_PULLDOWN" : \
+             (type) == DIALOG_FONT_REPLACEMENT ? "DIALOG_FONT_REPLACEMENT" : \
+             (type) == DIALOG_ENABLE_DESKTOP_RESIZE_MODE ? "DIALOG_ENABLE_DESKTOP_RESIZE_MODE" :\
+             (type) == DIALOG_DISABLE_DESKTOP_RESIZE_MODE ? "DIALOG_DISABLE_DESKTOP_RESIZE_MODE" :\
+             (type) == DIALOG_FAILED_RECONNECTION ? "DIALOG_FAILED_RECONNECTION" : \
+             (type) == DIALOG_ENABLE_DEFER_MODE ? "DIALOG_ENABLE_DEFER_MODE" : \
+             (type) == DIALOG_DISABLE_DEFER_MODE ? "DIALOG_DISABLE_DEFER_MODE" : \
+             (type) == DIALOG_DISABLE_XKB ? "DIALOG_DISABLE_XKB" : \
+             "UNKNOWN_DIALOG")
+
+/*
+ * Message to be showed to users when the close
+ * button is pressed. The right message is chosen
+ * according if session does or does not run in
+ * persistent mode.
+ */
+
+#define DIALOG_KILL_SESSION_MESSAGE \
+\
+"\
+Do you really want to close the session?\
+"
+
+#define DIALOG_KILL_SESSION_TYPE "yesno"
+
+#define DIALOG_KILL_SESSION_LOCAL 0
+
+
+#define DIALOG_SUSPEND_SESSION_MESSAGE \
+\
+"\
+Press the disconnect button to disconnect the running session.\n\
+You will be able to resume the session at later time. Press the\n\
+terminate button to exit the session and close all the running\n\
+programs.\
+"
+
+#define DIALOG_SUSPEND_SESSION_TYPE "yesnosuspend"
+
+#define DIALOG_SUSPEND_SESSION_LOCAL 0
+
+
+#define DIALOG_ROOTLESS_MESSAGE \
+\
+"\
+All remote applications have been terminated.\n\
+Do you want to close the session?\
+"
+
+#define DIALOG_ROOTLESS_TYPE "yesno"
+
+#define DIALOG_ROOTLESS_LOCAL 0
+
+
+#define DIALOG_PULLDOWN_MESSAGE \
+\
+nxagentPulldownWindow
+
+#define DIALOG_PULLDOWN_TYPE "pulldown"
+
+#define DIALOG_PULLDOWN_LOCAL 0
+
+
+#define DIALOG_FONT_REPLACEMENT_MESSAGE \
+\
+"\
+Unable to retrieve all the fonts currently in use. \n\
+Missing fonts have been replaced.\
+"
+
+#define DIALOG_FONT_REPLACEMENT_TYPE "ok"
+
+#define DIALOG_FONT_REPLACEMENT_LOCAL 0
+
+
+#define DIALOG_FAILED_RECONNECTION_MESSAGE \
+\
+nxagentFailedReconnectionMessage
+
+#define DIALOG_FAILED_RECONNECTION_TYPE "ok"
+
+#define DIALOG_FAILED_RECONNECTION_LOCAL 0
+
+
+#define DIALOG_ENABLE_DESKTOP_RESIZE_MODE_MESSAGE \
+\
+"\
+The session is now running in desktop resize mode.\n\
+You can resize the desktop by simply dragging the\n\
+desktop window's border. You can press Ctrl+Alt+R\n\
+again to disable this option.\
+"
+
+#define DIALOG_ENABLE_DESKTOP_RESIZE_MODE_TYPE "ok"
+
+#define DIALOG_ENABLE_DESKTOP_RESIZE_MODE_LOCAL 0
+
+#define DIALOG_DISABLE_DESKTOP_RESIZE_MODE_MESSAGE \
+\
+"\
+The session is now running in viewport mode. You can\n\
+navigate across different areas of the desktop window\n\
+by dragging the desktop with the mouse or by using the\n\
+arrows keys while pressing Ctrl+Alt. Press Ctrl+Alt+R\n\
+again to return to the desktop resize mode.\
+"
+
+#define DIALOG_DISABLE_DESKTOP_RESIZE_MODE_TYPE "ok"
+
+#define DIALOG_DISABLE_DESKTOP_RESIZE_MODE_LOCAL 0
+
+
+#define DIALOG_ENABLE_DEFER_MODE_MESSAGE \
+\
+"\
+Deferred screen updates are now enabled. You can press\n\
+Ctrl+Alt+E again to disable this option.\
+"
+
+#define DIALOG_ENABLE_DEFER_MODE_TYPE "ok"
+
+#define DIALOG_ENABLE_DEFER_MODE_LOCAL 0
+
+
+#define DIALOG_DISABLE_DEFER_MODE_MESSAGE \
+\
+"\
+Deferred screen updates are now disabled. You can press\n\
+Ctrl+Alt+E to enable it again.\
+"
+
+#define DIALOG_DISABLE_DEFER_MODE_TYPE "ok"
+
+#define DIALOG_DISABLE_DEFER_MODE_LOCAL 0
+
+
+#define DIALOG_DISABLE_XKB_MESSAGE \
+\
+"\
+Changing layout is not allowed with your current display.\
+"
+
+#define DIALOG_DISABLE_XKB_TYPE "ok"
+
+#define DIALOG_DISABLE_XKB_LOCAL 0
+
+#endif /* __Dialog_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
new file mode 100644
index 000000000..c2e131954
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -0,0 +1,2705 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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;
+int nxagentNumDefaultColormaps;
+int *nxagentDepths;
+int nxagentNumDepths;
+XPixmapFormatValues *nxagentPixmapFormats;
+XPixmapFormatValues *nxagentRemotePixmapFormats;
+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 && 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;
+
+  nxagentPixmapFormats = xalloc(nxagentNumDepths * sizeof(XPixmapFormatValues));
+
+  for (i = 1; i <= MAXDEPTH; i++)
+  {
+    depth = 0;
+
+    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;
+
+  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;
+  }
+
+  /*
+   * 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/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h
new file mode 100644
index 000000000..d18785b60
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h
@@ -0,0 +1,179 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Display_H__
+#define __Display_H__
+
+#define MAXDEPTH 32
+#define MAXVISUALSPERDEPTH 256
+
+extern Display *nxagentDisplay;
+extern Display *nxagentShadowDisplay;
+extern XVisualInfo *nxagentVisuals;
+extern int nxagentNumVisuals;
+extern int nxagentDefaultVisualIndex;
+extern Colormap *nxagentDefaultColormaps;
+extern int nxagentNumDefaultColormaps;
+extern int *nxagentDepths;
+extern int nxagentNumDepths;
+extern XPixmapFormatValues *nxagentPixmapFormats;
+extern int nxagentNumPixmapFormats;
+extern Pixel nxagentBlackPixel;
+extern Pixel nxagentWhitePixel;
+extern Drawable nxagentDefaultDrawables[MAXDEPTH + 1];
+extern Pixmap nxagentScreenSaverPixmap;
+
+/*
+ * The "confine" window is used in nxagentConstrainCursor().
+ * We are currently overriding the original Xnest behaviour
+ * and just skip the "constrain" stuff.
+ */
+
+extern Window nxagentConfineWindow;
+
+/*
+ * Keyboard and pointer are handled as they were hardware
+ * devices, that is we translate the key codes according to
+ * our own transcripts. We inherit this behaviour from Xnest.
+ * The following mask will contain the event mask selected
+ * for the root window. All the keyboard and pointer events
+ * are enqueued to the mi that translates and posts them to
+ * managed clients.
+ */
+
+extern unsigned long nxagentEventMask;
+
+void nxagentOpenDisplay(int argc, char *argv[]);
+void nxagentWaitDisplay(void);
+void nxagentCloseDisplay(void);
+void nxagentAbortDisplay(void);
+
+void nxagentAddXConnection(void);
+void nxagentRemoveXConnection(void);
+
+Bool nxagentXServerGeometryChanged(void);
+
+/*
+ * Create the default drawables.
+ */
+
+void nxagentGetDepthsAndPixmapFormats(void);
+void nxagentSetDefaultDrawables(void);
+
+extern Bool nxagentTrue24;
+
+void nxagentBackupDisplayInfo(void);
+void nxagentCleanupBackupDisplayInfo(void);
+
+void nxagentInstallDisplayHandlers(void);
+void nxagentPostInstallDisplayHandlers(void);
+void nxagentResetDisplayHandlers(void);
+
+void nxagentInstallSignalHandlers(void);
+void nxagentPostInstallSignalHandlers(void);
+void nxagentResetSignalHandlers(void);
+
+void nxagentDisconnectDisplay(void);
+Bool nxagentReconnectDisplay(void *p0);
+
+/*
+ * Deal with the smart scheduler.
+ */
+
+#ifdef SMART_SCHEDULE
+
+#define nxagentInitTimer() \
+\
+    SmartScheduleInit();
+
+#define nxagentStopTimer() \
+\
+    if (SmartScheduleTimerStopped == 0) \
+    { \
+      SmartScheduleStopTimer(); \
+    } \
+\
+    SmartScheduleIdle = 1;
+
+#define nxagentStartTimer() \
+\
+    if (SmartScheduleTimerStopped == 1) \
+    { \
+      SmartScheduleStartTimer(); \
+    } \
+\
+      SmartScheduleIdle = 0;
+
+#define nxagentDisableTimer() \
+\
+    if (SmartScheduleTimerStopped == 0) \
+    { \
+      SmartScheduleStopTimer(); \
+    } \
+\
+    SmartScheduleDisable = 1;
+
+#endif /* #ifdef SMART_SCHEDULE */
+
+/*
+ * File descriptor currently used by
+ * Xlib for the agent display.
+ */
+
+extern int nxagentXConnectionNumber;
+
+/*
+ * File descriptor currently used by
+ * Xlib for the agent shadow display.
+ */
+
+extern int nxagentShadowXConnectionNumber;
+
+int nxagentServerOrder(void);
+
+#define nxagentClientOrder(client) \
+    ((client)->swapped ? !nxagentServerOrder() : nxagentServerOrder())
+
+/*
+ * Terminate the agent after the next
+ * dispatch loop.
+ */
+
+#define nxagentTerminateSession() \
+    do \
+    { \
+      dispatchException |= DE_TERMINATE; \
+    \
+      isItTimeToYield = TRUE; \
+    } \
+    while (0)
+
+#endif /* __Display_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
new file mode 100644
index 000000000..89cc1a846
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -0,0 +1,3201 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "dixstruct.h"
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Trap.h"
+#include "Image.h"
+#include "Drawable.h"
+#include "Client.h"
+#include "Visual.h"
+#include "Events.h"
+#include "GCs.h"
+#include "Utils.h"
+#include "Handlers.h"
+#include "Pixels.h"
+#include "Reconnect.h"
+
+#include "NXlib.h"
+
+#include "mibstorest.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+/*
+ * The list of rectangles composing a region
+ * s returned by nxagentGetOptimizedRegion-
+ * Boxes() instead of REGION_RECTS().
+ */
+
+#define USE_OPTIMIZED_BOXES
+
+/*
+ * The rectangles composing a region are de-
+ * fragmented to reduce the number of synch-
+ * ronizing PutImage's.
+ */
+
+#define ADVANCED_BOXES_DEFRAG
+
+/*
+ * If defined, send the XClearArea at the end
+ * of the loop synchronizing the shadow pixmap.
+ * In this way, large images can be splitted but
+ * the user will see more updates togheter.
+ */
+
+#undef  COLLECTED_UPDATES
+
+#ifdef ADVANCED_BOXES_DEFRAG
+#define INCLUDE_MARGIN 10
+#endif
+
+struct nxagentExposeBackground
+{
+  PixmapPtr pBackground;
+  RegionPtr pExpose;
+};
+
+RESTYPE RT_NX_CORR_BACKGROUND;
+RESTYPE RT_NX_CORR_WINDOW;
+RESTYPE RT_NX_CORR_PIXMAP;
+
+int nxagentCorruptedPixmaps     = 0;
+int nxagentCorruptedWindows     = 0;
+int nxagentCorruptedBackgrounds = 0;
+
+int nxagentForceSynchronization = 0;
+
+_nxagentSynchronizationRec nxagentSynchronization = { (DrawablePtr) NULL, 0, 0, 0, 0, 0 };
+
+RegionPtr nxagentDeferredBackgroundExposures = NullRegion;
+
+/*
+ * Predicate functions used to synchronize the
+ * content of the remote drawable with the data
+ * stored in the virtual frame-buffer.
+ */
+
+void nxagentSynchronizeDrawablePredicate(void *p0, XID x1, void *p2);
+void nxagentExposeBackgroundPredicate(void *p0, XID x1, void *p2);
+
+/*
+ * Imported from NXresource.c
+ */
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
+unsigned long nxagentGetColor(DrawablePtr pDrawable, int xPixel, int yPixel);
+unsigned long nxagentGetDrawableColor(DrawablePtr pDrawable);
+unsigned long nxagentGetRegionColor(DrawablePtr pDrawable, RegionPtr pRegion);
+
+int nxagentSynchronizeDrawable(DrawablePtr pDrawable, int wait, unsigned int breakMask, WindowPtr owner)
+{
+  int result;
+
+  pDrawable = nxagentSplitDrawable(pDrawable);
+
+  if (nxagentLosslessTrap == 0)
+  {
+    if (nxagentDrawableStatus(pDrawable) == Synchronized)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeDrawable: Drawable [%s][%p] with id [%ld] already "
+                  "synchronized.\n", nxagentDrawableType(pDrawable),
+                      (void *) pDrawable, pDrawable -> id);
+      #endif
+
+      return 0;
+    }
+  }
+
+  /*
+   * What we want here is to avoid drawing on the
+   * framebuffer and just perform the operation
+   * on the real X server. This is the purpose of
+   * the FB trap. At the same time we also want
+   * to avoid a split, so that the image will be
+   * transferred in a single operation.
+   */
+
+  nxagentFBTrap = 1;
+
+  nxagentSplitTrap = 1;
+
+  result = nxagentSynchronizeDrawableData(pDrawable, breakMask, owner);
+
+  nxagentSplitTrap = 0;
+
+  nxagentFBTrap = 0;
+
+  if (wait == DO_WAIT && nxagentSplitResource(pDrawable) != NULL)
+  {
+    nxagentWaitDrawable(pDrawable);
+  }
+
+  #ifdef TEST
+
+  if (nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    fprintf(stderr, "nxagentSynchronizeDrawable: Drawable %s [%p] with id [%ld] now synchronized.\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable, pDrawable -> id);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentSynchronizeDrawable: Drawable %s [%p] with id [%ld] not fully synchronized.\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable, pDrawable -> id);
+  }
+
+  #endif
+
+  return result;
+}
+
+int nxagentSynchronizeDrawableData(DrawablePtr pDrawable, unsigned int breakMask, WindowPtr owner)
+{
+  int width, height, depth, length;
+  unsigned int leftPad, format;
+
+  char *data = NULL;
+  DrawablePtr pSrcDrawable;
+  GCPtr pGC;
+
+  int success;
+
+  if (pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    leftPad = 0;
+
+    width  = pDrawable -> width;
+    height = pDrawable -> height;
+    depth  = pDrawable -> depth;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeDrawableData: Synchronizing drawable (%s) with geometry [%d][%d][%d].\n",
+                nxagentDrawableType(pDrawable), width, height, depth);
+    #endif
+
+    format = (depth == 1) ? XYPixmap : ZPixmap;
+
+    length = nxagentImageLength(width, height, format, leftPad, depth);
+
+    if ((data = xalloc(length)) == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentSynchronizeDrawableData: WARNING! Failed to allocate memory for the operation.\n");
+      #endif
+
+      success = 0;
+
+      goto nxagentSynchronizeDrawableDataEnd;
+    }
+
+    pSrcDrawable = (pDrawable -> type == DRAWABLE_PIXMAP ?
+                        ((DrawablePtr) nxagentVirtualPixmap((PixmapPtr) pDrawable)) :
+                            pDrawable);
+
+    /*
+     * Synchronize the whole pixmap if we need
+     * to download a fresh copy with lossless
+     * compression turned off.
+     */
+
+    if (nxagentLosslessTrap == 1)
+    {
+      pGC = nxagentGetGraphicContext(pDrawable);
+
+      if (pGC == NULL)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentSynchronizeDrawableData: WARNING! Failed to get the temporary GC.\n");
+        #endif
+
+        success = 0;
+
+        goto nxagentSynchronizeDrawableDataFree;
+      }
+
+      ValidateGC(pDrawable, pGC);
+
+      fbGetImage(pSrcDrawable, 0, 0,
+                     width, height, format, AllPlanes, data);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeDrawableData: Forcing synchronization of "
+                  "pixmap at [%p] with lossless compression.\n", (void *) pDrawable);
+      #endif
+
+      nxagentPutImage(pDrawable, pGC, depth, 0, 0,
+                          width, height, leftPad, format, data);
+
+      success = 1;
+
+      goto nxagentSynchronizeDrawableDataFree;
+    }
+    else if (nxagentReconnectTrap == 1)
+    {
+      /*
+       * The pixmap data is not synchronized unless
+       * we need it. We noticed we have to reconnect
+       * the pixmaps used by the GC's clip mask.
+       * The other data will be synchronized on demand.
+       */
+
+      if (pDrawable -> depth == 1)
+      {
+        #ifdef TEST
+
+        if (nxagentReconnectTrap == 1)
+        {
+          static int totalLength;
+          static int totalReconnectedPixmaps;
+
+          totalLength += length;
+          totalReconnectedPixmaps++;
+
+          fprintf(stderr, "nxagentSynchronizeDrawableData: Reconnecting pixmap at [%p] [%dx%d] "
+                      "Depth [%d] Size [%d]. Total size [%d]. Total reconnected pixmaps [%d].\n", 
+                          (void *) pDrawable, width, height, depth, length,
+                              totalLength, totalReconnectedPixmaps);
+        }
+
+        #endif
+
+        pGC = nxagentGetGraphicContext(pDrawable);
+
+        if (pGC == NULL)
+        {
+          #ifdef WARNING
+          fprintf(stderr, "nxagentSynchronizeDrawableData: WARNING! Failed to create the temporary GC.\n");
+          #endif
+
+          success = 0;
+
+          goto nxagentSynchronizeDrawableDataFree;
+        }
+
+        ValidateGC(pDrawable, pGC);
+
+        fbGetImage(pSrcDrawable, 0, 0,
+                       width, height, format, AllPlanes, data);
+
+        nxagentPutImage(pDrawable, pGC, depth, 0, 0,
+                            width, height, leftPad, format, data);
+
+        success = 1;
+
+        goto nxagentSynchronizeDrawableDataFree;
+      }
+      else
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSynchronizeDrawableData: Skipping synchronization of "
+                    "pixmap at [%p][%p] during reconnection.\n", (void *) pDrawable, (void*) nxagentVirtualPixmap((PixmapPtr)pDrawable));
+        #endif
+
+        nxagentMarkCorruptedRegion(pDrawable, NullRegion);
+
+        success = 1;
+
+        goto nxagentSynchronizeDrawableDataFree;
+      }
+    }
+  }
+
+  /*
+   * By calling this function with the NullRegion
+   * as parameter we are requesting to synchro-
+   * nize the full visible corrupted region of
+   * the drawable.
+   */
+
+  success = nxagentSynchronizeRegion(pDrawable, NullRegion, breakMask, owner);
+
+nxagentSynchronizeDrawableDataFree:
+
+  if (data != NULL)
+  {
+    xfree(data);
+  }
+
+nxagentSynchronizeDrawableDataEnd:
+
+  return success;
+}
+
+/*
+ * If pRegion is NullRegion, all the viewable
+ * corrupted region will be synchronized.
+ */
+
+int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned int breakMask, WindowPtr owner)
+{
+  GCPtr pGC;
+  DrawablePtr pSrcDrawable;
+  BoxPtr pBox;
+  RegionPtr clipRegion;
+
+  RegionRec tileRegion;
+  RegionRec exposeRegion;
+  BoxRec box;
+  BoxRec tileBox;
+
+  #ifdef COLLECTED_UPDATES
+  RegionRec collectedUpdates;
+  #endif
+
+  char *data;
+
+  int nBox;
+  int x, y;
+  int w, h;
+  int tileWidth, tileHeight;
+  int length, format, leftPad;
+  int i;
+  int saveTrap;
+  int success;
+  int useStoredBitmap;
+
+  unsigned long now;
+  unsigned long elapsedTime;
+
+
+  leftPad    = 0;
+  success    = 0;
+  data       = NULL;
+  pGC        = NULL;
+  clipRegion = NullRegion;
+
+  #ifdef COLLECTED_UPDATES
+  REGION_INIT(pDrawable -> pScreen, &collectedUpdates, NullBox, 1);
+  #endif
+
+  REGION_INIT(pDrawable -> pScreen, &exposeRegion, NullBox, 1);
+
+  if (nxagentDrawableBitmap(pDrawable) != NullPixmap &&
+          nxagentDrawableStatus((DrawablePtr) nxagentDrawableBitmap(pDrawable)) == Synchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Drawable [%s] at [%p] has an already synchronized "
+                "bitmap at [%p].\n", nxagentDrawableType(pDrawable),
+                    (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable));
+    #endif
+
+    nxagentDestroyDrawableBitmap(pDrawable);
+  }
+
+  /*
+   * The stored bitmap may be used if we
+   * are going to synchronize the full
+   * drawable.
+   */
+
+  useStoredBitmap = (nxagentDrawableBitmap(pDrawable) != NullPixmap && pRegion == NullRegion);
+
+  if (useStoredBitmap != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap "
+                "[%d,%d,%d,%d] with [%ld] rects.\n", nxagentDrawableType(pDrawable),
+                    (void *) pDrawable, nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
+                                    REGION_NUM_RECTS(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
+    #endif
+
+    clipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
+
+    /*
+     * Intersecting the viewable region of the
+     * drawable with the region remaining from
+     * a previous loop.
+     */
+
+    REGION_INTERSECT(pDrawable -> pScreen, clipRegion, clipRegion,
+                         nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)));
+
+    /*
+     * The bitmap regions used in the synchro-
+     * nizations are only those corrupted also
+     * on the drawable. In this way, if we put
+     * a tile in a bad position (e.g. if the
+     * corrupted region moves), the next synch-
+     * ronization will fix the error.
+     */
+
+    REGION_INTERSECT(pDrawable -> pScreen, clipRegion, clipRegion,
+                         nxagentCorruptedRegion(pDrawable));
+
+    /*
+     * The bitmap to synchronize is clipped.
+     */
+
+    if (REGION_NIL(clipRegion) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeRegion: The bitmap region [%d,%d,%d,%d] is not viewable. "
+                  "Destroying it.\n", clipRegion -> extents.x1, clipRegion -> extents.y1,
+                      clipRegion -> extents.x2, clipRegion -> extents.y2);
+      #endif
+
+      nxagentDestroyDrawableBitmap(pDrawable);
+
+      goto nxagentSynchronizeRegionFree;
+    }
+
+    /*
+     * Using the saved bitmap as source, instead
+     * of the drawable itself.
+     */
+
+    pSrcDrawable = ((DrawablePtr) nxagentVirtualPixmap(nxagentDrawableBitmap(pDrawable)));
+  }
+  else
+  {
+    if (pRegion != NullRegion && REGION_NIL(pRegion) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeRegion: Region [%d,%d,%d,%d] is nil. Skipping synchronization.\n",
+                  pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+      #endif
+
+      goto nxagentSynchronizeRegionFree;
+    }
+
+    if (nxagentDrawableStatus(pDrawable) == Synchronized)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeRegion: The [%s] at [%p] is already synchronized.\n",
+                  nxagentDrawableType(pDrawable), (void *) pDrawable);
+      #endif
+
+      goto nxagentSynchronizeRegionFree;
+    }
+
+    /*
+     * Creating a region containing the viewable
+     * area of drawable.
+     */
+
+    clipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
+
+    /*
+     * If the corrupted region is not viewable, we
+     * can skip the synchronization.
+     */
+
+    REGION_INTERSECT(pDrawable -> pScreen, clipRegion, clipRegion, nxagentCorruptedRegion(pDrawable));
+
+    if (REGION_NIL(clipRegion) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeRegion: The corrupted region [%d,%d,%d,%d] is not viewable "
+                  "on [%s] at [%p]. Skipping the synchronization.\n", clipRegion -> extents.x1,
+                      clipRegion -> extents.y1, clipRegion -> extents.x2, clipRegion -> extents.y2,
+                          nxagentDrawableType(pDrawable), (void *) pDrawable);
+      #endif
+
+     goto nxagentSynchronizeRegionFree; 
+    }
+
+    /*
+     * We can skip the synchronization if the re-
+     * quested region is not corrupted. Specifying
+     * a NullRegion as parameter, all the viewable
+     * corrupted region will be synchronized.
+     */
+
+    if (pRegion != NullRegion)
+    {
+      REGION_INTERSECT(pDrawable -> pScreen, clipRegion, clipRegion, pRegion);
+
+      if (REGION_NIL(clipRegion) == 1)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSynchronizeRegion: Region requested [%d,%d,%d,%d] already "
+                    "synchronized on [%s] at [%p].\n", pRegion -> extents.x1,
+                        pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+                            nxagentDrawableType(pDrawable), (void *) pDrawable);
+        #endif
+
+        goto nxagentSynchronizeRegionFree;
+      }
+    }
+
+    pSrcDrawable = (pDrawable -> type == DRAWABLE_PIXMAP ?
+                      ((DrawablePtr) nxagentVirtualPixmap((PixmapPtr) pDrawable)) :
+                          pDrawable);
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSynchronizeRegion: Synchronizing region with coordinates [%d,%d,%d,%d] "
+              "on [%s] at [%p].\n", clipRegion -> extents.x1, clipRegion -> extents.y1,
+                  clipRegion -> extents.x2, clipRegion -> extents.y2,
+                      nxagentDrawableType(pDrawable), (void *) pDrawable);
+  #endif
+
+  saveTrap = nxagentGCTrap;
+
+  nxagentGCTrap = 0;
+
+  nxagentFBTrap = 1;
+
+  nxagentSplitTrap = 1;
+
+  pGC = nxagentGetGraphicContext(pDrawable);
+
+  if (pGC == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to create the temporary GC.\n");
+    #endif
+
+    goto nxagentSynchronizeRegionFree;
+  }
+
+  ValidateGC(pDrawable, pGC);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSynchronizeRegion: Going to synchronize [%ld] rects of [%s] at [%p].\n",
+              REGION_NUM_RECTS(clipRegion), (pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window"),
+                  (void *) pDrawable);
+
+  fprintf(stderr, "nxagentSynchronizeRegion: Extents geometry [%d,%d,%d,%d].\n",
+          clipRegion -> extents.x1, clipRegion -> extents.y1, clipRegion -> extents.x2, clipRegion -> extents.y2);
+
+  fprintf(stderr, "nxagentSynchronizeRegion: Drawable geometry [%d,%d,%d,%d].\n",
+              pDrawable -> x, pDrawable -> y, pDrawable -> width, pDrawable -> height);
+  #endif
+
+  w = tileWidth  = (nxagentOption(TileWidth)  > pDrawable -> width  ? pDrawable -> width  : nxagentOption(TileWidth));
+  h = tileHeight = (nxagentOption(TileHeight) > pDrawable -> height ? pDrawable -> height : nxagentOption(TileHeight));
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentSynchronizeRegion: Using tiles of size [%dx%d].\n", tileWidth, tileHeight);
+  #endif
+
+  data = nxagentAllocateImageData(w, h, pDrawable -> depth, &length, &format);
+
+  if (data == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to allocate memory for synchronization.\n");
+    #endif
+
+    goto nxagentSynchronizeRegionFree;
+  }
+
+  #ifndef USE_OPTIMIZED_BOXES
+
+  pBox = REGION_RECTS(clipRegion);
+
+  #else
+
+  pBox = nxagentGetOptimizedRegionBoxes(clipRegion);
+
+  #endif /* USE_OPTIMIZED_BOXES */
+
+  nBox = REGION_NUM_RECTS(clipRegion);
+
+  now = GetTimeInMillis();
+
+  nxagentSynchronization.abort = 0;
+
+  /*
+   * Going to split the updated region into small blocks.
+   */
+
+  for (i = 0; i < nBox; i++)
+  {
+    #ifdef USE_OPTIMIZED_BOXES
+
+    if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+            pBox[i].x2 == 0 && pBox[i].y2 == 0)
+    {
+      continue;
+    }
+
+    #endif
+
+    box = pBox[i];
+
+    for (y = box.y1; y < box.y2; y += h)
+    {
+      h = MIN(box.y2 - y, tileHeight);
+
+      for (x = box.x1; x < box.x2; x += w)
+      {
+        w = MIN(box.x2 - x, tileWidth);
+
+        if (canBreakOnTimeout(breakMask))
+        {
+          /*
+           * Abort the synchronization loop if it
+           * lasts for more than DeferTimeout
+           * milliseconds.
+           */
+
+          elapsedTime = GetTimeInMillis() - now;
+
+          if (elapsedTime > nxagentOption(DeferTimeout))
+          {
+            #ifdef TEST
+            fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+                        "[%lu] ms elapsed.\n", elapsedTime);
+            #endif
+
+            nxagentSynchronization.abort = 1;
+
+            goto nxagentSynchronizeRegionStop;
+          }
+        }
+
+        /*
+         * Abort the loop if we go out of bandwidth.
+         */
+
+        if (breakOnCongestionDrawable(breakMask, pDrawable) == 1)
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+                      "congestion [%d] blocking [%d].\n", nxagentCongestion,
+                          nxagentBlocking);
+          #endif
+
+          nxagentSynchronization.abort = 1;
+
+          goto nxagentSynchronizeRegionStop;
+        }
+
+        /*
+         * Abort the loop if the display blocks.
+         */
+
+        if (breakOnBlocking(breakMask) == 1)
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+                      "blocking [%d] congestion [%d].\n", nxagentBlocking,
+                          nxagentCongestion);
+          #endif
+
+          nxagentSynchronization.abort = 1;
+
+          goto nxagentSynchronizeRegionStop;
+        }
+
+        tileBox.x1 = x;
+        tileBox.y1 = y;
+        tileBox.x2 = x + w;
+        tileBox.y2 = y + h;
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentSynchronizeRegion: Going to synchronize tile [%d,%d,%d,%d].\n",
+                    tileBox.x1, tileBox.y1, tileBox.x2, tileBox.y2);
+        #endif
+
+        nxagentGetImage(pSrcDrawable, x, y, w, h, format, AllPlanes, data);
+
+        nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
+                                x, y, w, h, leftPad, format, data);
+
+        /*
+         * Going to unmark the synchronized
+         * region.
+         */
+
+        REGION_INIT(pDrawable -> pScreen, &tileRegion, &tileBox, 1);
+
+        REGION_UNION(pDrawable -> pScreen, &exposeRegion, &exposeRegion, &tileRegion);
+
+        #ifdef COLLECTED_UPDATES
+        REGION_APPEND(pDrawable -> pScreen, &collectedUpdates, &tileRegion);
+        #endif
+
+        if (useStoredBitmap != 0)
+        {
+          /*
+           * When a bitmap's tile is synchronized,
+           * we can clear the corresponding region.
+           * We can't use the nxagentUnmarkCorrupted-
+           * Region because we have not a resource
+           * associated to this pixmap.
+           */
+
+          REGION_SUBTRACT(pDrawable -> pScreen, nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)),
+                              nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)), &tileRegion); 
+
+          /*
+           * The drawable's corrupted region can
+           * be cleared if the bitmap's tile data
+           * matches the drawable's content at the
+           * same position.
+           */
+
+          if (nxagentDrawableStatus(pDrawable) == NotSynchronized)
+          {
+            char *cmpData;
+
+            int cmpLength, cmpFormat;
+
+            cmpData = nxagentAllocateImageData(w, h, pDrawable -> depth, &cmpLength, &cmpFormat);
+
+            if (cmpData != NULL)
+            {
+              nxagentGetImage(pDrawable, x, y, w, h, format, AllPlanes, cmpData);
+
+              if (memcmp(data, cmpData, cmpLength) == 0)
+              {
+                #ifdef TEST
+                fprintf(stderr, "nxagentSynchronizeRegion: Tile [%d,%d,%d,%d] matches drawable's data at same position.\n",
+                            x, y, x + w, y + h);
+                #endif
+
+                nxagentUnmarkCorruptedRegion(pDrawable, &tileRegion);
+              }
+            }
+            else
+            {
+              #ifdef WARNING
+              fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to allocate memory to compare tiles.\n");
+              #endif
+            }
+
+            if (cmpData != NULL)
+            {
+              xfree(cmpData);
+            }
+          }
+        }
+        else
+        {
+          nxagentUnmarkCorruptedRegion(pDrawable, &tileRegion);
+
+          if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+          {
+            #ifdef TEST
+            fprintf(stderr, "nxagentSynchronizeRegion: Going to clean bitmap at [%p] with newer data.\n",
+                        (void *) nxagentDrawableBitmap(pDrawable));
+            #endif
+
+            REGION_SUBTRACT(pDrawable -> pScreen, nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)),
+                                nxagentPixmapCorruptedRegion(nxagentDrawableBitmap(pDrawable)), &tileRegion);
+          }
+        }
+
+        REGION_UNINIT(pDrawable -> pScreen, &tileRegion);
+
+        #if !defined(COLLECTED_UPDATES)
+
+        if (owner != NULL)
+        {
+          if (nxagentOption(Shadow) == 1 &&
+                  (nxagentOption(XRatio) != DONT_SCALE ||
+                      nxagentOption(YRatio) != DONT_SCALE))
+          {
+            int scaledx;
+            int scaledy;
+            int scaledw;
+            int scaledh;
+
+            scaledx = nxagentScale(x, nxagentOption(XRatio));
+            scaledy = nxagentScale(y, nxagentOption(YRatio));
+
+            scaledw = nxagentScale(x + w, nxagentOption(XRatio)) - scaledx;
+            scaledh = nxagentScale(y + h, nxagentOption(YRatio)) - scaledy;
+
+            XClearArea(nxagentDisplay, nxagentWindow(owner), scaledx, scaledy, scaledw, scaledh, 0);
+          }
+          else
+          {
+            XClearArea(nxagentDisplay, nxagentWindow(owner), x, y, w, h, 0);
+          }
+        }
+
+        #endif /* #if !defined(COLLECTED_UPDATES) */
+
+        /*
+         * Abort the loop on the user's input.
+         * This is done here to check for events
+         * read after the flush caused by the
+         * PutImage.
+         */
+
+        nxagentDispatchHandler((ClientPtr) 0, 0, 0);
+
+        if (breakOnEvent(breakMask) == 1)
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentSynchronizeRegion: Synchronization break with "
+                      "new input events.\n");
+          #endif
+
+          nxagentSynchronization.abort = 1;
+
+          goto nxagentSynchronizeRegionStop;
+        }
+      }
+    }
+  }
+
+nxagentSynchronizeRegionStop:
+
+  nxagentSplitTrap = 0;
+
+  nxagentFBTrap = 0;
+
+  nxagentGCTrap = saveTrap;
+
+  success = 1;
+
+  if (nxagentOption(Shadow) == 0)
+  {
+    if (nxagentSynchronization.abort == 1)
+    {
+      /*
+       * Storing the pointer to the drawable we
+       * were synchronizing when the loop aborted.
+       * It is used in nxagentSynchronizeDrawable-
+       * Predicate.
+       */
+
+      nxagentSynchronization.pDrawable = pDrawable;
+      nxagentSynchronization.drawableType = pDrawable -> type;
+
+      if (nxagentDrawableBitmap(pDrawable) == NullPixmap)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSynchronizeRegion: Going to create the synchronization bitmap.\n");
+        #endif
+
+        nxagentCreateDrawableBitmap(pDrawable);
+      }
+    }
+    else
+    {
+      if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSynchronizeRegion: Synchronization loop finished. Going to destroy synchronization bitmap.\n");
+        #endif
+
+        nxagentDestroyDrawableBitmap(pDrawable);
+      }
+    }
+
+    if (pDrawable -> type == DRAWABLE_PIXMAP &&
+            nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1 &&
+                REGION_NIL(&exposeRegion) == 0)
+    {
+      struct nxagentExposeBackground eb;
+
+      int i;
+
+      eb.pBackground = (PixmapPtr) pDrawable;
+      eb.pExpose = &exposeRegion;
+
+      for (i = 0; i < MAXCLIENTS; i++)
+      {
+        if (clients[i] != NULL)
+        {
+          FindClientResourcesByType(clients[i], RT_WINDOW,
+                                        nxagentExposeBackgroundPredicate, &eb);
+        }
+      }
+    }
+  }
+  #ifdef COLLECTED_UPDATES
+  else
+  {
+    if (owner != NULL)
+    {
+      int overlap = 0;
+
+      REGION_VALIDATE(pDrawable -> pScreen, &collectedUpdates, &overlap);
+
+      for (i = 0; i < REGION_NUM_RECTS(&collectedUpdates); i++)
+      {
+        x = REGION_RECTS(&collectedUpdates)[i].x1;
+        y = REGION_RECTS(&collectedUpdates)[i].y1;
+        w = REGION_RECTS(&collectedUpdates)[i].x2 - REGION_RECTS(&collectedUpdates)[i].x1;
+        h = REGION_RECTS(&collectedUpdates)[i].y2 - REGION_RECTS(&collectedUpdates)[i].y1;
+       
+        if (nxagentOption(Shadow) == 1 &&
+                (nxagentOption(XRatio) != DONT_SCALE ||
+                    nxagentOption(YRatio) != DONT_SCALE))
+        {
+          int scaledx;
+          int scaledy;
+          int scaledw;
+          int scaledh;
+
+          scaledx = nxagentScale(x, nxagentOption(XRatio));
+          scaledy = nxagentScale(y, nxagentOption(YRatio));
+
+          scaledw = nxagentScale(x + w, nxagentOption(XRatio)) - scaledx;
+          scaledh = nxagentScale(y + h, nxagentOption(YRatio)) - scaledy;
+
+          XClearArea(nxagentDisplay, nxagentWindow(owner), scaledx, scaledy, scaledw, scaledh, 0);
+        }
+        else
+        {
+          XClearArea(nxagentDisplay, nxagentWindow(owner), x, y, w, h, 0);
+        }
+      }
+    }
+  }
+  #endif /* #ifdef COLLECTED_UPDATES */
+
+nxagentSynchronizeRegionFree:
+
+  if (clipRegion != NullRegion)
+  {
+    nxagentFreeRegion(pDrawable, clipRegion);
+  }
+
+  if (data != NULL)
+  {
+    xfree(data);
+  }
+
+  REGION_UNINIT(pDrawable -> pScreen, &exposeRegion);
+
+  #ifdef COLLECTED_UPDATES
+
+  REGION_UNINIT(pDrawable -> pScreen, &collectedUpdates);
+
+  #endif /* #ifdef COLLECTED_UPDATES */
+
+  return success;
+}
+
+void nxagentSynchronizeBox(DrawablePtr pDrawable, BoxPtr pBox, unsigned int breakMask)
+{
+  RegionPtr pRegion;
+
+  if (nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeBox: The [%s] at [%p] is already synchronized.\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable);
+    #endif
+
+    return;
+  }
+
+  if (pBox == NullBox)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeBox: Going to synchronize the whole [%s] at [%p].\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable);
+    #endif
+
+    nxagentSynchronizeRegion(pDrawable, NullRegion, breakMask, NULL);
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeBox: Going to create a region from box [%d,%d,%d,%d].\n",
+                pBox -> x1, pBox -> y1, pBox -> x2, pBox -> y2);
+    #endif
+
+    pRegion = nxagentCreateRegion(pDrawable, NULL, pBox -> x1, pBox -> y1,
+                                      pBox -> x2 - pBox -> x1, pBox -> y2 - pBox -> y1);
+
+
+    if (REGION_NIL(pRegion) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeBox: Resulting region [%d,%d,%d,%d] is nil. Skipping synchronization.\n",
+                  pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+      #endif
+
+      nxagentFreeRegion(pDrawable, pRegion);
+
+      return;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeBox: Going to synchronize the region [%d,%d,%d,%d] of "
+                "[%s] at [%p].\n", pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2,
+                    pRegion -> extents.y2, nxagentDrawableType(pDrawable), (void *) pDrawable);
+    #endif
+
+    nxagentSynchronizeRegion(pDrawable, pRegion, breakMask, NULL);
+
+    nxagentFreeRegion(pDrawable, pRegion);
+  }
+}
+
+void nxagentSynchronizeDrawablePredicate(void *p0, XID x1, void *p2)
+{
+  DrawablePtr pDrawable = (DrawablePtr) p0;
+  unsigned int *breakMask = (unsigned int *) p2;
+
+  int shouldClearHiddenRegion = 1;
+
+  /*
+   * The nxagentSynchronization.abort propa-
+   * gates a break condition across the resour-
+   * ces loop, in order to block also the sub-
+   * sequent synchronizations.
+   */
+
+  if (nxagentSynchronization.abort == 1 ||
+          nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    return;
+  }
+
+  /*
+   * In order to implement a kind of round-robin
+   * synchronization, the previous incomplete
+   * drawable synchronization is saved to jump
+   * to the next resource available of same type.
+   */
+
+  if (nxagentSynchronization.pDrawable != NULL &&
+          pDrawable -> type == nxagentSynchronization.drawableType)
+  {
+    if (nxagentSynchronization.pDrawable != pDrawable)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Skipping drawable [%s][%p] while looking "
+                  "for last synchronized drawable [%p].\n", nxagentDrawableType(pDrawable),
+                      (void *) pDrawable, (void *) nxagentSynchronization.pDrawable);
+      #endif
+
+      return;
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Last synchronized drawable [%p] found. "
+                  "Skipping to the next resource.\n", (void *) nxagentSynchronization.pDrawable);
+      #endif
+
+      nxagentSynchronization.pDrawable = NULL;
+
+      return;
+    }
+  }
+
+  if (pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    /*
+     * The pixmaps to be synchronized are those
+     * used as background or used as source of
+     * any deferred operations for at least 2
+     * times.
+     */
+
+    if (NXAGENT_SHOULD_SYNCHRONIZE_PIXMAP(pDrawable) == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Skipping pixmap at [%p] "
+                  "with usage [%d] background [%d].\n", (void *) pDrawable,
+                      nxagentPixmapUsageCounter((PixmapPtr) pDrawable),
+                          nxagentIsCorruptedBackground((PixmapPtr) pDrawable));
+      #endif
+
+      return;
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Synchronizing pixmap at [%p] "
+                  "with usage [%d] background [%d].\n", (void *) pDrawable,
+                      nxagentPixmapUsageCounter((PixmapPtr) pDrawable),
+                          nxagentIsCorruptedBackground((PixmapPtr) pDrawable));
+    }
+    #endif
+  }
+  else if (NXAGENT_SHOULD_SYNCHRONIZE_WINDOW(pDrawable) == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Skipping not visible window at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    if (shouldClearHiddenRegion == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Clearing out the not visible window "
+                  "at [%p].\n", (void *) pDrawable);
+      #endif
+
+      nxagentCleanCorruptedDrawable(pDrawable);
+    }
+
+    return;
+  }
+
+  /*
+   * Postpone the synchronization if we went
+   * out of bandwidth or if the display blocks.
+   * The pixmap synchronization is more careful
+   * with bandwidth usage.
+   */
+
+/*
+FIXME: This condition sounds only as a
+       complication, as the break parameters
+       are already checked while synchroni-
+       zing the drawable.
+
+  if (breakOnCongestion(*breakMask) == 1 ||
+          (pDrawable -> type == DRAWABLE_PIXMAP &&
+               *breakMask != NEVER_BREAK && nxagentCongestion > 0))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeDrawablePredicate: WARNING! Breaking the "
+                "synchronization with congestion [%d] blocking [%d].\n",
+                    nxagentCongestion, nxagentBlocking);
+    #endif
+
+    nxagentSynchronization.abort = 1;
+
+    return;
+  }
+*/
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Synchronizing drawable [%s][%p] "
+              "with geometry (%dx%d).\n", nxagentDrawableType(pDrawable),
+                  (void *) pDrawable, pDrawable -> width, pDrawable -> height);
+
+  fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Corrupted extents [%d,%d,%d,%d] "
+              "with [%ld] rects.\n", nxagentCorruptedRegion(pDrawable) -> extents.x1,
+                  nxagentCorruptedRegion(pDrawable) -> extents.y1, nxagentCorruptedRegion(pDrawable) ->
+                      extents.x2, nxagentCorruptedRegion(pDrawable) -> extents.y2,
+                          REGION_NUM_RECTS(nxagentCorruptedRegion(pDrawable)));
+  #endif
+
+  /*
+   * The stored bitmap is destroyed inside
+   * the synchronization loop, so we have
+   * to check here its presence to know if
+   * we can clear the dirty windows.
+   */
+
+  shouldClearHiddenRegion = (nxagentDrawableBitmap(pDrawable) == NullPixmap);
+
+  nxagentSynchronizeDrawable(pDrawable, DONT_WAIT, *breakMask, NULL);
+
+  if (nxagentDrawableStatus(pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Drawable [%s][%p] not fully synchronized.\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable);
+    #endif
+
+    /*
+     * If the remaining corrupted region is on
+     * an hidden section (not viewable or outside
+     * of the pixmap's area) of a drawable,
+     * we can clear it.
+     */
+
+    if (nxagentSynchronization.abort == 0 &&
+            shouldClearHiddenRegion == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSynchronizeDrawablePredicate: Clearing out the remaining corrupted "
+                  "[%s] at [%p].\n", nxagentDrawableType(pDrawable), (void *) pDrawable);
+      #endif
+
+      nxagentCleanCorruptedDrawable(pDrawable);
+    }
+  }
+}
+
+void nxagentSynchronizationLoop(unsigned int mask)
+{
+  unsigned int breakMask;
+
+  int doRoundRobin;
+
+/*
+FIXME: All drawables should be set as synchronized and
+       never marked as corrupted while the display is
+       down.
+*/
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizationLoop: WARNING! Not synchronizing the drawables "
+                "with the display down.\n");
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSynchronizationLoop: Synchronizing [%d] windows [%d] pixmaps "
+              "and [%d] backgrounds with mask [%u].\n", nxagentCorruptedWindows, nxagentCorruptedPixmaps,
+                  nxagentCorruptedBackgrounds, mask);
+
+  fprintf(stderr, "nxagentSynchronizationLoop: Stored bitmaps [%d] windows [%d] pixmaps "
+              "and [%d] backgrounds.\n", nxagentSynchronization.windowBitmaps,
+                  nxagentSynchronization.pixmapBitmaps, nxagentSynchronization.backgroundBitmaps);
+
+  fprintf(stderr, "nxagentSynchronizationLoop: Starting loops with congestion [%d] "
+              "blocking [%d].\n", nxagentCongestion, nxagentBlocking);
+  #endif
+
+  breakMask = mask;
+
+  /*
+   * The resource counter can be reset if we
+   * have not aborted the synchronization loop,
+   * if we are not skipping resources to do
+   * round-robin and if the bitmaps are all
+   * synchronized.
+   */
+
+  doRoundRobin = (nxagentSynchronization.pDrawable != NULL);
+
+  nxagentSynchronization.abort = 0;
+
+  /*
+   * Synchronize the windows.
+   */
+
+  if (NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_WINDOWS(mask))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizationLoop: Going to loop through corrupted window resources.\n");
+    #endif
+
+    FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_WINDOW,
+                                  nxagentSynchronizeDrawablePredicate, &breakMask);
+
+    #ifdef TEST
+
+    if (nxagentSynchronization.abort == 0 &&
+            nxagentSynchronization.windowBitmaps == 0 &&
+                doRoundRobin == 0)
+    {
+      if (nxagentCorruptedWindows > 0)
+      {
+        fprintf(stderr, "nxagentSynchronizationLoop: Closing the loop with [%d] "
+                    "corrupted windows.\n", nxagentCorruptedWindows);
+      }
+
+      nxagentCorruptedWindows = 0;
+    }
+
+    #endif
+  }
+
+  /*
+   * Synchronize the backgrounds.
+   */
+
+  if (nxagentSynchronization.abort == 0 &&
+          NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_BACKGROUNDS(mask))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizationLoop: Going to loop through corrupted background resources.\n");
+    #endif
+
+    FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_BACKGROUND,
+                                  nxagentSynchronizeDrawablePredicate, &breakMask);
+
+    #ifdef TEST
+
+    if (nxagentSynchronization.abort == 0 &&
+            nxagentSynchronization.backgroundBitmaps == 0 &&
+                doRoundRobin == 0)
+    {
+      if (nxagentCorruptedBackgrounds > 0)
+      {
+        fprintf(stderr, "nxagentSynchronizationLoop: Closing the loop with [%d] "
+                    "corrupted backgrounds.\n", nxagentCorruptedBackgrounds);
+      }
+
+      nxagentCorruptedBackgrounds = 0;
+    }
+
+    #endif
+  }
+
+  /*
+   * If there is bandwidth remaining, synchronize
+   * the pixmaps. Synchronizing a pixmap doesn't
+   * produce any visible results. Better is to
+   * synchronize them on demand, before using the
+   * pixmap in a copy or in a composite operation.
+   */
+
+  if (nxagentSynchronization.abort == 0 &&
+          NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_PIXMAPS(mask))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizationLoop: Going to loop through corrupted pixmap resources.\n");
+    #endif
+
+    FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_PIXMAP,
+                                  nxagentSynchronizeDrawablePredicate, &breakMask);
+
+
+    if (nxagentSynchronization.abort == 0 &&
+            nxagentSynchronization.pixmapBitmaps == 0 &&
+                doRoundRobin == 0)
+    {
+      #ifdef TEST
+
+      if (nxagentCorruptedPixmaps > 0)
+      {
+        fprintf(stderr, "nxagentSynchronizationLoop: Closing the loop with [%d] "
+                    "corrupted pixmaps.\n", nxagentCorruptedPixmaps);
+      }
+
+      #endif
+
+      nxagentCorruptedPixmaps = 0;
+    }
+
+  }
+
+  /*
+   * If the last synchronized drawable has been
+   * removed, we have to reset the variable sto-
+   * ring its pointer.
+   */
+
+  if (nxagentSynchronization.pDrawable != NULL &&
+          nxagentFindClientResource(serverClient -> index, RT_NX_CORR_WINDOW,
+              nxagentSynchronization.pDrawable) == 0 &&
+                  nxagentFindClientResource(serverClient -> index, RT_NX_CORR_BACKGROUND,
+                      nxagentSynchronization.pDrawable) == 0 &&
+                          nxagentFindClientResource(serverClient -> index, RT_NX_CORR_PIXMAP,
+                              nxagentSynchronization.pDrawable) == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizationLoop: Synchronization drawable [%p] removed from resources.\n",
+                (void *) nxagentSynchronization.pDrawable);
+    #endif
+
+    nxagentSynchronization.pDrawable = NULL;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSynchronizationLoop: Closing loops with congestion [%d] "
+              "blocking [%d].\n", nxagentCongestion, nxagentBlocking);
+
+  fprintf(stderr, "nxagentSynchronizationLoop: There are now [%d] windows [%d] pixmaps "
+              "and [%d] backgrounds to synchronize.\n", nxagentCorruptedWindows,
+                  nxagentCorruptedPixmaps, nxagentCorruptedBackgrounds);
+  #endif
+}
+
+RegionPtr nxagentCreateRegion(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                                  int width, int height)
+{
+  RegionPtr pRegion;
+  BoxRec box;
+
+  box.x1 = x;
+  box.y1 = y;
+  box.x2 = x + width;
+  box.y2 = y + height;
+
+  pRegion = REGION_CREATE(pDrawable -> pScreen, &box, 1);
+
+  /*
+   * Clipping the region.
+   */
+
+  if (pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    BoxRec tmpBox;
+    RegionRec tmpRegion;
+
+    /*
+     * The region created doesn't need to be clipped
+     * if it has the pixmap dimensions.
+     */
+
+    if (x != 0 || y != 0 ||
+            width != pDrawable -> width ||
+                height != pDrawable -> height)
+    {
+      tmpBox.x1 = 0;
+      tmpBox.y1 = 0;
+      tmpBox.x2 = pDrawable -> width;
+      tmpBox.y2 = pDrawable -> height;
+
+      REGION_INIT(pDrawable -> pScreen, &tmpRegion, &tmpBox, 1);
+
+      REGION_INTERSECT(pDrawable -> pScreen, pRegion, &tmpRegion, pRegion);
+
+      REGION_UNINIT(pDrawable -> pScreen, &tmpRegion);
+    }
+  }
+  else
+  {
+    /*
+     * We use the clipList because the borderClip
+     * contains also parts of the window covered
+     * by its children.
+     */
+
+    REGION_TRANSLATE(pDrawable -> pScreen, pRegion,
+                         pDrawable -> x, pDrawable -> y);
+
+    if (nxagentWindowPriv((WindowPtr) pDrawable) -> hasTransparentChildren == 1)
+    {
+      REGION_INTERSECT(pDrawable -> pScreen, pRegion, pRegion, &((WindowPtr) pDrawable) -> borderClip);
+    }
+    else
+    {
+      REGION_INTERSECT(pDrawable -> pScreen, pRegion, pRegion, &((WindowPtr) pDrawable) -> clipList);
+    }
+
+    REGION_TRANSLATE(pDrawable -> pScreen, pRegion,
+                         -pDrawable -> x, -pDrawable -> y);
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateRegion: New region created with coordinates [%d,%d,%d,%d].\n",
+              pRegion -> extents.x1, pRegion -> extents.y1,
+                  pRegion -> extents.x2, pRegion -> extents.y2);
+  #endif
+
+  /*
+   * If the pRegion is NIL we don't need
+   * to intersect it with the GC's clipmask.
+   */
+
+  if (REGION_NIL(pRegion) == 0 &&
+          pGC != NULL && pGC -> clientClip != NULL &&
+              pGC -> clientClipType == CT_REGION)
+  {
+    RegionRec clipRegion;
+
+    REGION_INIT(pDrawable -> pScreen, &clipRegion, NullBox, 1);
+
+    REGION_COPY(pDrawable -> pScreen, &clipRegion, (RegionPtr) pGC -> clientClip);
+
+    /*
+     * The clip origin is relative to the origin of
+     * the destination drawable. The clip mask coor-
+     * dinates are relative to the clip origin.
+     */
+
+    if (pGC -> clipOrg.x != 0 || pGC -> clipOrg.y != 0)
+    {
+      REGION_TRANSLATE(pDrawable -> pScreen, &clipRegion, pGC -> clipOrg.x, pGC -> clipOrg.y);
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCreateRegion: Clipping region to the clip mask with coordinates [%d,%d,%d,%d].\n",
+                clipRegion.extents.x1, clipRegion.extents.y1,
+                    clipRegion.extents.x2, clipRegion.extents.y2);
+    #endif
+
+    REGION_INTERSECT(pDrawable -> pScreen, pRegion, pRegion, &clipRegion);
+
+    REGION_UNINIT(pDrawable -> pScreen, &clipRegion);
+  }
+
+  return pRegion;
+}
+
+void nxagentMarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+  int x;
+  int y;
+  int width;
+  int height;
+
+  if (pRegion != NullRegion && REGION_NIL(pRegion) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentMarkCorruptedRegion: Region [%d,%d,%d,%d] is nil. Skipping operation.\n",
+                pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+    #endif
+
+    return;
+  }
+
+  /*
+   * If the drawable was synchronized, the counter
+   * reporting the number of corrupted drawables
+   * must be increased. Moreover the corrupted ti-
+   * mestamp must be set.
+   */
+
+  if (nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    if (pDrawable -> type == DRAWABLE_WINDOW)
+    {
+      nxagentAllocateCorruptedResource(pDrawable, RT_NX_CORR_WINDOW);
+    }
+
+    nxagentSetCorruptedTimestamp(pDrawable);
+  }
+
+  if (pRegion == NullRegion)
+  {
+    x = 0;
+    y = 0;
+
+    width  = pDrawable -> width;
+    height = pDrawable -> height;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentMarkCorruptedRegion: Fully invalidating %s [%p] with "
+                "coordinates [%d,%d][%d,%d].\n", nxagentDrawableType(pDrawable),
+                    (void *) pDrawable, x, y, width, height);
+    #endif
+
+    pRegion = nxagentCreateRegion(pDrawable, NULL, x, y, width, height);
+
+    nxagentValidateSplit(pDrawable, pRegion);
+
+    REGION_UNION(pDrawable -> pScreen, nxagentCorruptedRegion(pDrawable),
+                     nxagentCorruptedRegion(pDrawable), pRegion);
+
+    nxagentFreeRegion(pDrawable, pRegion);
+  }
+  else
+  {
+    #ifdef TEST
+
+    x = pRegion -> extents.x1;
+    y = pRegion -> extents.y1;
+
+    width = pRegion -> extents.x2 - pRegion -> extents.x1;
+    height = pRegion -> extents.y2 - pRegion -> extents.y1;
+
+    fprintf(stderr, "nxagentMarkCorruptedRegion: Partly invalidating %s [%p] with "
+                "coordinates [%d,%d][%d,%d].\n", nxagentDrawableType(pDrawable),
+                    (void *) pDrawable, x, y, width, height);
+
+    #endif
+
+    nxagentValidateSplit(pDrawable, pRegion);
+
+    REGION_UNION(pDrawable -> pScreen, nxagentCorruptedRegion(pDrawable),
+                     nxagentCorruptedRegion(pDrawable), pRegion);
+  }
+}
+
+void nxagentUnmarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+  int oldStatus;
+
+  if (pRegion != NullRegion && REGION_NIL(pRegion) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentUnmarkCorruptedRegion: Region [%d,%d,%d,%d] is nil. Skipping operation.\n",
+                pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+    #endif
+
+    return;
+  }
+
+  oldStatus = nxagentDrawableStatus(pDrawable);
+
+  if (oldStatus == Synchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentUnmarkCorruptedRegion: Drawable %s [%p] already synchronized.\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable);
+    #endif
+
+    return;
+  }
+
+  if (pRegion == NullRegion)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentUnmarkCorruptedRegion: Fully validating %s [%p].\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable);
+    #endif
+
+    nxagentValidateSplit(pDrawable, NULL);
+
+    REGION_EMPTY(pDrawable -> pScreen, nxagentCorruptedRegion(pDrawable));
+  }
+  else
+  {
+    #ifdef TEST
+
+    fprintf(stderr, "nxagentUnmarkCorruptedRegion: Validating %s [%p] with region [%d,%d,%d,%d].\n",
+                nxagentDrawableType(pDrawable), (void *) pDrawable,
+                    pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2);
+
+    #endif
+
+    nxagentValidateSplit(pDrawable, pRegion);
+
+    REGION_SUBTRACT(pDrawable -> pScreen, nxagentCorruptedRegion(pDrawable),
+                        nxagentCorruptedRegion(pDrawable), pRegion);
+  }
+
+  /*
+   * If the drawable becomes synchronized, the
+   * counter reporting the number of corrupted
+   * drawables must be decreased. Moreover the
+   * corrupted timestamp must be reset.
+   */
+
+  if (oldStatus == NotSynchronized &&
+          nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    if (pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_BACKGROUND);
+
+      nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_PIXMAP);
+
+      nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> containTrapezoids = 0;
+    }
+    else
+    {
+      nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_WINDOW);
+    }
+
+    nxagentResetCorruptedTimestamp(pDrawable);
+
+    /*
+     * If the resource is no longer dirty,
+     * the associated bitmap is destroyed.
+     */
+
+    if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+    {
+       nxagentDestroyDrawableBitmap(pDrawable);
+    }
+  }
+}
+
+void nxagentMoveCorruptedRegion(WindowPtr pWin, unsigned int mask)
+{
+  /*
+   * If a window is resized, its corrupted
+   * region is moved according to the bit
+   * gravity.
+   */
+
+  if (nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+  {
+    if (((mask & CWHeight) && nxagentWindowPriv(pWin) -> height != pWin -> drawable.height) ||
+            ((mask & CWWidth) && nxagentWindowPriv(pWin) -> width != pWin -> drawable.width))
+    {
+      int nx, ny;
+
+      GravityTranslate(0, 0,
+                       nxagentWindowPriv(pWin) -> x - pWin -> origin.x + wBorderWidth(pWin),
+                       nxagentWindowPriv(pWin) -> y - pWin -> origin.y + wBorderWidth(pWin),
+                       pWin -> drawable.width - nxagentWindowPriv(pWin) -> width,
+                       pWin -> drawable.height - nxagentWindowPriv(pWin) -> height,
+                       pWin -> bitGravity, &nx, &ny);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentMoveCorruptedRegion: Moving the corrupted region to [%d,%d] for window [%p].\n",
+                  nx, ny, (void *) pWin);
+      #endif
+
+      REGION_TRANSLATE(pWin -> pScreen, nxagentCorruptedRegion((DrawablePtr) pWin),
+                           nx, ny);
+
+      /*
+       * Having moved the corrupted region, we
+       * need to invalidate the pending commits
+       * or otherwise the image will fall in
+       * the wrong area.
+       */
+
+      nxagentValidateSplit((DrawablePtr) pWin, NULL);
+
+
+      /*
+       * The window reconfiguration invalidates
+       * the synchronization bitmap.
+       */
+
+      nxagentDestroyDrawableBitmap((DrawablePtr) pWin);
+    }
+  }
+}
+
+/*
+ * The DDX layer uses an 'Y-X banding' representation of
+ * regions: it sorts all rectangles composing a region
+ * using first the y-dimension, than the x-dimension; mo-
+ * reover it organizes the rectangles in 'bands' sharing
+ * the same y-dimension. This representation does not mi-
+ * nimize the number of rectangles. For example, the fol-
+ * lowing region has 4 rectangles:
+ *
+ *    +-----------+
+ *    |           |   +---+
+ *    |     A     |   | B |
+ *    |           |   +---+
+ *    +-----------+
+ *
+ * The rectangle 'B' creates a band which splits the rec-
+ * tangle A in 3 parts, for a total of 3 bands. The num-
+ * ber of rectangles composing the region is 4.
+ *
+ * This kind of representation is not advisable for the
+ * lazy synchronization because, in the example above,
+ * the nxagent had to send 4 put images instead of 2.
+ *
+ * To minimize the problem we use the following function:
+ * by traversing the list of rectangles we merge all bo-
+ * xes with same x coordinates and coincident y, in order
+ * to create an X-Y banding.
+ *
+ * Be careful: all the coordinates of boxes merged are
+ * set to 0, so take care of this when looping through
+ * the box list returned by this function.
+ */
+
+BoxPtr nxagentGetOptimizedRegionBoxes(RegionPtr pRegion)
+{
+  BoxPtr pBox;
+
+  BoxRec boxExtents;
+
+  int nBox;
+  int i, j;
+
+  #ifdef DEBUG
+  int nBoxOptim;
+  #endif
+
+  pBox = REGION_RECTS(pRegion);
+
+  nBox = REGION_NUM_RECTS(pRegion);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Going to optimize region at [%p] with [%d] rects.\n",
+              (void *) pRegion, nBox);
+  #endif
+
+  if (nBox <= 1)
+  {
+    return pBox;
+  }
+
+  #ifdef DEBUG
+  nBoxOptim = nBox;
+  #endif
+
+  /*
+   * The boxes are now grouped to grown as much
+   * as possible, using their overlapping vertex
+   * as rule.
+   */
+
+  for (i = 0; i < nBox; i++)
+  {
+    /*
+     * If the coordinates are (0,0) the box
+     * has been already merged, so we can skip
+     * it.
+     */
+
+    if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+            pBox[i].x2 == 0 && pBox[i].y2 == 0)
+    {
+      continue;
+    }
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Referential box [%d] has coordinates [%d,%d,%d,%d].\n",
+                i, pBox[i].x1, pBox[i].y1, pBox[i].x2, pBox[i].y2);
+    #endif
+
+    #ifdef ADVANCED_BOXES_DEFRAG
+
+    boxExtents.x1 = pBox[i].x1;
+    boxExtents.y1 = pBox[i].y1;
+    boxExtents.x2 = pBox[i].x2;
+
+    #endif
+
+    boxExtents.y2 = pBox[i].y2;
+
+    for (j = i+1; j < nBox; j++)
+    {
+      if (pBox[j].x1 == 0 && pBox[j].y1 == 0 &&
+              pBox[j].x2 == 0 && pBox[j].y2 == 0)
+      {
+        continue;
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Mergeable box [%d] has coordinates [%d,%d,%d,%d].\n",
+                  j, pBox[j].x1, pBox[j].y1, pBox[j].x2, pBox[j].y2);
+      #endif
+
+      /*
+       * Each consequent box is merged if its
+       * higher side overlaps the lower side
+       * of current box.
+       * In case of ADVANCED_BOXES_DEFRAG the higher
+       * side must be included within a range
+       * defined by INCLUDE_MARGIN.
+       */
+
+      #ifndef ADVANCED_BOXES_DEFRAG
+
+      if (pBox[j].y1 == boxExtents.y2 &&
+          pBox[j].x1 == pBox[i].x1 &&
+          pBox[j].x2 == pBox[i].x2)
+
+      #else
+
+      if (pBox[j].x1 > boxExtents.x1 - INCLUDE_MARGIN &&
+          pBox[j].x1 < boxExtents.x1 + INCLUDE_MARGIN &&
+          pBox[j].y1 > boxExtents.y2 - INCLUDE_MARGIN &&
+          pBox[j].y1 < boxExtents.y2 + INCLUDE_MARGIN &&
+          pBox[j].x2 > boxExtents.x2 - INCLUDE_MARGIN &&
+          pBox[j].x2 < boxExtents.x2 + INCLUDE_MARGIN)
+
+      #endif
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Going to merge box at [%d] with box at [%d].\n",
+                    j, i);
+        #endif
+
+        #ifdef ADVANCED_BOXES_DEFRAG
+
+        if (pBox[j].x1 < boxExtents.x1)
+        {
+          boxExtents.x1 = pBox[j].x1;
+        }
+
+        if (pBox[j].x2 > boxExtents.x2)
+        {
+          boxExtents.x2 = pBox[j].x2;
+        }
+
+        if (pBox[j].y1 < boxExtents.y1)
+        {
+          boxExtents.y1 = pBox[j].y1;
+        }
+
+        #endif
+
+        if (pBox[j].y2 > boxExtents.y2)
+        {
+          boxExtents.y2 = pBox[j].y2;
+        }
+
+        /*
+         * By appending a box to another, we have
+         * to remove it from the box list. We do
+         * this by setting its coordinates to (0,0)
+         * and by checking their value in the main
+         * loop.
+         */
+
+        pBox[j].x1 = pBox[j].y1 = pBox[j].x2 = pBox[j].y2 = 0;
+
+        #ifdef DEBUG
+        nBoxOptim--;
+        #endif
+      }
+    }
+
+    /*
+     * Extend the box height.
+     */
+
+    #ifdef ADVANCED_BOXES_DEFRAG
+
+    pBox[i].x1 = boxExtents.x1;
+    pBox[i].y1 = boxExtents.y1;
+    pBox[i].x2 = boxExtents.x2;
+
+    #endif
+
+    pBox[i].y2 = boxExtents.y2;
+  }
+
+  #ifdef ADVANCED_BOXES_DEFRAG
+
+  /*
+   * The new list need to be validated to
+   * avoid boxes overlapping. This code may
+   * be improved to remove also the partial-
+   * ly overlapping boxes.
+   */
+
+  for (i = 0; i < nBox; i++)
+  {
+    if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+            pBox[i].x2 == 0 && pBox[i].y2 == 0)
+    {
+      continue;
+    }
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Referential box [%d] has coordinates [%d,%d,%d,%d].\n",
+                i, pBox[i].x1, pBox[i].y1, pBox[i].x2, pBox[i].y2);
+    #endif
+
+    boxExtents.x1 = pBox[i].x1;
+    boxExtents.y1 = pBox[i].y1;
+    boxExtents.x2 = pBox[i].x2;
+    boxExtents.y2 = pBox[i].y2;
+
+    for (j = i+1; j < nBox; j++)
+    {
+      if (pBox[j].x1 == 0 && pBox[j].y1 == 0 &&
+              pBox[j].x2 == 0 && pBox[j].y2 == 0)
+      {
+        continue;
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Mergeable box [%d] has coordinates [%d,%d,%d,%d].\n",
+                  j, pBox[j].x1, pBox[j].y1, pBox[j].x2, pBox[j].y2);
+      #endif
+
+      if ((boxExtents.x1 <= pBox[j].x1 &&
+           boxExtents.x2 >= pBox[j].x2 &&
+           boxExtents.y1 <= pBox[j].y1 &&
+           boxExtents.y2 >= pBox[j].y2))
+      {
+        /*
+         * If a box is completely inside
+         * another, we set its coordinates
+         * to 0 to consider it as merged.
+         */
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Going to merge box [%d,%d,%d,%d] "
+                    "with its box container [%d,%d,%d,%d].\n", pBox[j].x1, pBox[j].y1,
+                        pBox[j].x2, pBox[j].y2, boxExtents.x1, boxExtents.y1, boxExtents.y1,
+                            boxExtents.y2);
+        #endif
+
+        pBox[j].x1 = pBox[j].y1 = pBox[j].x2 = pBox[j].y2 = 0;
+
+        #ifdef DEBUG
+        nBoxOptim--;
+        #endif
+      }
+    }
+  }
+
+  #endif
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentGetOptimizedRegionBoxes: Original boxes number [%d] Optimized boxes number [%d].\n",
+              nBox, nBoxOptim);
+  #endif
+
+  return pBox;
+}
+
+unsigned long nxagentGetColor(DrawablePtr pDrawable, int xPixel, int yPixel)
+{
+  XImage *ximage;
+  Visual *pVisual;
+  char *data;
+
+  int depth, format, length;
+  int leftPad = 0;
+  unsigned long pixel;
+
+  depth = pDrawable -> depth;
+  format = (depth == 1) ? XYPixmap : ZPixmap;
+  length = nxagentImageLength(1, 1, format, leftPad, depth);
+
+  if ((data = xalloc(length)) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentGetColor: WARNING! Failed to allocate memory for the operation.\n");
+    #endif
+
+    return -1;
+  }
+
+  pVisual = nxagentImageVisual(pDrawable, depth);
+
+  if (pVisual == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentGetColor: WARNING! Visual not found. Using default visual.\n");
+    #endif
+
+    pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+  }
+
+  fbGetImage(pDrawable, xPixel, yPixel, 1, 1, format, AllPlanes, data);
+
+  ximage = XCreateImage(nxagentDisplay, pVisual, depth, format, leftPad, (char *) data,
+                            1, 1, BitmapPad(nxagentDisplay),
+                                nxagentImagePad(1, format, leftPad, 1));
+
+  if (ximage == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentGetColor: WARNING! Failed to create the XImage.\n");
+    #endif
+
+    xfree(data);
+
+    return -1;
+  }
+
+  pixel = XGetPixel(ximage, 0, 0);
+
+  XDestroyImage(ximage);
+
+  return pixel;
+}
+
+/*
+ * This function could be used to determine
+ * the ClearArea color of corrupted regions
+ * on screen.
+ */
+
+unsigned long nxagentGetRegionColor(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+  int xPicker, yPicker;
+
+  if (REGION_NIL(pRegion) == 1)
+  {
+    return nxagentGetDrawableColor(pDrawable);
+  }
+
+  /*
+   * The pixel used as reference is the first
+   * outer pixel at the bottom right corner
+   * of corrupted region extents.
+   */
+
+  xPicker = pRegion -> extents.x2 + 1;
+
+  if (xPicker > pDrawable -> width)
+  {
+    xPicker = pDrawable -> width;
+  }
+
+  yPicker = pRegion -> extents.y2 + 1;
+
+  if (yPicker > pDrawable -> height)
+  {
+    yPicker = pDrawable -> height;
+  }
+
+  return nxagentGetColor(pDrawable, xPicker, yPicker);
+}
+
+unsigned long nxagentGetDrawableColor(DrawablePtr pDrawable)
+{
+  int xPicker, yPicker;
+
+  /*
+   * The pixel used to determine the co-
+   * lor of a drawable is at coordinates
+   * (x + width - 4, y + 4).
+   */
+
+  xPicker = pDrawable -> width - 4;
+
+  yPicker = 4;
+
+  return nxagentGetColor(pDrawable, xPicker, yPicker);
+}
+
+void nxagentClearRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+  WindowPtr pWin;
+  BoxPtr pBox;
+
+  unsigned long color;
+  unsigned long backupPixel = 0;
+  int nBox, i;
+  int restore;
+
+  #ifdef DEBUG
+  static int nBoxCleared;
+  #endif
+
+  if (pDrawable -> type != DRAWABLE_WINDOW)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentClearRegion: Cannot clear a pixmap. Exiting.\n");
+    #endif
+
+    return;
+  }
+
+  if (pRegion == NullRegion || REGION_NIL(pRegion) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentClearRegion: The region is empty. Exiting.\n");
+    #endif
+
+    return;
+  }
+
+  pWin = (WindowPtr) pDrawable;
+
+  restore = 0;
+
+  /*
+   * If the window has already a background, we
+   * can hope it will be nice.
+   */
+
+  if (pWin -> backgroundState != None)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClearRegion: Window at [%p] has background state [%u].\n",
+                (void *) pWin, pWin -> backgroundState);
+    #endif
+  }
+  else
+  {
+    /*
+     * Save the original state.
+     */
+
+    backupPixel = pWin -> background.pixel;
+
+    color = nxagentGetDrawableColor((DrawablePtr) pWin);
+
+    if (color == -1)
+    {
+      color = 0xffffff;
+    }
+
+    pWin -> backgroundState = BackgroundPixel;
+    pWin -> background.pixel = color;
+
+    nxagentChangeWindowAttributes(pWin, CWBackPixel);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClearRegion: Window at [%p] now has pixel background [%ld].\n",
+                (void *) pWin, color);
+    #endif
+
+    restore = 1;
+  }
+
+  pBox = nxagentGetOptimizedRegionBoxes(pRegion);
+
+  nBox = REGION_NUM_RECTS(pRegion);
+
+  for (i = 0; i < nBox; i++)
+  {
+    if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+            pBox[i].x2 == 0 && pBox[i].y2 == 0)
+    {
+      continue;
+    }
+
+    XClearArea(nxagentDisplay, nxagentWindow(pWin), pBox[i].x1, pBox[i].y1,
+                   pBox[i].x2 - pBox[i].x1, pBox[i].y2 - pBox[i].y1, False);
+
+    #ifdef DEBUG
+    nBoxCleared++;
+    #endif
+  }
+
+  /*
+   * Restore the old state.
+   */
+
+  if (restore == 1)
+  {
+    pWin -> backgroundState = None;
+    pWin -> background.pixel = backupPixel;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentClearRegion: Number of cleared boxes is [%d].\n", nBoxCleared);
+  #endif
+}
+
+void nxagentFillRemoteRegion(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+  GCPtr      pGC;
+  BoxPtr     pBox;
+  XRectangle *pRects;
+
+  int        nrects;
+  int        i;
+
+  if (REGION_NIL(pRegion) == 1)
+  {
+    return;
+  }
+
+  pGC = nxagentGetGraphicContext(pDrawable);
+
+  nrects = REGION_NUM_RECTS(pRegion);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentFillRemoteRegion: Going to fill remote region [%d,%d,%d,%d] rects [%d] with color [%lu].\n",
+              pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+                  nrects, pGC -> fgPixel);
+  #endif
+
+  if (nrects == 1)
+  {
+    XFillRectangle(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                      pRegion -> extents.x1, pRegion -> extents.y1,
+                          pRegion -> extents.x2 - pRegion -> extents.x1,
+                              pRegion -> extents.y2 - pRegion -> extents.y1);
+  }
+  else
+  {
+    pBox = REGION_RECTS(pRegion);
+
+    pRects = xalloc(nrects * sizeof(XRectangle));
+
+    for (i = 0; i < nrects; i++)
+    {
+      pRects[i].x      = pBox[i].x1;
+      pRects[i].y      = pBox[i].y1;
+      pRects[i].width  = pBox[i].x2 - pBox[i].x1;
+      pRects[i].height = pBox[i].y2 - pBox[i].y1;
+    }
+
+    XFillRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                        pRects, nrects);
+
+    xfree(pRects);
+  }
+}
+
+int nxagentDestroyCorruptedWindowResource(pointer p, XID id)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyCorruptedWindowResource: Removing corrupted window [%p] from resources.\n",
+              (void *) p);
+  #endif
+
+  nxagentWindowPriv((WindowPtr) p) -> corruptedId = None;
+
+  return 1;
+}
+
+int nxagentDestroyCorruptedPixmapResource(pointer p, XID id)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyCorruptedPixmapResource: Removing corrupted pixmap [%p] from resources.\n",
+              (void *) p);
+  #endif
+
+  nxagentPixmapPriv((PixmapPtr) p) -> corruptedId = None;
+
+  return 1;
+}
+
+int nxagentDestroyCorruptedBackgroundResource(pointer p, XID id)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyCorruptedBackgroundResource: Removing corrupted pixmap background [%p] from resources.\n",
+              (void *) p);
+  #endif
+
+  nxagentPixmapPriv((PixmapPtr) p) -> corruptedBackgroundId = None;
+
+  return 1;
+}
+
+void nxagentPointsToDirtyRegion(DrawablePtr pDrawable, int mode,
+                                    int nPoints, xPoint *pPoints)
+{
+  RegionPtr pRegion;
+  RegionRec tmpRegion;
+  BoxRec box, extents;
+
+  xPoint *xp;
+  int np;
+
+  np = nPoints;
+  xp = pPoints;
+
+  pRegion = REGION_CREATE(pDrawable -> pScreen, NullBox, 1);
+
+  while (np--)
+  {
+    if (CoordModePrevious)
+    {
+      box.x1 = box.x2 = (xp-1) -> x + xp -> x;
+      box.y1 = box.y2 = (xp-1) -> y + xp -> y;
+    }
+    else
+    {
+      box.x1 = box.x2 = xp -> x;
+      box.y1 = box.y2 = xp -> y;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentPointsToDirtyRegion: Adding the point (%d,%d) to the dirty region.\n",
+                box.x1, box.y1);
+    #endif
+
+    /*
+     * By using REGION_APPEND() and REGION_VALIDATE()
+     * this loop could become less expensive.
+     */
+
+    REGION_INIT(pDrawable -> pScreen, &tmpRegion, &box, 1);
+
+    REGION_UNION(pDrawable -> pScreen, pRegion, pRegion, &tmpRegion);
+
+    REGION_UNINIT(pDrawable -> pScreen, &tmpRegion);
+
+    xp++;
+  }
+
+  extents = *REGION_EXTENTS(pDrawable -> pScreen, pRegion);
+
+  REGION_RESET(pDrawable -> pScreen, pRegion, &extents);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPointsToDirtyRegion: The resulting dirty region has [%ld] rects and"
+              " extents (%d,%d,%d,%d).\n", REGION_NUM_RECTS(pRegion), extents.x1,
+                  extents.y1, extents.x2, extents.y2);
+  #endif
+
+  nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+  REGION_DESTROY(pDrawable -> pScreen, pRegion);
+}
+
+#ifdef DUMP
+
+#define USE_MULTIPLE_COLORS
+
+void nxagentCorruptedRegionOnWindow(void *p0, XID x, void *p2)
+{
+  WindowPtr pWin = (WindowPtr) p0;
+  RegionPtr clipRegion;
+  RegionRec visRegion;
+  BoxPtr pBox;
+
+  XlibGC gc;
+  XGCValues value;
+
+  static unsigned long color = 0xff000000;
+  int nrectangles;
+  int i;
+
+  /*
+   * There are no regions to draw.
+   */
+
+  if (nxagentDrawableStatus((DrawablePtr) pWin) == Synchronized)
+  {
+    return;
+  }
+
+  /*
+   * The window is not visible.
+   */
+
+  if (nxagentWindowIsVisible(pWin) == 0)
+  {
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCorruptedRegionOnWindow: Going to draw on window at [%p].\n",
+              (void *) pWin);
+  #endif
+
+  clipRegion = nxagentCreateRegion((DrawablePtr) pWin, NULL, 0, 0,
+                                      pWin -> drawable.width, pWin -> drawable.height);
+
+  REGION_INIT(pWin -> drawable.pScreen, &visRegion, NullBox, 1);
+
+  REGION_INTERSECT(pWin -> drawable.pScreen, &visRegion, clipRegion, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+  nxagentFreeRegion(pWin -> drawable.pScreen, clipRegion);
+
+  if (REGION_NIL(&visRegion) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCorruptedRegionOnWindow: The corrupted region of window at [%p] is hidden.\n",
+                (void *) pWin);
+    #endif
+
+    REGION_UNINIT(pWin -> drawable.pScreen, &visRegion);
+
+    return;
+  }
+
+  nxagentClearRegion((DrawablePtr) pWin, &visRegion);
+
+  #ifdef USE_MULTIPLE_COLORS
+
+  color += nxagentWindow(pWin) * 5;
+
+  if (color == 0 || color == 0xffffffff)
+  {
+    color = 0xff000000;
+  }
+
+  #endif
+
+  value.foreground = color;
+  value.subwindow_mode = IncludeInferiors;
+
+  gc = XCreateGC(nxagentDisplay, nxagentWindow(pWin), GCForeground | GCSubwindowMode, &value);
+
+  nrectangles = REGION_NUM_RECTS(&visRegion);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCorruptedRegionOnWindow: Going to draw the region with extents [%d,%d,%d,%d] and [%d] rects.\n",
+              visRegion.extents.x1, visRegion.extents.y1, visRegion.extents.x2, visRegion.extents.y2,
+                  nrectangles);
+  #endif
+
+  pBox = nxagentGetOptimizedRegionBoxes(&visRegion);
+
+  for (i = 0; i < nrectangles; i++)
+  {
+    if (pBox[i].x1 == 0 && pBox[i].y1 == 0 &&
+            pBox[i].x2 == 0 && pBox[i].y2 == 0)
+    {
+      continue;
+    }
+
+    XDrawRectangle(nxagentDisplay, nxagentWindow(pWin), gc,
+                       pBox[i].x1, pBox[i].y1, pBox[i].x2 - pBox[i].x1 - 1,
+                           pBox[i].y2 - pBox[i].y1 - 1);
+  }
+
+  XFreeGC(nxagentDisplay, gc);
+
+  REGION_UNINIT(pWin -> drawable.pScreen, &visRegion);
+}
+
+void nxagentRegionsOnScreen()
+{
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_CORR_WINDOW,
+                                nxagentCorruptedRegionOnWindow, NULL);
+}
+
+#endif
+
+/*
+ * If the synchronization loop breaks and the
+ * drawable synchronization cannot be completed,
+ * the remaining data is stored in a bitmap.
+ * The synchronization loop is then restarted
+ * using the bitmap as source instead of the
+ * drawable.
+ */
+
+void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
+{
+  PixmapPtr pBitmap;
+  GCPtr pGC = NULL;
+  RegionPtr pClipRegion = NullRegion;
+
+  char *data = NULL;
+
+  int x, y;
+  int w, h;
+  int length, format;
+  int saveTrap;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for drawable at [%p].\n",
+              (void *) pDrawable);
+  #endif
+
+  /*
+   * The bitmap is created only in the
+   * nxagent.
+   */
+
+  saveTrap = nxagentGCTrap;
+
+  nxagentGCTrap = 1;
+
+  if (nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCreateDrawableBitmap: The drawable is already synchronized. Skipping bitmap creation.\n");
+    #endif
+
+    goto nxagentCreateDrawableBitmapEnd;
+  }
+
+  /*
+   * Should create a function to append
+   * a bitmap to another, instead of de-
+   * stroy the old one.
+   */
+
+  if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreateDrawableBitmap: WARNING! Going to replace the bitmap at [%p] with corrupted [%d,%d,%d,%d].\n",
+                  (void *) nxagentDrawableBitmap(pDrawable),
+                      nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+                          nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+                              nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+                                  nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2);
+    #endif
+
+    nxagentDestroyDrawableBitmap(pDrawable);
+  }
+
+  /*
+   * Clipping to the visible area.
+   */
+
+  pClipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
+
+  REGION_INTERSECT(pDrawable -> pScreen, pClipRegion, pClipRegion, nxagentCorruptedRegion(pDrawable));
+
+  if (REGION_NIL(pClipRegion) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCreateDrawableBitmap: The corrupted region is not visible. Skipping bitmap creation.\n");
+    #endif
+
+    goto nxagentCreateDrawableBitmapEnd;
+  }
+
+  pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth);
+
+  pGC = GetScratchGC(pBitmap -> drawable.depth, pBitmap -> drawable.pScreen);
+
+  ValidateGC((DrawablePtr) pBitmap, pGC);
+
+  x = pClipRegion -> extents.x1;
+  y = pClipRegion -> extents.y1;
+  w = pClipRegion -> extents.x2 - pClipRegion -> extents.x1;
+  h = pClipRegion -> extents.y2 - pClipRegion -> extents.y1;
+
+  data = nxagentAllocateImageData(w, h, pDrawable -> depth, &length, &format);
+
+  if (data == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreateDrawableBitmap: Cannot allocate memory for the bitmap data.\n");
+    #endif
+
+    nxagentDestroyPixmap(pBitmap);
+
+    goto nxagentCreateDrawableBitmapEnd;
+  }
+
+  nxagentGetImage(pDrawable, x, y, w, h, format, AllPlanes, data);
+
+  nxagentPutImage((DrawablePtr) pBitmap, pGC, pBitmap -> drawable.depth, x, y, w, h,
+                      0, format, data);
+ 
+  REGION_UNION(pDrawable -> pScreen, nxagentCorruptedRegion((DrawablePtr) pBitmap),
+                   nxagentCorruptedRegion((DrawablePtr) pBitmap), pClipRegion);
+
+  if (pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> synchronizationBitmap = pBitmap;
+
+    if (nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1)
+    {
+      nxagentSynchronization.backgroundBitmaps++;
+    }
+    else
+    {
+      nxagentSynchronization.pixmapBitmaps++;
+    }
+  }
+  else
+  {
+    nxagentWindowPriv((WindowPtr) pDrawable) -> synchronizationBitmap = pBitmap;
+
+    nxagentSynchronization.windowBitmaps++;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateDrawableBitmap: Drawable [%p] has bitmap at [%p] with corrupted [%d,%d,%d,%d].\n",
+                (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable),
+                    nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2);
+  #endif
+
+nxagentCreateDrawableBitmapEnd:
+
+  nxagentGCTrap = saveTrap;
+
+  if (pClipRegion != NullRegion)
+  {
+    nxagentFreeRegion(pDrawable, pClipRegion);
+  }
+
+  if (data != NULL)
+  {
+    xfree(data);
+  }
+
+  if (pGC != NULL)
+  {
+    FreeScratchGC(pGC);
+  }
+}
+
+void nxagentDestroyDrawableBitmap(DrawablePtr pDrawable)
+{
+  if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentDestroyDrawableBitmap: Destroying bitmap for drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    nxagentDestroyPixmap(nxagentDrawableBitmap(pDrawable));
+
+    if (pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> synchronizationBitmap = NullPixmap;
+
+      if (nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1)
+      {
+        nxagentSynchronization.backgroundBitmaps--;
+      }
+      else
+      {
+        nxagentSynchronization.pixmapBitmaps--;
+      }
+    }
+    else
+    {
+      nxagentWindowPriv((WindowPtr) pDrawable) -> synchronizationBitmap = NullPixmap;
+
+      nxagentSynchronization.windowBitmaps--;
+    }
+  }
+}
+
+void nxagentIncreasePixmapUsageCounter(PixmapPtr pPixmap)
+{
+  if (nxagentDrawableStatus((DrawablePtr) pPixmap) == Synchronized)
+  {
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentIncreasePixmapUsageCounter: Pixmap usage counter was [%d].\n",
+              nxagentPixmapUsageCounter(pPixmap));
+  #endif
+
+  nxagentPixmapUsageCounter(pPixmap) += 1;
+
+  nxagentAllocateCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+}
+
+void nxagentAllocateCorruptedResource(DrawablePtr pDrawable, RESTYPE type)
+{
+  PixmapPtr pRealPixmap;
+
+  if (nxagentSessionState == SESSION_DOWN)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentAllocateCorruptedResource: WARNING! Not allocated corrupted resource "
+                "[%s][%p] with the display down.\n", nxagentDrawableType(pDrawable),
+                    (void *) pDrawable);
+    #endif
+
+    return;
+  }
+
+  if (type == RT_NX_CORR_WINDOW)
+  {
+    if (nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentAllocateCorruptedResource: New resource at [%p]. Corrupted "
+                  "windows counter was [%d].\n", (void *) pDrawable, nxagentCorruptedWindows);
+      #endif
+
+      nxagentCorruptedWindows++;
+
+      nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId = FakeClientID(serverClient -> index);
+
+      AddResource(nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId, RT_NX_CORR_WINDOW,
+                      (pointer) pDrawable);
+    }
+  }
+  else if (type == RT_NX_CORR_BACKGROUND)
+  {
+    pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+    if (nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId == 0)
+    {
+      /*
+       * When a pixmap is added to the background
+       * corrupted resources, it must be removed
+       * from the pixmap corrupted resources.
+       */
+
+      nxagentDestroyCorruptedResource(pDrawable, RT_NX_CORR_PIXMAP);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentAllocateCorruptedResource: New resource at [%p]. Corrupted "
+                  "backgrounds counter was [%d].\n", (void *) pDrawable, nxagentCorruptedBackgrounds);
+      #endif
+
+      nxagentCorruptedBackgrounds++;
+
+      nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId = FakeClientID(serverClient -> index);
+
+      AddResource(nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId, RT_NX_CORR_BACKGROUND,
+                      (pointer) pRealPixmap);
+    }
+  }
+  else if (type == RT_NX_CORR_PIXMAP)
+  {
+    /*
+     * The shared memory pixmaps are always dirty
+     * and shouldn't be synchronized.
+     */
+
+    if (nxagentPixmapUsageCounter((PixmapPtr) pDrawable) >= MINIMUM_PIXMAP_USAGE_COUNTER &&
+            nxagentIsShmPixmap((PixmapPtr) pDrawable) == 0)
+    {
+      pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+      if (nxagentPixmapPriv(pRealPixmap) -> corruptedId == 0)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentAllocateCorruptedResource: New resource at [%p]. Corrupted "
+                    "pixmaps counter was [%d].\n", (void *) pDrawable, nxagentCorruptedPixmaps);
+        #endif
+
+        nxagentCorruptedPixmaps++;
+
+        nxagentPixmapPriv(pRealPixmap) -> corruptedId = FakeClientID(serverClient -> index);
+
+        AddResource(nxagentPixmapPriv(pRealPixmap) -> corruptedId, RT_NX_CORR_PIXMAP,
+                        (pointer) pRealPixmap);
+      }
+    }
+  }
+}
+
+void nxagentDestroyCorruptedResource(DrawablePtr pDrawable, RESTYPE type)
+{
+  PixmapPtr pRealPixmap;
+
+  if (type == RT_NX_CORR_WINDOW)
+  {
+    if (nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId != 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDestroyCorruptedResource: Removing resource at [%p]. Corrupted "
+                  "windows counter was [%d].\n", (void *) pDrawable, nxagentCorruptedWindows);
+      #endif
+
+      if (nxagentCorruptedWindows > 0)
+      {
+        nxagentCorruptedWindows--;
+      }
+
+      FreeResource(nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedId, RT_NONE);
+
+      if (nxagentSynchronization.pDrawable == pDrawable)
+      {
+        nxagentSynchronization.pDrawable = NULL;
+      }
+    }
+  }
+  else if (type == RT_NX_CORR_BACKGROUND)
+  {
+    pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+    if (nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId != 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDestroyCorruptedResource:  Removing resource at [%p]. Corrupted "
+                  "backgrounds counter was [%d].\n", (void *) pDrawable, nxagentCorruptedBackgrounds);
+      #endif
+
+      if (nxagentCorruptedBackgrounds > 0)
+      {
+        nxagentCorruptedBackgrounds--;
+      }
+
+      FreeResource(nxagentPixmapPriv(pRealPixmap) -> corruptedBackgroundId, RT_NONE);
+
+      if (nxagentSynchronization.pDrawable == pDrawable)
+      {
+        nxagentSynchronization.pDrawable = NULL;
+      }
+    }
+  }
+  else if (type == RT_NX_CORR_PIXMAP)
+  {
+    pRealPixmap = nxagentRealPixmap((PixmapPtr) pDrawable);
+
+    if (nxagentPixmapPriv(pRealPixmap) -> corruptedId != 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDestroyCorruptedResource:  Removing resource at [%p]. Corrupted "
+                  "pixmaps counter was [%d].\n", (void *) pDrawable, nxagentCorruptedPixmaps);
+      #endif
+
+      if (nxagentCorruptedPixmaps > 0)
+      {
+        nxagentCorruptedPixmaps--;
+      }
+
+      FreeResource(nxagentPixmapPriv(pRealPixmap) -> corruptedId, RT_NONE);
+
+      if (nxagentSynchronization.pDrawable == pDrawable)
+      {
+        nxagentSynchronization.pDrawable = NULL;
+      }
+    }
+  }
+}
+
+void nxagentCleanCorruptedDrawable(DrawablePtr pDrawable)
+{
+  if (nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCleanCorruptedDrawable: Clearing out the corrupted drawable [%s][%p].\n",
+              nxagentDrawableType(pDrawable), (void *) pDrawable);
+  #endif
+
+  nxagentUnmarkCorruptedRegion(pDrawable, NullRegion);
+
+  if (nxagentDrawableBitmap(pDrawable) != NullPixmap)
+  {
+    nxagentDestroyDrawableBitmap(pDrawable);
+  }
+}
+
+void nxagentUnmarkExposedRegion(WindowPtr pWin, RegionPtr pRegion, RegionPtr pOther)
+{
+  RegionRec clipRegion;
+
+  if (pRegion != NullRegion && REGION_NIL(pRegion) == 0 &&
+          nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+  {
+    REGION_INIT(pWin -> drawable.pScreen, &clipRegion, NullBox, 1);
+
+    REGION_COPY(pWin -> drawable.pScreen, &clipRegion, pRegion);
+    
+    if (pOther != NullRegion && REGION_NIL(pOther) == 0)
+    {
+      REGION_UNION(pWin -> drawable.pScreen, &clipRegion, &clipRegion, pOther);
+    }
+
+    REGION_TRANSLATE(pWin -> drawable.pScreen, &clipRegion, -pWin -> drawable.x, -pWin -> drawable.y);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentUnmarkExposedRegion: Validating expose region [%d,%d,%d,%d] "
+                "on window [%p].\n", clipRegion.extents.x1, clipRegion.extents.y1,
+                    clipRegion.extents.x2, clipRegion.extents.y2, (void *) pWin);
+    #endif
+
+    nxagentUnmarkCorruptedRegion((DrawablePtr) pWin, &clipRegion);
+
+    REGION_UNINIT(pWin -> drawable.pScreen, &clipRegion);
+  }
+}
+
+int nxagentSynchronizationPredicate()
+{
+  if (nxagentCorruptedWindows == 0 &&
+          nxagentCorruptedBackgrounds == 0 &&
+              nxagentCorruptedPixmaps == 0)
+  {
+    return NotNeeded;
+  }
+
+  if (nxagentBlocking == 0 &&
+          nxagentCongestion <= 4 &&
+              nxagentReady == 0 &&
+                  nxagentUserInput(NULL) == 0)
+  {
+    return Needed;
+  }
+
+  /*
+   * If there are resources to synchronize
+   * but the conditions to start the loop
+   * are not satisfied, a little delay is
+   * requested to check for a new loop as
+   * soon as possible.
+   */
+
+  return Delayed;
+}
+
+void nxagentSendBackgroundExpose(WindowPtr pWin, PixmapPtr pBackground, RegionPtr pExpose)
+{
+  RegionRec expose;
+  miBSWindowPtr pBackingStore;
+
+  REGION_INIT(pWin -> pScreen, &expose, NullBox, 1);
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentSendBackgroundExpose: Original expose region is [%d,%d,%d,%d].\n",
+              pExpose -> extents.x1, pExpose -> extents.y1,
+                  pExpose -> extents.x2, pExpose -> extents.y2);
+
+  fprintf(stderr, "nxagentSendBackgroundExpose: Window clipList is [%d,%d,%d,%d].\n",
+              pWin -> clipList.extents.x1, pWin -> clipList.extents.y1,
+                  pWin -> clipList.extents.x2, pWin -> clipList.extents.y2);
+  #endif
+
+  if (nxagentDrawableStatus((DrawablePtr) pBackground) == Synchronized &&
+          (pBackground -> drawable.width < pWin -> drawable.width ||
+              pBackground -> drawable.height < pWin -> drawable.height))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSendBackgroundExpose: Pixmap background [%dx%d] is "
+                "smaller than window [%dx%d]. Going to expose the winSize.\n",
+                    pBackground -> drawable.width, pBackground -> drawable.height, 
+                        pWin -> drawable.width, pWin -> drawable.height);
+    #endif
+
+    REGION_COPY(pWin -> pScreen, &expose, &pWin -> winSize);
+  }
+  else
+  {
+    REGION_COPY(pWin -> pScreen, &expose, pExpose);
+
+    REGION_TRANSLATE(pWin -> pScreen, &expose, pWin -> drawable.x, pWin -> drawable.y);
+  }
+
+  REGION_SUBTRACT(pWin -> pScreen, &expose, &expose, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+  if (REGION_NIL(&pWin -> clipList) != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSendBackgroundExpose: Exposures deferred because the window "
+                "is hidden.\n");
+    #endif
+
+    REGION_UNION(pWin -> pScreen, nxagentDeferredBackgroundExposures,
+                     nxagentDeferredBackgroundExposures, &expose);
+
+    nxagentWindowPriv(pWin) -> deferredBackgroundExpose = 1;
+
+    goto nxagentSendBackgroundExposeEnd;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSendBackgroundExpose: Sending expose [%d,%d,%d,%d].\n",
+              expose.extents.x1, expose.extents.y1, expose.extents.x2, expose.extents.y2);
+  #endif
+
+  /*
+   * This prevents hidden region to be exposed.
+   */
+
+  pBackingStore = (miBSWindowPtr)pWin->backStorage;
+
+  if ((pBackingStore != NULL) && (REGION_NIL(&pBackingStore->SavedRegion) == 0))
+  {
+    REGION_TRANSLATE(pWin -> pScreen, &expose, -pWin -> drawable.x, -pWin -> drawable.y);
+
+    REGION_SUBTRACT(pWin -> pScreen, &expose, &expose, &pBackingStore -> SavedRegion);
+
+    REGION_TRANSLATE(pWin -> pScreen, &expose, pWin -> drawable.x, pWin -> drawable.y);
+  }
+
+  REGION_INTERSECT(pWin -> pScreen, &expose, &expose, &pWin -> clipList);
+
+  miWindowExposures(pWin, &expose, &expose);
+
+nxagentSendBackgroundExposeEnd:
+
+  REGION_UNINIT(pWin -> pScreen, &expose);
+}
+
+void nxagentExposeBackgroundPredicate(void *p0, XID x1, void *p2)
+{
+  WindowPtr pWin = (WindowPtr) p0;
+  WindowPtr pParent;
+
+  struct nxagentExposeBackground *pPair = p2;
+
+  if (REGION_NIL(pPair -> pExpose) != 0)
+  {
+    return;
+  }
+
+  if (pWin -> backgroundState == BackgroundPixmap &&
+          pWin -> background.pixmap == pPair -> pBackground)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentExposeBackgroundPredicate: Window at [%p] uses pixmap [%p] "
+                "as background.\n", (void *) pWin, (void *) pPair -> pBackground);
+    #endif
+
+    nxagentSendBackgroundExpose(pWin, pPair -> pBackground, pPair -> pExpose);
+  }
+  else if (pWin -> backgroundState == ParentRelative)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentExposeBackgroundPredicate: Window [%p] uses parent's background.\n",
+                (void *) pWin);
+    #endif
+
+    pParent = pWin -> parent;
+
+    while (pParent != NULL)
+    {
+      if (pParent -> backgroundState == BackgroundPixmap &&
+              pParent -> background.pixmap == pPair -> pBackground)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentExposeBackgroundPredicate: Parent window at [%p] uses pixmap [%p] "
+                    "as background.\n", (void *) pParent, (void *) pPair -> pBackground);
+        #endif
+
+        nxagentSendBackgroundExpose(pWin, pPair -> pBackground, pPair -> pExpose);
+
+        break;
+      }
+
+      pParent = pParent -> parent;
+    }
+  }
+}
+
+/*
+ * This function is similar to nxagentClipAndSendExpose().
+ */
+
+int nxagentClipAndSendClearExpose(WindowPtr pWin, pointer ptr)
+{
+  RegionPtr exposeRgn;
+  RegionPtr remoteExposeRgn;
+
+  #ifdef DEBUG
+  BoxRec box;
+  #endif
+
+  remoteExposeRgn = (RegionRec *) ptr;
+
+  if (nxagentWindowPriv(pWin) -> deferredBackgroundExpose == 1)
+  {
+    exposeRgn = REGION_CREATE(pWin -> drawable.pScreen, NULL, 1);
+
+    #ifdef DEBUG
+    box = *REGION_EXTENTS(pWin->drawable.pScreen, remoteExposeRgn);
+
+    fprintf(stderr, "nxagentClipAndSendClearExpose: Background expose extents: [%d,%d,%d,%d].\n",
+                box.x1, box.y1, box.x2, box.y2);
+
+    box = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin -> clipList);
+
+    fprintf(stderr, "nxagentClipAndSendClearExpose: Clip list extents for window at [%p]: [%d,%d,%d,%d].\n",
+                (void *) pWin, box.x1, box.y1, box.x2, box.y2);
+    #endif
+
+    REGION_INTERSECT(pWin -> drawable.pScreen, exposeRgn, remoteExposeRgn, &pWin -> clipList);
+
+    /*
+     * If the region will be synchronized,
+     * the expose on corrupted regions can
+     * be ignored.
+     */
+
+    REGION_SUBTRACT(pWin -> drawable.pScreen, exposeRgn, exposeRgn, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+    if (REGION_NOTEMPTY(pWin -> drawable.pScreen, exposeRgn))
+    {
+      #ifdef DEBUG
+      box = *REGION_EXTENTS(pWin->drawable.pScreen, exposeRgn);
+
+      fprintf(stderr, "nxagentClipAndSendClearExpose: Forwarding expose [%d,%d,%d,%d] to window at [%p] pWin.\n",
+                  box.x1, box.y1, box.x2, box.y2, (void *) pWin);
+      #endif
+
+      REGION_SUBTRACT(pWin -> drawable.pScreen, remoteExposeRgn, remoteExposeRgn, exposeRgn);
+
+      miWindowExposures(pWin, exposeRgn, exposeRgn);
+    }
+
+    REGION_DESTROY(pWin -> drawable.pScreen, exposeRgn);
+
+    nxagentWindowPriv(pWin) -> deferredBackgroundExpose = 0;
+  }
+
+  if (REGION_NOTEMPTY(pWin -> drawable.pScreen, remoteExposeRgn))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClipAndSendClearExpose: Region not empty. Walk children.\n");
+    #endif
+
+
+    return WT_WALKCHILDREN;
+  }
+  else
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClipAndSendClearExpose: Region empty. Stop walking.\n");
+    #endif
+
+    return WT_STOPWALKING;
+  }
+}
+
+void nxagentSendDeferredBackgroundExposures(void)
+{
+  if (nxagentDeferredBackgroundExposures == NullRegion)
+  {
+    nxagentDeferredBackgroundExposures = REGION_CREATE(WindowTable[0] -> drawable.pScreen, NullBox, 1);
+  }
+
+  if (REGION_NOTEMPTY(WindowTable[0] -> drawable.pScreen, nxagentDeferredBackgroundExposures) != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSendDeferredBackgroundExposures: Going to send deferred exposures to the root window.\n");
+    #endif
+
+    TraverseTree(WindowTable[0], nxagentClipAndSendClearExpose, (void *) nxagentDeferredBackgroundExposures);
+
+    REGION_EMPTY(WindowTable[0] -> drawable.pScreen, nxagentDeferredBackgroundExposures);
+  }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
new file mode 100644
index 000000000..62af0685d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
@@ -0,0 +1,221 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Drawable_H__
+#define __Drawable_H__
+
+#include "resource.h"
+#include "Windows.h"
+#include "Pixmaps.h"
+
+/*
+ * Structures and macros used to manage the Lazy encoding.
+ */
+
+typedef struct
+{
+  DrawablePtr pDrawable;
+  int         drawableType;
+  int         abort;
+  int         windowBitmaps;
+  int         pixmapBitmaps;
+  int         backgroundBitmaps;
+
+} _nxagentSynchronizationRec;
+
+extern _nxagentSynchronizationRec nxagentSynchronization;
+
+enum DrawableStatus
+{
+  Synchronized,
+  NotSynchronized
+};
+
+enum SynchronizationPredicate
+{
+  Needed,
+  NotNeeded,
+  Delayed
+};
+
+/*
+ * Shall the synchronization wait for the
+ * drawable wakening?
+ */
+
+#define DONT_WAIT 0
+#define DO_WAIT   1
+
+/*
+ * How the synchronization loop can be
+ * interrupted? A 0 mask means that the
+ * loop can't be stopped.
+ */
+
+#define EVENT_BREAK       (1 << 0)
+#define CONGESTION_BREAK  (1 << 1)
+#define BLOCKING_BREAK    (1 << 2)
+
+#define NEVER_BREAK  0
+#define ALWAYS_BREAK (EVENT_BREAK      | \
+                      CONGESTION_BREAK | \
+                      BLOCKING_BREAK)
+
+/*
+ * Minimum value of usage counter which
+ * a pixmap should have to be synchronized.
+ */
+
+#define MINIMUM_PIXMAP_USAGE_COUNTER 2
+
+/*
+ * This is the macro used to get the external XID
+ * from a generic pointer to a drawable.
+ */
+
+#define nxagentDrawable(pDrawable) \
+  ((pDrawable)->type == DRAWABLE_WINDOW ? \
+      nxagentWindow((WindowPtr)pDrawable) : \
+          nxagentPixmap((PixmapPtr)pDrawable))
+
+#define nxagentVirtualDrawable(pDrawable) \
+  (DrawablePtr)((pDrawable)->type == DRAWABLE_WINDOW ? \
+      NULL : nxagentVirtualPixmap((PixmapPtr)pDrawable))
+
+#define nxagentDrawablePicture(pDrawable) \
+  ((DrawablePtr)((pDrawable)->type == DRAWABLE_WINDOW ? \
+      nxagentWindowPriv((WindowPtr)pDrawable) -> pPicture : \
+          nxagentPixmapPriv((PixmapPtr)pDrawable) -> pPicture))
+
+#define nxagentCorruptedRegion(pDrawable) \
+    ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+        nxagentPixmapCorruptedRegion((PixmapPtr) pDrawable) : \
+            nxagentWindowCorruptedRegion((WindowPtr) pDrawable))
+
+#define nxagentDrawableStatus(pDrawable) \
+    (REGION_NIL(nxagentCorruptedRegion(pDrawable)) ? \
+        Synchronized : NotSynchronized)
+
+#define nxagentDrawableContainGlyphs(pDrawable) \
+    ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+        nxagentPixmapContainGlyphs((PixmapPtr) (pDrawable)) : \
+            nxagentWindowContainGlyphs((WindowPtr) (pDrawable)))
+
+#define nxagentSetDrawableContainGlyphs(pDrawable, value) \
+do \
+{ \
+  if ((pDrawable) -> type == DRAWABLE_PIXMAP) \
+  { \
+    nxagentPixmapContainGlyphs(nxagentRealPixmap((PixmapPtr) (pDrawable))) = (value); \
+  } \
+  else \
+  { \
+    nxagentWindowContainGlyphs((WindowPtr) (pDrawable)) = (value); \
+  } \
+} while (0)
+
+#define nxagentDrawableBitmap(pDrawable) \
+    ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+        nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) (pDrawable))) -> synchronizationBitmap : \
+            nxagentWindowPriv((WindowPtr) (pDrawable)) -> synchronizationBitmap)
+
+#define nxagentDrawableTimestamp(pDrawable) \
+    ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+        nxagentPixmapTimestamp((PixmapPtr) pDrawable) : \
+            nxagentWindowTimestamp((WindowPtr) pDrawable))
+
+#define nxagentDrawableType(pDrawable) \
+    ((pDrawable) -> type == DRAWABLE_PIXMAP ? "pixmap" : "window")
+
+extern RESTYPE RT_NX_CORR_BACKGROUND;
+extern RESTYPE RT_NX_CORR_WINDOW;
+extern RESTYPE RT_NX_CORR_PIXMAP;
+
+extern int nxagentCorruptedPixmaps;
+extern int nxagentCorruptedWindows;
+extern int nxagentCorruptedBackgrounds;
+
+extern int nxagentForceSynchronization;
+
+extern RegionPtr nxagentCreateRegion(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                                  int width, int height);
+
+#define nxagentFreeRegion(pDrawable, pRegion) \
+    REGION_DESTROY((pDrawable) -> pScreen, pRegion);
+
+extern void nxagentMarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+extern void nxagentUnmarkCorruptedRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+extern void nxagentMoveCorruptedRegion(WindowPtr pWin, unsigned int mask);
+extern void nxagentIncreasePixmapUsageCounter(PixmapPtr pPixmap);
+
+extern int  nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned int breakMask, WindowPtr owner);
+extern void nxagentSynchronizeBox(DrawablePtr pDrawable, BoxPtr pBox, unsigned int breakMask);
+extern int  nxagentSynchronizeDrawable(DrawablePtr pDrawable, int wait, unsigned int breakMask, WindowPtr owner);
+extern int  nxagentSynchronizeDrawableData(DrawablePtr pDrawable, unsigned int breakMask, WindowPtr owner);
+extern void nxagentSynchronizationLoop(unsigned int mask);
+
+extern int nxagentSynchronizationPredicate(void);
+
+extern BoxPtr nxagentGetOptimizedRegionBoxes(RegionPtr pRegion);
+
+extern void nxagentCleanCorruptedDrawable(DrawablePtr pDrawable);
+
+extern void nxagentUnmarkExposedRegion(WindowPtr pWin, RegionPtr pRegion, RegionPtr pOther);
+extern void nxagentSendDeferredBackgroundExposures(void);
+
+extern void nxagentClearRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+extern void nxagentFillRemoteRegion(DrawablePtr pDrawable, RegionPtr pRegion);
+
+extern void nxagentAllocateCorruptedResource(DrawablePtr pDrawable, RESTYPE type);
+extern void nxagentDestroyCorruptedResource(DrawablePtr pDrawable, RESTYPE type);
+extern int nxagentDestroyCorruptedBackgroundResource(pointer p, XID id);
+extern int nxagentDestroyCorruptedWindowResource(pointer p, XID id);
+extern int nxagentDestroyCorruptedPixmapResource(pointer p, XID id);
+
+extern void nxagentCreateDrawableBitmap(DrawablePtr pDrawable);
+extern void nxagentDestroyDrawableBitmap(DrawablePtr pDrawable);
+
+extern void nxagentRegionsOnScreen(void);
+
+#define PRINT_REGION_BOXES(pRegion, strRegion) \
+do \
+{ \
+  int i; \
+  int numRects; \
+  BoxPtr pBox; \
+\
+  if (pRegion == NullRegion) \
+  { \
+    fprintf(stderr, "printRegionBoxes:: Region " strRegion " is null.\n"); \
+    break; \
+  } \
+\
+  numRects = REGION_NUM_RECTS(pRegion); \
+  pBox = REGION_RECTS(pRegion); \
+\
+  fprintf(stderr, "printRegionBoxes:: Region " strRegion " at [%p] has [%d] boxes:\n", \
+              (void *) (pRegion), numRects); \
+\
+  for (i = 0; i < numRects; i++) \
+  { \
+    fprintf(stderr, "[%d] [%d,%d,%d,%d]\n", \
+                i, pBox[i].x1, pBox[i].y1, pBox[i].x2, pBox[i].y2); \
+  } \
+\
+} while (0)
+
+#endif /* __Drawable_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.c b/nx-X11/programs/Xserver/hw/nxagent/Error.c
new file mode 100644
index 000000000..e60845dd3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.c
@@ -0,0 +1,636 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "os.h"
+
+#include "scrnintstr.h"
+#include "Agent.h"
+
+#include "Xlib.h"
+#include "Xproto.h"
+
+#include "Error.h"
+#include "Args.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+
+/*
+ * Duplicated stderr file descriptor.
+ */
+
+static int nxagentStderrDup = -1;
+
+/*
+ * Saved stderr file descriptor.
+ */
+
+static int nxagentStderrBackup = -1;
+
+/*
+ * Clients log file descriptor.
+ */
+
+static int nxagentClientsLog = -1;
+
+#define DEFAULT_STRING_LENGTH 256
+
+
+/*
+ * Clients log file name.
+ */
+
+char nxagentClientsLogName[DEFAULT_STRING_LENGTH] = { 0 };
+
+/*
+ * User's home.
+ */
+
+static char nxagentHomeDir[DEFAULT_STRING_LENGTH] = { 0 };
+
+/*
+ * NX root directory.
+ */
+
+static char nxagentRootDir[DEFAULT_STRING_LENGTH] = { 0 };
+
+/*
+ * Session log Directory.
+ */
+
+static char nxagentSessionDir[DEFAULT_STRING_LENGTH] = { 0 };
+
+char *nxagentGetClientsPath(void);
+
+static int nxagentPrintError(Display *dpy, XErrorEvent *event, FILE *fp);
+
+/* declare an error handler that does not exit when an error 
+ * event is catched.
+ */
+
+int nxagentErrorHandler(Display *dpy, XErrorEvent *event)
+{
+  if (nxagentVerbose == 1)
+  {
+    nxagentPrintError(dpy, event, stderr);
+  }
+
+  return 0;
+}
+
+/* copied from XlibInt.c */
+/* extension stuff roughly commented out */
+static int nxagentPrintError(dpy, event, fp)
+    Display *dpy;
+    XErrorEvent *event;
+    FILE *fp;
+{
+    char buffer[BUFSIZ];
+    char mesg[BUFSIZ];
+    char number[32];
+    char *mtype = "XlibMessage";
+    /*
+    register _XExtension *ext = (_XExtension *)NULL;
+    _XExtension *bext = (_XExtension *)NULL;
+    */
+    XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
+    XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+    (void) fprintf(fp, "%s:  %s\n  ", mesg, buffer);
+    XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+	mesg, BUFSIZ);
+    (void) fprintf(fp, mesg, event->request_code);
+    if (event->request_code < 128) {
+	sprintf(number, "%d", event->request_code);
+	XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+    } else {
+      /*	for (ext = dpy->ext_procs;
+	     ext && (ext->codes.major_opcode != event->request_code);
+	     ext = ext->next)
+	  ;
+	if (ext)
+	    strcpy(buffer, ext->name);
+	else
+      */
+	    buffer[0] = '\0';
+    }
+    (void) fprintf(fp, " (%s)\n", buffer);
+    if (event->request_code >= 128) {
+	XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+			      mesg, BUFSIZ);
+	fputs("  ", fp);
+	(void) fprintf(fp, mesg, event->minor_code);
+	/*
+	if (ext) {
+	    sprintf(mesg, "%s.%d", ext->name, event->minor_code);
+	    XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+	    (void) fprintf(fp, " (%s)", buffer);
+	}
+	*/
+	fputs("\n", fp);
+    }
+    if (event->error_code >= 128) {
+	/* kludge, try to find the extension that caused it */
+	buffer[0] = '\0';
+	/*
+	for (ext = dpy->ext_procs; ext; ext = ext->next) {
+	    if (ext->error_string) 
+		(*ext->error_string)(dpy, event->error_code, &ext->codes,
+				     buffer, BUFSIZ);
+	    if (buffer[0]) {
+		bext = ext;
+		break;
+	    }
+	    if (ext->codes.first_error &&
+		ext->codes.first_error < (int)event->error_code &&
+		(!bext || ext->codes.first_error > bext->codes.first_error))
+		bext = ext;
+	}    
+	if (bext)
+	    sprintf(buffer, "%s.%d", bext->name,
+		    event->error_code - bext->codes.first_error);
+	else
+	*/
+	    strcpy(buffer, "Value");
+	XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+	if (mesg[0]) {
+	    fputs("  ", fp);
+	    (void) fprintf(fp, mesg, event->resourceid);
+	    fputs("\n", fp);
+	}
+	/* let extensions try to print the values */
+	/*
+	for (ext = dpy->ext_procs; ext; ext = ext->next) {
+	    if (ext->error_values)
+		(*ext->error_values)(dpy, event, fp);
+	}
+	*/
+    } else if ((event->error_code == BadWindow) ||
+	       (event->error_code == BadPixmap) ||
+	       (event->error_code == BadCursor) ||
+	       (event->error_code == BadFont) ||
+	       (event->error_code == BadDrawable) ||
+	       (event->error_code == BadColor) ||
+	       (event->error_code == BadGC) ||
+	       (event->error_code == BadIDChoice) ||
+	       (event->error_code == BadValue) ||
+	       (event->error_code == BadAtom)) {
+	if (event->error_code == BadValue)
+	    XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+				  mesg, BUFSIZ);
+	else if (event->error_code == BadAtom)
+	    XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+				  mesg, BUFSIZ);
+	else
+	    XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+				  mesg, BUFSIZ);
+	fputs("  ", fp);
+	(void) fprintf(fp, mesg, event->resourceid);
+	fputs("\n", fp);
+    }
+    XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 
+			  mesg, BUFSIZ);
+    fputs("  ", fp);
+    (void) fprintf(fp, mesg, event->serial);
+    XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+			  mesg, BUFSIZ);
+    fputs("\n  ", fp);
+    /*    (void) fprintf(fp, mesg, dpy->request); */
+    fputs("\n", fp);
+    if (event->error_code == BadImplementation) return 0;
+    return 1;
+}
+
+int nxagentExitHandler(const char *message)
+{
+  FatalError(message);
+
+  return 0;
+}
+
+void nxagentOpenClientsLogFile()
+{
+  char * clientsLogName;
+
+  if (*nxagentClientsLogName == '\0')
+  {
+    clientsLogName = nxagentGetClientsPath();
+
+    if (clientsLogName != NULL)
+    {
+      free(clientsLogName);
+    }
+  }
+
+  if (nxagentClientsLogName != NULL && *nxagentClientsLogName !='\0')
+  {
+    nxagentClientsLog = open(nxagentClientsLogName, O_RDWR | O_CREAT | O_APPEND, 0600);
+
+    if (nxagentClientsLog == -1)
+    {
+      fprintf(stderr, "Warning: Failed to open clients log. Error is %d '%s'.\n",
+                  errno, strerror(errno));
+    }
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenClientsLogFile: Cannot open clients log file. The path does not exist.\n");
+    #endif
+  }
+}
+
+void nxagentCloseClientsLogFile(void)
+{
+  close(nxagentClientsLog);
+}
+
+void nxagentStartRedirectToClientsLog(void)
+{
+  nxagentOpenClientsLogFile();
+
+  if (nxagentClientsLog != -1)
+  {
+    if (nxagentStderrBackup == -1)
+    {
+      nxagentStderrBackup = dup(2);
+    }
+
+    if (nxagentStderrBackup != -1)
+    {
+      nxagentStderrDup = dup2(nxagentClientsLog, 2);
+
+      if (nxagentStderrDup == -1)
+      {
+        fprintf(stderr, "Warning: Failed to redirect stderr. Error is %d '%s'.\n",
+                    errno, strerror(errno));
+      }
+    }
+    else
+    {
+      fprintf(stderr, "Warning: Failed to backup stderr. Error is %d '%s'.\n",
+                  errno, strerror(errno));
+    }
+  }
+}
+
+void nxagentEndRedirectToClientsLog(void)
+{
+  if (nxagentStderrBackup != -1)
+  {
+    nxagentStderrDup = dup2(nxagentStderrBackup, 2);
+
+    if (nxagentStderrDup == -1)
+    {
+      fprintf(stderr, "Warning: Failed to restore stderr. Error is %d '%s'.\n",
+                  errno, strerror(errno));
+    }
+  }
+
+  nxagentCloseClientsLogFile();
+}
+
+char *nxagentGetHomePath(void)
+{
+  char *homeEnv;
+  char *homePath;
+
+  if (*nxagentHomeDir == '\0')
+  {
+    /*
+     * Check the NX_HOME environment.
+     */
+
+    homeEnv = getenv("NX_HOME");
+
+    if (homeEnv == NULL || *homeEnv == '\0')
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentGetHomePath: No environment for NX_HOME.\n");
+      #endif
+
+      homeEnv = getenv("HOME");
+
+      if (homeEnv == NULL || *homeEnv == '\0')
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentGetHomePath: PANIC! No environment for HOME.\n");
+        #endif
+
+        return NULL;
+      }
+    }
+
+    if (strlen(homeEnv) > DEFAULT_STRING_LENGTH - 1)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentGetHomePath: PANIC! Invalid value for the NX "
+                  "home directory '%s'.\n", homeEnv);
+      #endif
+    }
+
+    strncpy(nxagentHomeDir, homeEnv, DEFAULT_STRING_LENGTH - 1);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentGetHomePath: Assuming NX user's home directory '%s'.\n", nxagentHomeDir);
+    #endif
+  }
+
+  homePath = (char*) malloc(strlen(nxagentHomeDir) + 1);
+
+  if (homePath == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentGetHomePath: PANIC! Can't allocate memory for the home path.\n");
+    #endif
+
+    return NULL;
+  }
+
+  strcpy(homePath, nxagentHomeDir);
+
+  return homePath;
+}
+
+char *nxagentGetRootPath(void)
+{
+  char *rootEnv;
+  char *homeEnv;
+  char *rootPath;
+
+  struct stat dirStat;
+
+  if (*nxagentRootDir == '\0')
+  {
+    /*
+     * Check the NX_ROOT environment.
+     */
+
+    rootEnv = getenv("NX_ROOT");
+
+    if (rootEnv == NULL || *rootEnv == '\0')
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentGetRootPath: WARNING! No environment for NX_ROOT.\n");
+      #endif
+
+      /*
+       * We will determine the root NX directory
+       * based on the NX_HOME or HOME directory
+       * settings.
+       */
+
+      homeEnv = nxagentGetHomePath();
+
+      if (homeEnv == NULL)
+      {
+
+        #ifdef PANIC
+        #endif
+
+        return NULL;
+      }
+
+      if (strlen(homeEnv) > DEFAULT_STRING_LENGTH -
+              strlen("/.nx") - 1)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentGetRootPath: PANIC! Invalid value for the NX "
+                    "home directory '%s'.\n", homeEnv);
+        #endif
+
+        free(homeEnv);
+
+        return NULL;
+      }
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentGetRootPath: Assuming NX root directory in '%s'.\n", homeEnv);
+      #endif
+
+      strcpy(nxagentRootDir, homeEnv);
+      strcat(nxagentRootDir, "/.nx");
+
+      free(homeEnv);
+
+      /*
+       * Create the NX root directory.
+       */
+
+      if ((stat(nxagentRootDir, &dirStat) == -1) && (errno == ENOENT))
+      {
+        if (mkdir(nxagentRootDir, 0777) < 0 && (errno != EEXIST))
+        {
+          #ifdef PANIC
+          fprintf(stderr, "nxagentGetRootPath: PANIC! Can't create directory '%s'. Error is %d '%s'.\n",
+                      nxagentRootDir, errno, strerror(errno));
+          #endif
+
+          return NULL;
+        }
+      }
+    }
+    else
+    {
+      if (strlen(rootEnv) > DEFAULT_STRING_LENGTH - 1)
+      {
+        #ifdef PANIC
+         fprintf(stderr, "nxagentGetRootPath: PANIC! Invalid value for the NX root directory '%s'.\n",
+                     rootEnv);
+        #endif
+
+        return NULL;
+      }
+
+      strcpy(nxagentRootDir, rootEnv);
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentGetRootPath: Assuming NX root directory '%s'.\n",
+                nxagentRootDir);
+    #endif
+        
+  }
+
+  rootPath = malloc(strlen(nxagentRootDir) + 1);
+
+  if (rootPath == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentGetRootPath: Can't allocate memory for the root path.\n");
+    #endif
+
+    return NULL;
+  }
+
+  strcpy(rootPath, nxagentRootDir);
+
+  return rootPath;
+}
+
+char *nxagentGetSessionPath()
+{
+
+  char *rootPath;
+  char *sessionPath;
+
+  struct stat dirStat;
+
+  if (*nxagentSessionDir == '\0')
+  {
+    /*
+     * If nxagentSessionId does not exist we
+     * assume that the sessionPath cannot be
+     * realized and do not use the clients
+     * log file.
+     */
+
+    if (*nxagentSessionId == '\0')
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentGetSessionPath: Session id does not exist. Assuming session path NULL.\n");
+      #endif
+
+      return NULL;
+    }
+
+    rootPath = nxagentGetRootPath();
+
+    if (rootPath == NULL)
+    {
+      return NULL;
+    }
+
+    strcpy(nxagentSessionDir, rootPath);
+
+    free(rootPath);
+
+    if (strlen(nxagentSessionDir) + strlen("/C-") + strlen(nxagentSessionId) > DEFAULT_STRING_LENGTH - 1)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentGetSessionPath: PANIC!: Invalid value for the NX session directory '%s'.\n",
+                  nxagentSessionDir);
+      #endif
+
+      return NULL;
+    }
+
+    strcat(nxagentSessionDir, "/C-");
+
+    strcat(nxagentSessionDir, nxagentSessionId);
+
+    if ((stat(nxagentSessionDir, &dirStat) == -1) && (errno == ENOENT))
+    {
+      if (mkdir(nxagentSessionDir, 0777) < 0 && (errno != EEXIST))
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentGetSessionPath: PANIC! Can't create directory '%s'. Error is %d '%s'.\n",
+                    nxagentSessionDir, errno, strerror(errno));
+        #endif
+
+        return NULL;
+      }
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentGetSessionPath: NX session is '%s'.\n",
+                nxagentSessionDir);
+    #endif
+
+  }
+
+  sessionPath = malloc(strlen(nxagentSessionDir) + 1);
+
+  if (sessionPath  == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentGetSessionPath:: PANIC! Can't allocate memory for the session path.\n");
+    #endif
+
+    return NULL;
+  }
+
+
+  strcpy(sessionPath, nxagentSessionDir);
+
+  return sessionPath;
+}
+
+char *nxagentGetClientsPath()
+{
+  char *sessionPath;
+  char *clientsPath;
+
+  if (*nxagentClientsLogName == '\0')
+  {
+    sessionPath = nxagentGetSessionPath();
+
+    if (sessionPath == NULL)
+    {
+      return NULL;
+    }
+
+    if (strlen(sessionPath) + strlen("/clients") > DEFAULT_STRING_LENGTH - 1)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentGetClientsPath: PANIC! Invalid value for the NX clients Log File Path '%s'.\n",
+                  nxagentClientsLogName);
+      #endif
+
+      free(sessionPath);
+
+      return NULL;
+    }
+
+    strcpy(nxagentClientsLogName, sessionPath);
+
+    strcat(nxagentClientsLogName, "/clients");
+
+    free(sessionPath);
+  }
+
+  clientsPath = malloc(strlen(nxagentClientsLogName) + 1);
+
+  if (clientsPath == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentGetClientsPath: PANIC! Can't allocate memory for the clients Log File Path path.\n");
+    #endif
+
+    return NULL;
+  }
+
+  strcpy(clientsPath, nxagentClientsLogName);
+
+  return clientsPath; 
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.h b/nx-X11/programs/Xserver/hw/nxagent/Error.h
new file mode 100644
index 000000000..78e15592b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.h
@@ -0,0 +1,37 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Error_H__
+#define __Error_H__
+
+/*
+ * Clients log file name.
+ */
+
+extern char nxagentClientsLogName[];
+
+extern char nxagentVerbose;
+
+int nxagentErrorHandler(Display *dpy, XErrorEvent *event);
+
+int nxagentExitHandler(const char *message);
+
+void nxagentStartRedirectToClientsLog(void);
+
+void nxagentEndRedirectToClientsLog(void);
+
+#endif /* __Error_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
new file mode 100644
index 000000000..e1eab6fd2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -0,0 +1,3822 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "X.h"
+#include "signal.h"
+#include "unistd.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "selection.h"
+#include "keysym.h"
+#include "fb.h"
+#include "mibstorest.h"
+#include "osdep.h"
+
+#include "Agent.h"
+#include "Args.h"
+#include "Atoms.h"
+#include "Colormap.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Windows.h"
+#include "Pixmaps.h"
+#include "Keyboard.h"
+#include "Keystroke.h"
+#include "Events.h"
+#include "Pointer.h"
+#include "Rootless.h"
+#include "Splash.h"
+#include "Trap.h"
+#include "Dialog.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Split.h"
+#include "Drawable.h"
+#include "Handlers.h"
+#include "Utils.h"
+
+#include "NX.h"
+#include "NXvars.h"
+#include "NXproto.h"
+
+#ifdef NXAGENT_FIXKEYS
+#include "inputstr.h"
+#include "input.h"
+#endif
+
+#include "XKBlib.h"
+
+#define GC     XlibGC
+#define Font   XlibFont
+#define KeySym XlibKeySym
+#define XID    XlibXID
+#include "Xlibint.h"
+#undef  GC
+#undef  Font
+#undef  KeySym
+#undef  XID
+
+#include <X11/cursorfont.h>
+
+#include "Shadow.h"
+#include "Xrandr.h"
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level. Please note
+ * that if you want to enable DEBUG here, then
+ * you need to enable DEBUG even in Rootless.c
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef  BLOCKS
+
+extern Bool nxagentOnce;
+
+extern WindowPtr nxagentRootTileWindow;
+extern int nxagentSplashCount;
+
+extern int nxagentLastClipboardClient;
+
+#ifdef DEBUG
+extern Bool nxagentRootlessTreesMatch(void);
+#endif
+
+Bool   xkbdRunning = False;
+pid_t  pidkbd;
+
+WindowPtr nxagentLastEnteredWindow = NULL;
+
+PropertyRequestRec nxagentPropertyRequests[NXNumberOfResources];
+
+void nxagentHandleCollectPropertyEvent(XEvent*);
+
+/*
+ * Finalize the asynchronous handling
+ * of the X_GrabPointer requests.
+ */
+
+void nxagentHandleCollectGrabPointerEvent(int resource);
+
+Bool nxagentCollectGrabPointerPredicate(Display *display, XEvent *X, XPointer ptr);
+
+/*
+ * Used in Handlers.c to synchronize
+ * the agent with the remote X server.
+ */
+
+void nxagentHandleCollectInputFocusEvent(int resource);
+
+/*
+ * Viewport navigation.
+ */
+
+static int viewportInc = 1;
+static enum HandleEventResult viewportLastKeyPressResult;
+static int viewportLastX;
+static int viewportLastY;
+static Cursor viewportCursor;
+
+/*
+ * Keyboard and pointer are handled as they were real devices by
+ * Xnest and we inherit this behaviour. The following mask will
+ * contain the event mask selected for the root window of the
+ * agent. All the keyboard and pointer events will be translated
+ * by the agent and sent to the internal clients according to
+ * events selected by the inferior windows.
+ */
+
+static Mask defaultEventMask;
+
+#define MAX_INC 200
+#define INC_STEP 5
+#define nextinc(x)  ((x) < MAX_INC ? (x) += INC_STEP : (x))
+
+/*
+ * Used to mask the appropriate bits in
+ * the state reported by XkbStateNotify
+ * and XkbGetIndicatorState.
+ */
+
+#define CAPSFLAG_IN_REPLY     1
+#define CAPSFLAG_IN_EVENT     2
+#define NUMFLAG_IN_EVENT      16
+#define NUMFLAG_IN_REPLY      2
+
+CARD32 nxagentLastEventTime     = 0;
+CARD32 nxagentLastKeyPressTime  = 0;
+Time   nxagentLastServerTime    = 0;
+
+/*
+ * Used for storing windows that need to
+ * receive expose events from the agent.
+ */
+
+#define nxagentExposeQueueHead nxagentExposeQueue.exposures[nxagentExposeQueue.start]
+
+ExposeQueue nxagentExposeQueue;
+
+RegionPtr nxagentRemoteExposeRegion = NULL;
+
+static void nxagentForwardRemoteExpose(void);
+
+static int nxagentClipAndSendExpose(WindowPtr pWin, pointer ptr);
+
+/*
+ * Associate a resource to a drawable and
+ * store the region affected by the split
+ * operation.
+ */
+
+SplitResourceRec nxagentSplitResources[NXNumberOfResources];
+
+/*
+ * Associate a resource to an unpack
+ * operation.
+ */
+
+UnpackResourceRec nxagentUnpackResources[NXNumberOfResources];
+
+/*
+ * We have to check these before launching
+ * the terminate dialog in rootless mode.
+ */
+
+Bool nxagentLastWindowDestroyed = False;
+Time nxagentLastWindowDestroyedTime = 0;
+
+/*
+ * Set this flag when an user input event
+ * is received.
+ */
+
+int nxagentInputEvent = 0;
+
+int nxagentKeyDown = 0;
+
+void nxagentSwitchResizeMode(ScreenPtr pScreen);
+
+int nxagentCheckWindowConfiguration(XConfigureEvent* X);
+
+#define nxagentMonitoredDuplicate(keysym) \
+    ((keysym) == XK_Left || (keysym) == XK_Up || \
+        (keysym) == XK_Right || (keysym) == XK_Down || \
+            (keysym) == XK_Page_Up || (keysym) == XK_Page_Down || \
+                (keysym) == XK_Delete || (keysym) == XK_BackSpace)
+
+void nxagentRemoveDuplicatedKeys(XEvent *X);
+
+void ProcessInputEvents()
+{
+  mieqProcessInputEvents();
+}
+
+void nxagentSwitchResizeMode(ScreenPtr pScreen)
+{
+  XSizeHints sizeHints;
+
+  int desktopResize = nxagentOption(DesktopResize);
+
+  nxagentChangeOption(DesktopResize, !desktopResize);
+
+  sizeHints.flags = PMaxSize;
+
+  if (nxagentOption(DesktopResize) == 0)
+  {
+    fprintf(stderr,"Info: Disabled desktop resize mode in agent.\n");
+
+    nxagentLaunchDialog(DIALOG_DISABLE_DESKTOP_RESIZE_MODE);
+
+    sizeHints.max_width = nxagentOption(RootWidth);
+    sizeHints.max_height = nxagentOption(RootHeight);
+  }
+  else
+  {
+    fprintf(stderr,"Info: Enabled desktop resize mode in agent.\n");
+
+    nxagentLaunchDialog(DIALOG_ENABLE_DESKTOP_RESIZE_MODE);
+
+    nxagentRRSetScreenConfig(pScreen, nxagentOption(Width), nxagentOption(Height));
+
+    sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+    sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+  }
+
+  XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                       &sizeHints);
+}
+
+void nxagentShadowSwitchResizeMode(ScreenPtr pScreen)
+{
+  XSizeHints sizeHints;
+
+  int desktopResize = nxagentOption(DesktopResize);
+
+  nxagentChangeOption(DesktopResize, !desktopResize);
+
+  sizeHints.flags = PMaxSize;
+
+  if (nxagentOption(DesktopResize) == 0)
+  {
+    nxagentShadowSetRatio(1.0, 1.0);
+
+    nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], WindowTable[0],
+                                      WindowTable[0] -> drawable.width, WindowTable[0] -> drawable.height);
+
+    sizeHints.max_width = nxagentOption(RootWidth);
+    sizeHints.max_height = nxagentOption(RootHeight);
+
+    fprintf(stderr,"Info: Disabled resize mode in shadow agent.\n");
+  }
+  else
+  {
+    nxagentShadowSetRatio(nxagentOption(Width) * 1.0 /
+                              WindowTable[0] -> drawable.width, 
+                                  nxagentOption(Height) * 1.0 /
+                                      WindowTable[0] -> drawable.height);
+
+    nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)],
+                                      WindowTable[0], WindowTable[0] -> drawable.width,
+                                          WindowTable[0] -> drawable.height);
+
+    sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+    sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+
+    fprintf(stderr,"Info: Enabled resize mode in shadow agent.\n");
+  }
+
+  XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                       &sizeHints);
+}
+
+static void nxagentSwitchDeferMode(void)
+{
+  if (nxagentOption(DeferLevel) == 0)
+  {
+    nxagentChangeOption(DeferLevel, UNDEFINED);
+
+    nxagentSetDeferLevel();
+  }
+  else
+  {
+    nxagentChangeOption(DeferLevel, 0);
+  }
+
+  if (nxagentOption(DeferLevel) != 0)
+  {
+    nxagentLaunchDialog(DIALOG_ENABLE_DEFER_MODE);
+  }
+  else
+  {
+    nxagentLaunchDialog(DIALOG_DISABLE_DEFER_MODE);
+
+    nxagentForceSynchronization = 1;
+  }
+}
+
+static Bool nxagentExposurePredicate(Display *display, XEvent *event, XPointer window)
+{
+  /*
+   *  Handle both Expose and ProcessedExpose events.
+   *  The latters are those not filtered by function
+   *  nxagentWindowExposures().
+   */
+
+  if (window)
+  {
+    return ((event -> type == Expose || event -> type == ProcessedExpose) &&
+                event -> xexpose.window == *((Window *) window));
+  }
+  else
+  {
+    return (event -> type == Expose || event -> type == ProcessedExpose);
+  }
+}
+
+static int nxagentAnyEventPredicate(Display *display, XEvent *event, XPointer parameter)
+{
+  return 1;
+}
+
+int nxagentInputEventPredicate(Display *display, XEvent *event, XPointer parameter)
+{
+  switch (event -> type)
+  {
+    case KeyPress:
+    case KeyRelease:
+    case ButtonPress:
+    case ButtonRelease:
+    {
+      return 1;
+    }
+    default:
+    {
+      return 0;
+    }
+  }
+}
+
+void nxagentInitDefaultEventMask()
+{
+  Mask mask = NoEventMask;
+
+  mask |= (StructureNotifyMask | VisibilityChangeMask);
+
+  mask |= ExposureMask;
+
+  mask |= NXAGENT_KEYBOARD_EVENT_MASK;
+  mask |= NXAGENT_POINTER_EVENT_MASK;
+
+  defaultEventMask = mask;
+}
+
+void nxagentGetDefaultEventMask(Mask *mask_return)
+{
+  *mask_return = defaultEventMask;
+}
+
+void nxagentSetDefaultEventMask(Mask mask)
+{
+  defaultEventMask = mask;
+}
+
+void nxagentGetEventMask(WindowPtr pWin, Mask *mask_return)
+{
+  Mask mask = NoEventMask;
+
+  if (nxagentOption(Rootless))
+  {
+    /*
+     * mask = pWin -> eventMask &
+     *           ~(NXAGENT_KEYBOARD_EVENT_MASK | NXAGENT_POINTER_EVENT_MASK);
+     */
+
+    if (pWin -> drawable.class == InputOutput)
+    {
+      if (nxagentWindowTopLevel(pWin))
+      {
+        mask = defaultEventMask;
+      }
+      else
+      {
+        mask = ExposureMask | VisibilityChangeMask | PointerMotionMask;
+      }
+    }
+
+    mask |= PropertyChangeMask;
+  }
+  else if (pWin -> drawable.class != InputOnly)
+  {
+    mask = ExposureMask | VisibilityChangeMask;
+  }
+
+  *mask_return = mask;
+}
+
+static int nxagentChangeMapPrivate(WindowPtr pWin, pointer ptr)
+{
+  if (pWin && nxagentWindowPriv(pWin))
+  {
+    nxagentWindowPriv(pWin) -> isMapped = *((Bool *) ptr);
+  }
+
+  return WT_WALKCHILDREN;
+}
+
+static int nxagentChangeVisibilityPrivate(WindowPtr pWin, pointer ptr)
+{
+  if (pWin && nxagentWindowPriv(pWin))
+  {
+    nxagentWindowPriv(pWin) -> visibilityState = *((int *) ptr);
+  }
+
+  return WT_WALKCHILDREN;
+}
+
+void nxagentDispatchEvents(PredicateFuncPtr predicate)
+{
+  XEvent X;
+  xEvent x;
+  ScreenPtr pScreen = NULL;
+
+  Bool minimize = False;
+  Bool startKbd = False;
+  Bool closeSession = False;
+  Bool switchFullscreen = False;
+
+  /*
+   * Last entered top level window.
+   */
+
+  static WindowPtr nxagentLastEnteredTopLevelWindow = NULL;
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[Begin read]\n");
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDispatchEvents: Going to handle new events with "
+              "predicate [%p].\n", predicate);
+  #endif
+
+  if (nxagentRemoteExposeRegion == NULL)
+  {
+    nxagentInitRemoteExposeRegion();
+  }
+
+  /*
+   * We must read here, even if apparently there is
+   * nothing to read. The ioctl() based readable
+   * function, in fact, is often unable to detect a
+   * failure of the socket, in particular if the
+   * agent was connected to the proxy and the proxy
+   * is gone. Thus we must trust the wakeup handler
+   * that called us after the select().
+   */
+
+  #ifdef TEST
+
+  if (nxagentPendingEvents(nxagentDisplay) == 0)
+  {
+    fprintf(stderr, "nxagentDispatchEvents: PANIC! No event needs to be dispatched.\n");
+  }
+
+  #endif
+
+  /*
+   * We want to process all the events already in
+   * the queue, plus any additional event that may
+   * be read from the network. If no event can be
+   * read, we want to continue handling our clients
+   * without flushing the output buffer.
+   */
+
+  while (nxagentCheckEvents(nxagentDisplay, &X, predicate != NULL ? predicate :
+                                nxagentAnyEventPredicate, NULL) == 1)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDispatchEvents: Going to handle new event type [%d].\n",
+                X.type);
+    #endif
+
+    /*
+     * Handle the incoming event.
+     */
+
+    switch (X.type)
+    {
+      #ifdef NXAGENT_CLIPBOARD
+
+      case SelectionClear:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new SelectionClear event.\n");
+        #endif
+
+        nxagentClearSelection(&X);
+
+        break;
+      }
+      case SelectionRequest:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new SelectionRequest event.\n");
+        #endif
+
+        nxagentRequestSelection(&X);
+
+        break;
+      }
+      case SelectionNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new SelectionNotify event.\n");
+        #endif
+
+        nxagentNotifySelection(&X);
+
+        break;
+      }
+
+      #endif /* NXAGENT_CLIPBOARD */
+
+      case PropertyNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: PropertyNotify on "
+                    "prop %d[%s] window %lx state %d\n",
+                        (int)X.xproperty.atom, validateString(XGetAtomName(nxagentDisplay, X.xproperty.atom)),
+                            X.xproperty.window, X.xproperty.state);
+        #endif
+
+        nxagentHandlePropertyNotify(&X);
+
+        break;
+      }
+      case KeyPress:
+      {
+        enum HandleEventResult result;
+
+        KeySym keysym;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeyPress event.\n");
+        #endif
+
+        nxagentInputEvent = 1;
+
+        nxagentKeyDown++;
+
+        nxagentHandleKeyPress(&X, &result);
+
+        if (viewportLastKeyPressResult != result)
+        {
+          viewportInc = 1;
+
+          viewportLastKeyPressResult = result;
+        }
+
+        if (result != doNothing && result != doStartKbd)
+        {
+          pScreen = nxagentScreen(X.xkey.window);
+        }
+
+        switch (result)
+        {
+          case doNothing:
+          {
+            break;
+          }
+          case doCloseSession:
+          {
+            closeSession = TRUE;
+
+            break;
+          }
+          case doMinimize:
+          {
+            minimize = TRUE;
+
+            break;
+          }
+          case doStartKbd:
+          {
+            startKbd = TRUE;
+
+            break;
+          }
+          case doSwitchFullscreen:
+          {
+            switchFullscreen = TRUE;
+
+            break;
+          }
+          case doViewportUp:
+          {
+            nxagentMoveViewport(pScreen, 0, -nextinc(viewportInc));
+
+            break;
+          }
+          case doViewportDown:
+          {
+            nxagentMoveViewport(pScreen, 0, +nextinc(viewportInc));
+
+            break;
+          }
+          case doViewportLeft:
+          {
+            nxagentMoveViewport(pScreen, -nextinc(viewportInc), 0);
+
+            break;
+          }
+          case doViewportRight:
+          {
+            nxagentMoveViewport(pScreen, +nextinc(viewportInc), 0);
+
+            break;
+          }
+          case doSwitchResizeMode:
+          {
+            if (nxagentOption(Shadow) == 0)
+            {
+              if (nxagentNoDialogIsRunning)
+              {
+                nxagentSwitchResizeMode(pScreen);
+              }
+            }
+            else
+            {
+              nxagentShadowSwitchResizeMode(pScreen);
+            }
+
+            break;
+          }
+          case doSwitchDeferMode:
+          {
+            if (nxagentNoDialogIsRunning)
+            {
+              nxagentSwitchDeferMode();
+            }
+
+            break;
+          }
+          default:
+          {
+            FatalError("nxagentDispatchEvent: handleKeyPress returned unknown value\n");
+
+            break;
+          }
+        }
+
+        /*
+         * Elide multiple KeyPress/KeyRelease events of
+         * the same key and generate a single pair. This
+         * is intended to reduce the impact of the laten-
+         * cy on the key auto-repeat, handled by the re-
+         * mote X server. We may optionally do that only
+         * if the timestamps in the events show an exces-
+         * sive delay.
+         */
+
+        keysym = XKeycodeToKeysym(nxagentDisplay, X.xkey.keycode, 0);
+
+        if (nxagentMonitoredDuplicate(keysym) == 1)
+        {
+          nxagentRemoveDuplicatedKeys(&X);
+        }
+
+        if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow) == 1 && result == doNothing)
+        {
+          NXShadowEvent(nxagentDisplay, X);
+        }
+
+        break;
+      }
+      case KeyRelease:
+      {
+        enum HandleEventResult result;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeyRelease event.\n");
+        #endif
+
+        nxagentInputEvent = 1;
+
+        nxagentKeyDown--;
+
+        if (nxagentKeyDown <= 0)
+        {
+          nxagentKeyDown = 0;
+        }
+
+        if (nxagentXkbState.Initialized == 0)
+        {
+          nxagentInitKeyboardState();
+        }
+
+        x.u.u.type = KeyRelease;
+        x.u.u.detail = X.xkey.keycode;
+        x.u.keyButtonPointer.time = nxagentLastKeyPressTime + (X.xkey.time - nxagentLastServerTime);
+
+        nxagentLastServerTime = X.xkey.time;
+
+        nxagentLastEventTime = GetTimeInMillis();
+
+        if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)))
+        {
+          mieqEnqueue(&x);
+
+          CriticalOutputPending = 1;
+
+          if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+          {
+            NXShadowEvent(nxagentDisplay, X);
+          }
+        }
+
+        break;
+      }
+      case ButtonPress:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonPress event.\n");
+        #endif
+
+        nxagentInputEvent = 1;
+
+        if (nxagentOption(Fullscreen))
+        {
+          if (nxagentMagicPixelZone(X.xbutton.x, X.xbutton.y))
+          {
+            pScreen = nxagentScreen(X.xbutton.window);
+
+            minimize = True;
+
+            break;
+          }
+        }
+
+        if (nxagentIpaq && nxagentClients <= 0)
+        {
+          closeSession = TRUE;
+        }
+
+        if (nxagentOption(DesktopResize) == False &&
+                (X.xbutton.state & (ControlMask | Mod1Mask)) == (ControlMask | Mod1Mask))
+        {
+          /*
+           * Start viewport navigation mode.
+           */
+
+          int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+                                                    nxagentCollectGrabPointerPredicate);
+
+          ScreenPtr pScreen = nxagentScreen(X.xbutton.window);
+          viewportCursor = XCreateFontCursor(nxagentDisplay, XC_fleur);
+
+          NXCollectGrabPointer(nxagentDisplay, resource,
+                                   nxagentDefaultWindows[pScreen -> myNum], True,
+                                       NXAGENT_POINTER_EVENT_MASK, GrabModeAsync,
+                                           GrabModeAsync, None, viewportCursor,
+                                               CurrentTime);
+          viewportLastX = X.xbutton.x;
+          viewportLastY = X.xbutton.y;
+
+          break;
+        }
+
+        if (!(nxagentOption(Fullscreen) &&
+                X.xbutton.window == nxagentFullscreenWindow &&
+                    X.xbutton.subwindow == None))
+        {
+          x.u.u.type = ButtonPress;
+          x.u.u.detail = X.xbutton.button;
+          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+          if (nxagentOption(Rootless))
+          {
+            x.u.keyButtonPointer.rootX = X.xmotion.x_root;
+            x.u.keyButtonPointer.rootY = X.xmotion.y_root;
+          }
+          else
+          {
+            x.u.keyButtonPointer.rootX = X.xmotion.x - nxagentOption(RootX);
+            x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
+          }
+
+          mieqEnqueue(&x);
+
+          CriticalOutputPending = 1;
+        }
+
+        if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+        {
+          X.xbutton.x -= nxagentOption(RootX);
+          X.xbutton.y -= nxagentOption(RootY);
+
+          if (nxagentOption(YRatio) != DONT_SCALE)
+          {
+            X.xbutton.x = (X.xbutton.x << PRECISION) / nxagentOption(YRatio);
+          }
+
+          if (nxagentOption(XRatio) != DONT_SCALE)
+          {
+            X.xbutton.y = (X.xbutton.y << PRECISION) / nxagentOption(YRatio);
+          }
+
+          NXShadowEvent(nxagentDisplay, X);
+        }
+
+        break;
+      }
+      case ButtonRelease:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonRelease event.\n");
+        #endif
+
+        nxagentInputEvent = 1;
+
+        if (viewportCursor)
+        {
+          /*
+           * Leave viewport navigation mode.
+           */
+
+          XUngrabPointer(nxagentDisplay, CurrentTime);
+
+          XFreeCursor(nxagentDisplay, viewportCursor);
+
+          viewportCursor = None;
+        }
+
+        if (minimize != True)
+        {
+          x.u.u.type = ButtonRelease;
+          x.u.u.detail = X.xbutton.button;
+          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+          if (nxagentOption(Rootless))
+          {
+            x.u.keyButtonPointer.rootX = X.xmotion.x_root;
+            x.u.keyButtonPointer.rootY = X.xmotion.y_root;
+          }
+          else
+          {
+            x.u.keyButtonPointer.rootX = X.xmotion.x - nxagentOption(RootX);
+            x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
+          }
+
+          mieqEnqueue(&x);
+
+          CriticalOutputPending = 1;
+        }
+
+        if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+        {
+          X.xbutton.x -= nxagentOption(RootX);
+          X.xbutton.y -= nxagentOption(RootY);
+
+          if (nxagentOption(XRatio) != DONT_SCALE)
+          {
+            X.xbutton.x = (X.xbutton.x << PRECISION) / nxagentOption(XRatio);
+          }
+
+          if (nxagentOption(YRatio) != DONT_SCALE)
+          {
+            X.xbutton.y = (X.xbutton.y << PRECISION) / nxagentOption(YRatio);
+          }
+
+          NXShadowEvent(nxagentDisplay, X);
+        }
+
+        break;
+      }
+      case MotionNotify:
+      {
+        ScreenPtr pScreen = nxagentScreen(X.xmotion.window);
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new MotionNotify event.\n");
+        #endif
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Handling motion notify window [%ld] root [%ld] child [%ld].\n",
+                    X.xmotion.window, X.xmotion.root, X.xmotion.subwindow);
+
+        fprintf(stderr, "nxagentDispatchEvents: Pointer at [%d][%d] relative root [%d][%d].\n",
+                    X.xmotion.x, X.xmotion.y, X.xmotion.x_root, X.xmotion.y_root);
+        #endif
+
+        x.u.u.type = MotionNotify;
+
+        if (nxagentOption(Rootless))
+        {
+          WindowPtr pWin = nxagentWindowPtr(X.xmotion.window);
+
+          if (pWin)
+          {
+            nxagentLastEnteredWindow = pWin;
+          }
+
+          if (nxagentPulldownDialogPid == 0 && (X.xmotion.y_root <
+                  nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
+          {
+            if (pWin && nxagentLastEnteredTopLevelWindow &&
+                    nxagentClientIsDialog(wClient(pWin)) == 0 &&
+                        nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
+                            nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
+                                X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                    (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
+                                        X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                            (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
+                                                nxagentOption(Menu) == 1)
+            {
+              nxagentPulldownDialog(nxagentLastEnteredTopLevelWindow -> drawable.id);
+            }
+          }
+
+          x.u.keyButtonPointer.rootX = X.xmotion.x_root;
+          x.u.keyButtonPointer.rootY = X.xmotion.y_root;
+        }
+        else
+        {
+          x.u.keyButtonPointer.rootX = X.xmotion.x - nxagentOption(RootX);
+          x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
+        }
+
+        x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+        if (viewportCursor == None &&
+                !(nxagentOption(Fullscreen) &&
+                    X.xmotion.window == nxagentDefaultWindows[pScreen -> myNum]
+                        && X.xmotion.subwindow == None))
+        {
+          mieqEnqueue(&x);
+        }
+
+        /*
+         * This test is more complicated and probably not necessary, compared
+         * to a simple check on viewportCursor.
+         *
+         * if (!nxagentOption(Fullscreen) &&
+         *       (X.xmotion.state & (ControlMask | Mod1Mask | Button1Mask)) ==
+         *            (ControlMask | Mod1Mask | Button1Mask))
+         */
+
+        if (viewportCursor)
+        {
+          /*
+           * Pointer is in viewport navigation mode.
+           */
+
+          nxagentMoveViewport(pScreen, viewportLastX - X.xmotion.x, viewportLastY - X.xmotion.y);
+
+          viewportLastX = X.xmotion.x;
+          viewportLastY = X.xmotion.y;
+        }
+
+        if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow) && !viewportCursor)
+        {
+          X.xmotion.x -= nxagentOption(RootX);
+          X.xmotion.y -= nxagentOption(RootY);
+
+          if (nxagentOption(XRatio) != DONT_SCALE)
+          {
+            X.xmotion.x = (X.xmotion.x << PRECISION) / nxagentOption(XRatio);
+          }
+
+          if (nxagentOption(YRatio) != DONT_SCALE)
+          {
+            X.xmotion.y = (X.xmotion.y << PRECISION) / nxagentOption(YRatio);
+          }
+
+          NXShadowEvent(nxagentDisplay, X);
+        }
+
+        if (nxagentOption(Shadow) == 0)
+        {
+          nxagentInputEvent = 1;
+        }
+
+        break;
+      }
+      case FocusIn:
+      {
+        WindowPtr pWin;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new FocusIn event.\n");
+        #endif
+
+        /*
+         * Here we change the focus state in the agent.
+         * It looks like this is needed only for root-
+         * less mode at the present moment.
+         */
+
+        if (nxagentOption(Rootless) &&
+                (pWin = nxagentWindowPtr(X.xfocus.window)))
+        {
+          SetInputFocus(serverClient, inputInfo.keyboard, pWin -> drawable.id,
+                            RevertToPointerRoot, GetTimeInMillis(), False);
+        }
+
+        if (X.xfocus.detail != NotifyInferior)
+        {
+          pScreen = nxagentScreen(X.xfocus.window);
+
+          if (pScreen)
+          {
+            nxagentDirectInstallColormaps(pScreen);
+          }
+        }
+
+        break;
+      }
+      case FocusOut:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new FocusOut event.\n");
+        #endif
+
+        if (X.xfocus.detail != NotifyInferior)
+        {
+          pScreen = nxagentScreen(X.xfocus.window);
+
+          if (pScreen)
+          {
+            nxagentDirectUninstallColormaps(pScreen);
+          }
+        }
+
+        #ifdef NXAGENT_FIXKEYS
+
+        {
+          /*
+           * Force the keys all up when focus is lost.
+           */
+
+          int i, k;
+          int mask = 1;
+          CARD8 val;
+
+          XEvent xM;
+          memset(&xM, 0, sizeof(XEvent));
+
+          for (i = 0; i < DOWN_LENGTH; i++) /* input.h */
+          {
+            val = inputInfo.keyboard->key->down[i];
+
+            if (val != 0)
+            {
+              for (k = 0; k < 8; k++)
+              {
+                if (val & (mask << k))
+                {
+                  #ifdef NXAGENT_FIXKEYS_DEBUG
+                  fprintf(stderr, "sending KeyRelease event for keycode: %x\n",
+                              i * 8 + k);
+                  #endif
+
+                  if (!nxagentOption(Rootless) ||
+                          inputInfo.keyboard->key->modifierMap[i * 8 + k])
+                  {
+                    x.u.u.type = KeyRelease;
+                    x.u.u.detail = i * 8 + k;
+                    x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+                    if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
+                    {
+                      xM.type = KeyRelease;
+                      xM.xkey.display = nxagentDisplay;
+                      xM.xkey.type = KeyRelease;
+                      xM.xkey.keycode = i * 8 + k;
+                      xM.xkey.state = inputInfo.keyboard->key->state;
+                      xM.xkey.time = GetTimeInMillis();
+                      NXShadowEvent(nxagentDisplay, xM);
+                    }
+
+                    mieqEnqueue(&x);
+                  }
+                }
+              }
+            }
+          }
+
+          nxagentKeyDown = 0;
+        }
+
+        #endif /* NXAGENT_FIXKEYS */
+
+        break;
+      }
+      case KeymapNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeymapNotify event.\n");
+        #endif
+
+        break;
+      }
+      case EnterNotify:
+      {
+        WindowPtr pWin;
+
+        WindowPtr pTLWin = NULL;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new EnterNotify event.\n");
+        #endif
+
+        if (nxagentOption(Rootless))
+        {
+          pWin = nxagentWindowPtr(X.xcrossing.window);
+
+          if (pWin != NULL)
+          {
+            for (pTLWin = pWin;
+                     pTLWin -> parent != WindowTable[pTLWin -> drawable.pScreen -> myNum];
+                         pTLWin = pTLWin -> parent);
+          }
+
+          if (pTLWin)
+          {
+            nxagentLastEnteredTopLevelWindow = pTLWin;
+          }
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentDispatchEvents: nxagentLastEnteredTopLevelWindow [%p].\n",
+                      nxagentLastEnteredTopLevelWindow);
+          #endif
+        }
+
+        if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+                (pWin = nxagentWindowPtr(X.xcrossing.window)) &&
+                    nxagentWindowTopLevel(pWin) && !pWin -> overrideRedirect &&
+                        (pWin -> drawable.x != X.xcrossing.x_root - X.xcrossing.x - pWin -> borderWidth ||
+                            pWin -> drawable.y != X.xcrossing.y_root - X.xcrossing.y - pWin -> borderWidth))
+        {
+          /*
+           * This code is useful for finding the window
+           * position. It should be re-implemented by
+           * following the ICCCM 4.1.5 recommendations.
+           */
+
+          XID values[4];
+          register XID *value = values;
+          Mask mask = 0;
+          ClientPtr pClient = wClient(pWin);
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentDispatchEvents: pWin -> drawable.x [%d] pWin -> drawable.y [%d].\n",
+                      pWin -> drawable.x, pWin -> drawable.y);
+          #endif
+
+          *value++ = (XID) (X.xcrossing.x_root - X.xcrossing.x - pWin -> borderWidth);
+          *value++ = (XID) (X.xcrossing.y_root - X.xcrossing.y - pWin -> borderWidth);
+
+          /*
+           * nxagentWindowPriv(pWin)->x = (X.xcrossing.x_root - X.xcrossing.x);
+           * nxagentWindowPriv(pWin)->y = (X.xcrossing.y_root - X.xcrossing.y);
+           */
+
+          mask = CWX | CWY;
+
+          nxagentScreenTrap = 1;
+
+          ConfigureWindow(pWin, mask, (XID *) values, pClient);
+
+          nxagentScreenTrap = 0;
+        }
+
+        if (nxagentOption(Fullscreen))
+        {
+          if (X.xcrossing.window == nxagentFullscreenWindow &&
+                  X.xcrossing.detail != NotifyInferior)
+          {
+            nxagentGrabPointerAndKeyboard(&X);
+          }
+        }
+
+        if (X.xcrossing.detail != NotifyInferior)
+        {
+          pScreen = nxagentScreen(X.xcrossing.window);
+
+          if (pScreen)
+          {
+            NewCurrentScreen(pScreen, X.xcrossing.x, X.xcrossing.y);
+
+            x.u.u.type = MotionNotify;
+
+            if (nxagentOption(Rootless))
+            {
+              nxagentLastEnteredWindow = nxagentWindowPtr(X.xcrossing.window);
+              x.u.keyButtonPointer.rootX = X.xcrossing.x_root;
+              x.u.keyButtonPointer.rootY = X.xcrossing.y_root;
+            }
+            else
+            {
+              x.u.keyButtonPointer.rootX = X.xcrossing.x - nxagentOption(RootX);
+              x.u.keyButtonPointer.rootY = X.xcrossing.y - nxagentOption(RootY);
+            }
+
+            x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+            mieqEnqueue(&x);
+
+            nxagentDirectInstallColormaps(pScreen);
+          }
+        }
+
+        nxagentInputEvent = 1;
+
+        break;
+      }
+      case LeaveNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new LeaveNotify event.\n");
+        #endif
+
+        if (nxagentOption(Rootless) && X.xcrossing.mode == NotifyNormal &&
+                X.xcrossing.detail != NotifyInferior)
+        {
+          nxagentLastEnteredWindow = NULL;
+        }
+
+        if (nxagentOption(Fullscreen))
+        {
+          if (X.xcrossing.window == nxagentFullscreenWindow &&
+                  X.xcrossing.detail != NotifyInferior &&
+                      X.xcrossing.mode == NotifyNormal)
+          {
+            nxagentUngrabPointerAndKeyboard(&X);
+
+            pScreen = nxagentScreen(X.xcrossing.window);
+
+            minimize = True;
+          }
+        }
+
+        if (X.xcrossing.detail != NotifyInferior)
+        {
+          pScreen = nxagentScreen(X.xcrossing.window);
+
+          if (pScreen)
+          {
+            nxagentDirectUninstallColormaps(pScreen);
+          }
+        }
+
+        nxagentInputEvent = 1;
+
+        break;
+      }
+      case DestroyNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new DestroyNotify event.\n");
+        #endif
+
+        if (nxagentParentWindow != (Window) 0 &&
+                X.xdestroywindow.window == nxagentParentWindow)
+        {
+          fprintf(stderr, "Warning: Unhandled destroy notify event received in agent.\n");
+        }
+
+        break;
+      }
+      case ClientMessage:
+      {
+        enum HandleEventResult result;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new ClientMessage event.\n");
+        #endif
+
+        nxagentHandleClientMessageEvent(&X, &result);
+
+        if (result == doCloseSession)
+        {
+          closeSession = TRUE;
+        }
+
+        break;
+      }
+      case VisibilityNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new VisibilityNotify event.\n");
+        #endif
+
+        if (X.xvisibility.window != nxagentDefaultWindows[0])
+        {
+          Window window = X.xvisibility.window;
+
+          WindowPtr pWin = nxagentWindowPtr(window);
+
+          if (pWin && nxagentWindowPriv(pWin))
+          {
+            if (nxagentWindowPriv(pWin) -> visibilityState != X.xvisibility.state)
+            {
+              int value = X.xvisibility.state;
+
+              if (nxagentOption(Rootless) == 1)
+              {
+                TraverseTree(pWin, nxagentChangeVisibilityPrivate, &value);
+              }
+              else
+              {
+                nxagentChangeVisibilityPrivate(pWin, &value);
+              }
+            }
+          }
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentDispatchEvents: Suppressing visibility notify on window [%lx].\n",
+                      X.xvisibility.window);
+          #endif
+
+          break;
+        }
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Visibility notify state is [%d] with previous [%d].\n",
+                    X.xvisibility.state, nxagentVisibility);
+        #endif
+
+        nxagentVisibility = X.xvisibility.state;
+
+        break;
+      }
+      case Expose:
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new Expose event.\n");
+        #endif
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchEvents: WARNING! Received Expose event "
+                    "for drawable [%lx] geometry [%d, %d, %d, %d] count [%d].\n",
+                        X.xexpose.window, X.xexpose.x, X.xexpose.y, X.xexpose.width,
+                            X.xexpose.height, X.xexpose.count);
+        #endif
+
+        nxagentHandleExposeEvent(&X);
+
+        break;
+      }
+      case GraphicsExpose:
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new GraphicsExpose event.\n");
+        #endif
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchEvents: WARNING! Received GraphicsExpose event "
+                    "for drawable [%lx] geometry [%d, %d, %d, %d] count [%d].\n",
+                        X.xgraphicsexpose.drawable, X.xgraphicsexpose.x, X.xgraphicsexpose.y,
+                            X.xgraphicsexpose.width, X.xgraphicsexpose.height,
+                                X.xgraphicsexpose.count);
+        #endif
+
+        nxagentHandleGraphicsExposeEvent(&X);
+
+        break;
+      }
+      case NoExpose:
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new NoExpose event.\n");
+        #endif
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchEvents: WARNING! Received NoExpose event for "
+                    "drawable [%lx].\n", X.xnoexpose.drawable);
+        #endif
+
+        break;
+      }
+      case CirculateNotify:
+      {
+        /*
+         * WindowPtr pWin;
+         * WindowPtr pSib;
+         * ClientPtr pClient;
+
+         * XID values[2];
+         * register XID *value = values;
+         * Mask mask = 0;
+         */
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new CirculateNotify event.\n");
+        #endif
+
+        /*
+         * FIXME: Do we need this?
+         *
+         * pWin = nxagentWindowPtr(X.xcirculate.window);
+         *
+         * if (!pWin)
+         * {
+         *   pWin = nxagentRootlessTopLevelWindow(X.xcirculate.window);
+         * }
+         *
+         * if (!pWin)
+         * {
+         *   break;
+         * }
+         *
+         * XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+         *                &root_return, &parent_return, &children_return, &nchildren_return);
+         *
+         * nxagentRootlessRestack(children_return, nchildren_return);
+         */
+
+        break;
+      }
+      case ConfigureNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new ConfigureNotify event.\n");
+        #endif
+
+        if (nxagentConfiguredSynchroWindow == X.xconfigure.window)
+        {
+          if (nxagentExposeQueue.exposures[nxagentExposeQueue.start].serial != X.xconfigure.x)
+          {
+            #ifdef WARNING
+            fprintf(stderr, "nxagentDispatchEvents: Requested ConfigureNotify changes didn't take place.\n");
+            #endif
+          }
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentDispatchEvents: Received ConfigureNotify and going to call "
+                      "nxagentSynchronizeExpose.\n");
+          #endif
+
+          nxagentSynchronizeExpose();
+
+          break;
+        }
+
+        nxagentHandleConfigureNotify(&X);
+
+        break;
+      }
+      case GravityNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new GravityNotify event.\n");
+        #endif
+
+        break;
+      }
+      case ReparentNotify:
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new ReparentNotify event.\n");
+        #endif
+
+        nxagentHandleReparentNotify(&X);
+
+        break;
+      }
+      case UnmapNotify:
+      {
+        WindowPtr pWin;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new UnmapNotify event.\n");
+        #endif
+
+        if (nxagentOption(Rootless) == 1)
+        {
+          if ((pWin = nxagentRootlessTopLevelWindow(X.xunmap.window)) != NULL ||
+                  ((pWin = nxagentWindowPtr(X.xunmap.window)) != NULL &&
+                      nxagentWindowTopLevel(pWin) == 1))
+          {
+            nxagentScreenTrap = 1;
+
+            UnmapWindow(pWin, False);
+
+            nxagentScreenTrap = 0;
+          }
+        }
+
+        if (nxagentUseNXTrans == 1 && nxagentOption(Rootless) == 0 &&
+                nxagentOption(Nested) == 0 && X.xmap.window != nxagentIconWindow)
+        {
+          nxagentVisibility = VisibilityFullyObscured;
+        }
+
+        break;
+      }
+      case MapNotify:
+      {
+        WindowPtr pWin;
+        ClientPtr pClient;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentDispatchEvents: Going to handle new MapNotify event.\n");
+        #endif
+
+        if (nxagentOption(Rootless) == 1)
+        {
+          Bool value = 1;
+
+          if ((pWin = nxagentRootlessTopLevelWindow(X.xmap.window)) != NULL ||
+                  ((pWin = nxagentWindowPtr(X.xmap.window)) != NULL &&
+                      nxagentWindowTopLevel(pWin) == 1))
+          {
+            pClient = wClient(pWin);
+
+            nxagentScreenTrap = 1;
+
+            MapWindow(pWin, pClient);
+
+            nxagentScreenTrap = 0;
+          }
+
+          if (pWin != NULL)
+          {
+            TraverseTree(pWin, nxagentChangeMapPrivate, &value);
+          }
+        }
+
+        if (nxagentOption(Fullscreen) == 1)
+        {
+          if (X.xmap.window == nxagentIconWindow)
+          {
+            pScreen = nxagentScreen(X.xmap.window);
+            nxagentMaximizeToFullScreen(pScreen);
+          }
+
+          nxagentVisibility = VisibilityUnobscured;
+          nxagentVisibilityStop = False;
+          nxagentVisibilityTimeout = GetTimeInMillis() + 2000;
+        }
+
+        break;
+      }
+      case MappingNotify:
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchEvents: WARNING! Going to handle new MappingNotify event.\n");
+        #endif
+
+        break;
+      }
+      default:
+      {
+        /*
+         * Let's check if this is a XKB
+         * state modification event.
+         */
+
+        if (nxagentHandleKeyboardEvent(&X) == 0)
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentDispatchEvents: WARNING! Unhandled event code [%d].\n",
+                      X.type);
+          #endif
+        }
+
+        break;
+      }
+
+    } /* End of switch (X.type) */
+
+  } /* End of while (...) */
+
+  /*
+   * Send the exposed regions to the clients.
+   */
+
+  nxagentForwardRemoteExpose();
+
+  /*
+   * Handle the agent window's changes.
+   */
+  
+  if (closeSession)
+  {
+    if (nxagentOption(Persistent))
+    {
+      if (nxagentNoDialogIsRunning)
+      {
+        nxagentLaunchDialog(DIALOG_SUSPEND_SESSION);
+      }
+    }
+    else
+    {
+      if (nxagentNoDialogIsRunning)
+      {
+        nxagentLaunchDialog(DIALOG_KILL_SESSION);
+      }
+    }
+  }
+
+  if (minimize)
+  {
+    nxagentWMDetect();
+
+    if (nxagentWMIsRunning)
+    {
+      if (nxagentOption(Fullscreen))
+      {
+        nxagentMinimizeFromFullScreen(pScreen);
+      }
+      else
+      {
+        XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0], DefaultScreen(nxagentDisplay));
+      }
+    }
+  }
+
+  if (switchFullscreen)
+  {
+    nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
+  }
+
+  if (startKbd)
+  {
+    if (xkbdRunning)
+    {
+      #ifdef NXAGENT_XKBD_DEBUG
+      fprintf(stderr, "Events: nxkbd now is NOT running: %d, %d\n",
+                  X.xkey.keycode, escapecode);
+      #endif
+
+      xkbdRunning = False;
+
+      kill(pidkbd, 9);
+    }
+    else
+    {
+      char kbddisplay[6];
+      char *kbdargs[6];
+
+      strcpy(kbddisplay,":");
+      strncat(kbddisplay, display, 4);
+
+      kbdargs[0] = "nxkbd";
+      kbdargs[1] = "-geometry";
+      kbdargs[2] = "240x70+0+250";
+      kbdargs[3] = "-display";
+      kbdargs[4] = kbddisplay;
+      kbdargs[5] = NULL;
+
+      switch (pidkbd = fork())
+      {
+        case 0:
+        {
+          execvp(kbdargs[0], kbdargs);
+
+          #ifdef NXAGENT_XKBD_DEBUG
+          fprintf(stderr, "Events: The execvp of nxkbd process failed.\n");
+          #endif
+
+          exit(1);
+
+          break;
+        }
+        case -1:
+        {
+          #ifdef NXAGENT_XKBD_DEBUG
+          fprintf(stderr, "Events: Can't fork to run the nxkbd process.\n");
+          #endif
+
+          break;
+        }
+        default:
+        {
+          break;
+        }
+      }
+
+      #ifdef NXAGENT_XKBD_DEBUG
+      fprintf(stderr, "Events: The nxkbd process now running with [%d][%d].\n",
+                  X.xkey.keycode, escapecode);
+      #endif
+
+      xkbdRunning = True;
+    }
+  }
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[End read]\n");
+  #endif
+
+  /*
+   * Let the underlying X server code
+   * process the input events.
+   */
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[Begin events]\n");
+  #endif
+
+  ProcessInputEvents();
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDispatchEvents: Output pending flag is [%d] critical [%d].\n",
+              NewOutputPending, CriticalOutputPending);
+  #endif
+
+  /*
+   * Write the events to our clients. We may
+   * flush only in the case of critical output
+   * but this doesn't seem beneficial.
+   *
+   * if (CriticalOutputPending == 1)
+   * {
+   *   FlushAllOutput();
+   * }
+   */
+
+  if (NewOutputPending == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentDispatchEvents: Flushed the processed events to clients.\n");
+    #endif
+
+    FlushAllOutput();
+  }
+
+  #ifdef TEST
+
+  if (nxagentPendingEvents(nxagentDisplay) > 0)
+  {
+    fprintf(stderr, "nxagentDispatchEvents: WARNING! More events need to be dispatched.\n");
+  }
+
+  #endif
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[End events]\n");
+  #endif
+}
+
+/*
+ * Functions providing the ad-hoc handling
+ * of the remote X events.
+ */
+
+int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
+{
+  xEvent x;
+
+  if (nxagentXkbState.Initialized == 0)
+  {
+    nxagentInitKeyboardState();
+  }
+
+  if (nxagentCheckSpecialKeystroke(&X -> xkey, result))
+  {
+    return 1;
+  }
+
+  nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
+
+  x.u.u.type = KeyPress;
+  x.u.u.detail = X -> xkey.keycode;
+  x.u.keyButtonPointer.time = nxagentLastKeyPressTime;
+
+  nxagentLastServerTime = X -> xkey.time;
+
+  mieqEnqueue(&x);
+
+  CriticalOutputPending = 1;
+
+  return 1;
+}
+
+int nxagentHandlePropertyNotify(XEvent *X)
+{
+  int resource;
+
+  if (nxagentOption(Rootless) && !nxagentNotifyMatchChangeProperty((XPropertyEvent *) X))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandlePropertyNotify: Property %ld on window %lx.\n",
+                X -> xproperty.atom, X -> xproperty.window);
+    #endif
+
+    if (nxagentWindowPtr(X -> xproperty.window) != NULL)
+    {
+      resource = NXGetCollectPropertyResource(nxagentDisplay);
+
+      if (resource == -1)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentHandlePropertyNotify: WARNING! Asyncronous get property queue is full.\n");
+        #endif
+
+        return 0;
+      }
+
+      NXCollectProperty(nxagentDisplay, resource,
+                            X -> xproperty.window, X -> xproperty.atom, 0,
+                                MAX_RETRIEVED_PROPERTY_SIZE, False, AnyPropertyType);
+
+      nxagentPropertyRequests[resource].window = X -> xproperty.window;
+      nxagentPropertyRequests[resource].property = X -> xproperty.atom;
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentHandlePropertyNotify: Failed to look up remote window property.\n");
+    }
+    #endif
+  }
+
+  return 1;
+}
+
+int nxagentHandleExposeEvent(XEvent *X)
+{
+  WindowPtr pWin = NULL;
+  Window window = None;
+
+  RegionRec sum;
+  RegionRec add;
+  BoxRec box;
+  int index = 0;
+  int overlap = 0;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentHandleExposeEvent: Checking remote expose events.\n");
+  #endif
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentHandleExposeEvent: Looking for window id [%ld].\n",
+              X -> xexpose.window);
+  #endif
+
+  window = X -> xexpose.window;
+
+  pWin = nxagentWindowPtr(window);
+
+  if (pWin != NULL)
+  {
+    REGION_INIT(pWin -> drawable.pScreen, &sum, (BoxRec *) NULL, 1);
+/*
+FIXME: This can be maybe optimized by consuming the
+       events that do not match the predicate.
+*/
+    do
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentHandleExposeEvent: Adding event for window id [%ld].\n",
+                  X -> xexpose.window);
+      #endif
+
+      box.x1 = pWin -> drawable.x + wBorderWidth(pWin) + X -> xexpose.x;
+      box.y1 = pWin -> drawable.y + wBorderWidth(pWin) + X -> xexpose.y;
+
+      box.x2 = box.x1 + X -> xexpose.width;
+      box.y2 = box.y1 + X -> xexpose.height;
+
+      REGION_INIT(pWin -> drawable.pScreen, &add, &box, 1);
+
+      REGION_APPEND(pWin -> drawable.pScreen, &sum, &add);
+
+      REGION_UNINIT(pWin -> drawable.pScreen, &add);
+
+      if (X -> xexpose.count == 0)
+      {
+        break;
+      }
+    }
+    while (nxagentCheckEvents(nxagentDisplay, X, nxagentExposurePredicate,
+                                  (XPointer) &window) == 1);
+
+    REGION_VALIDATE(pWin -> drawable.pScreen, &sum, &overlap);
+
+    REGION_INTERSECT(pWin->drawable.pScreen, &sum, &sum,
+                         &WindowTable[pWin->drawable.pScreen->myNum]->winSize);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentHandleExposeEvent: Sending events for window id [%ld].\n",
+                X -> xexpose.window);
+    #endif
+
+    /*
+     * If the agent has already sent auto-generated expose,
+     * save received exposes for later processing.
+     */
+
+    index = nxagentLookupByWindow(pWin);
+
+    if (index == -1)
+    {
+      miWindowExposures(pWin, &sum, NullRegion);
+    }
+    else
+    {
+      REGION_TRANSLATE(pWin -> drawable.pScreen, &sum, -pWin -> drawable.x, -pWin -> drawable.y);
+
+      if (nxagentExposeQueue.exposures[index].remoteRegion == NullRegion)
+      {
+        nxagentExposeQueue.exposures[index].remoteRegion = REGION_CREATE(pwin -> drawable.pScreen, NULL, 1);
+      }
+
+      REGION_UNION(pWin -> drawable.pScreen, nxagentExposeQueue.exposures[index].remoteRegion,
+                       nxagentExposeQueue.exposures[index].remoteRegion, &sum);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleExposeEvent: Added region for window [%ld] to position [%d].\n",
+                  nxagentWindow(pWin), index);
+      #endif
+
+      if (X -> xexpose.count == 0)
+      {
+        nxagentExposeQueue.exposures[index].remoteRegionIsCompleted = True;
+      }
+      else
+      {
+        nxagentExposeQueue.exposures[index].remoteRegionIsCompleted = False;
+      }
+    }
+
+    if (nxagentRootTileWindow != NULL)
+    {
+      if (nxagentWindowPriv(nxagentRootTileWindow) -> window == nxagentWindowPriv(pWin) -> window &&
+              nxagentSplashCount == 1 && X -> xexpose.count == 0)
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentHandleExposeEvent: Clearing root tile window id [%ld].\n",
+                    nxagentWindowPriv(nxagentRootTileWindow) -> window);
+        #endif
+
+        XClearWindow(nxagentDisplay, nxagentWindowPriv(nxagentRootTileWindow) -> window);
+      }
+    }
+
+    REGION_UNINIT(pWin -> drawable.pScreen, &sum);
+  }
+
+  return 1;
+}
+
+int nxagentHandleGraphicsExposeEvent(XEvent *X)
+{
+  /*
+   * Send an expose event to client, instead of graphics
+   * expose. If target drawable is a backing pixmap, send
+   * expose event for the saved window, else do nothing.
+   */
+
+  RegionPtr exposeRegion;
+  BoxRec rect;
+  WindowPtr pWin;
+  ScreenPtr pScreen;
+  StoringPixmapPtr pStoringPixmapRec = NULL;
+  miBSWindowPtr pBSwindow = NULL;
+  int drawableType;
+
+  pWin = nxagentWindowPtr(X -> xgraphicsexpose.drawable);
+
+  if (pWin != NULL)
+  {
+    drawableType = DRAWABLE_WINDOW;
+  }
+  else
+  {
+    drawableType = DRAWABLE_PIXMAP;
+  }
+
+  if (drawableType == DRAWABLE_PIXMAP)
+  {
+    pStoringPixmapRec = nxagentFindItemBSPixmapList(X -> xgraphicsexpose.drawable);
+
+    if (pStoringPixmapRec == NULL)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleGraphicsExposeEvent: WARNING! Storing pixmap not found.\n");
+      #endif
+
+      return 1;
+    }
+
+    pBSwindow = (miBSWindowPtr) pStoringPixmapRec -> pSavedWindow -> backStorage;
+
+    if (pBSwindow == NULL)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleGraphicsExposeEvent: WARNING! Back storage not found.\n");
+      #endif
+
+      return 1;
+    }
+
+    pWin = pStoringPixmapRec -> pSavedWindow;
+  }
+
+  pScreen = pWin -> drawable.pScreen;
+
+  /*
+   * Rectangle affected by GraphicsExpose
+   * event.
+   */
+
+  rect.x1 = X -> xgraphicsexpose.x;
+  rect.y1 = X -> xgraphicsexpose.y;
+  rect.x2 = rect.x1 + X -> xgraphicsexpose.width;
+  rect.y2 = rect.y1 + X -> xgraphicsexpose.height;
+
+  exposeRegion = REGION_CREATE(pScreen, &rect, 0);
+
+  if (drawableType == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleGraphicsExposeEvent: Handling GraphicsExpose event on pixmap with id"
+                " [%lu].\n", X -> xgraphicsexpose.drawable);
+    #endif
+
+    /*
+     * The exposeRegion coordinates are relative
+     * to the pixmap to which GraphicsExpose
+     * event refers. But the BS coordinates of
+     * the savedRegion  are relative to the
+     * window.
+     */
+
+    REGION_TRANSLATE(pScreen, exposeRegion, pStoringPixmapRec -> backingStoreX,
+                         pStoringPixmapRec -> backingStoreY);
+
+    /*
+     * We remove from SavedRegion the part
+     * affected by the GraphicsExpose event.
+     */
+
+    REGION_SUBTRACT(pScreen, &(pBSwindow -> SavedRegion), &(pBSwindow -> SavedRegion),
+                        exposeRegion);
+  }
+
+  /*
+   * Store the exposeRegion in order to send
+   * the expose event later. The coordinates
+   * must be relative to the screen.
+   */
+
+  REGION_TRANSLATE(pScreen, exposeRegion, pWin -> drawable.x, pWin -> drawable.y);
+
+  REGION_UNION(pScreen, nxagentRemoteExposeRegion, nxagentRemoteExposeRegion, exposeRegion);
+
+  REGION_DESTROY(pScreen, exposeRegion);
+
+  return 1;
+}
+
+int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
+{
+  ScreenPtr pScreen;
+  WindowPtr pWin;
+  xEvent x;
+
+  *result = doNothing;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleClientMessageEvent: ClientMessage event window [%ld] with "
+              "type [%ld] format [%d].\n", X -> xclient.window, X -> xclient.message_type,
+                  X -> xclient.format);
+  #endif
+
+  /*
+   * If window is 0, message_type is 0 and format is
+   * 32 then we assume event is coming from proxy.
+   */
+
+  if (X -> xclient.window == 0 &&
+          X -> xclient.message_type == 0 &&
+              X -> xclient.format == 32)
+  {
+    nxagentHandleProxyEvent(X);
+
+    return 1;
+  }
+
+  if (nxagentOption(Rootless))
+  {
+    Atom message_type = nxagentRemoteToLocalAtom(X -> xclient.message_type);
+
+    if (!ValidAtom(message_type))
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentHandleClientMessageEvent: WARNING Invalid type in client message.\n");
+      #endif
+
+      return 0;
+    }
+
+    pWin = nxagentWindowPtr(X -> xclient.window);
+
+    if (pWin == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "WARNING: Invalid window in ClientMessage.\n");
+      #endif
+
+      return 0;
+    }
+
+    if (message_type == MakeAtom("WM_PROTOCOLS", strlen("WM_PROTOCOLS"), False))
+    {
+      char *message_data;
+
+      x.u.u.type = ClientMessage;
+      x.u.u.detail = X -> xclient.format;
+
+      x.u.clientMessage.window = pWin -> drawable.id;
+      x.u.clientMessage.u.l.type = message_type;
+      x.u.clientMessage.u.l.longs0 = nxagentRemoteToLocalAtom(X -> xclient.data.l[0]);
+      x.u.clientMessage.u.l.longs1 = GetTimeInMillis();
+
+      if (!ValidAtom(x.u.clientMessage.u.l.longs0))
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentHandleClientMessageEvent: WARNING Invalid value in client message "
+                    "of type WM_PROTOCOLS.\n");
+        #endif
+
+        return 0;
+      }
+      else
+      {
+        message_data = validateString(NameForAtom(x.u.clientMessage.u.l.longs0));
+      }
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleClientMessageEvent: Sent client message of type WM_PROTOCOLS "
+                  "and value [%s].\n", message_data);
+      #endif
+
+      TryClientEvents(wClient(pWin), &x, 1, 1, 1, 0);
+    }
+    else
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentHandleClientMessageEvent: Ignored message type %ld [%s].\n",
+                  (long int) message_type, validateString(NameForAtom(message_type)));
+      #endif
+
+      return 0;
+    }
+
+    return 1;
+  }
+
+  if (X -> xclient.message_type == nxagentAtoms[1]) /* WM_PROTOCOLS */
+  {
+    Atom deleteWMatom, wmAtom;
+
+    wmAtom = (Atom) X -> xclient.data.l[0];
+
+    deleteWMatom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
+
+    if (wmAtom == deleteWMatom)
+    {
+      if (nxagentOnce && (nxagentClients == 0))
+      {
+        GiveUp(0);
+      }
+      else
+      {
+        #ifdef TEST
+        fprintf(stderr, "Events: WM_DELETE_WINDOW arrived Atom = %ld.\n", wmAtom);
+        #endif
+
+        if (X -> xclient.window == nxagentIconWindow)
+        {
+          pScreen = nxagentScreen(X -> xmap.window);
+
+          nxagentMaximizeToFullScreen(pScreen);
+        }
+
+        if (X -> xclient.window == (nxagentOption(Fullscreen) ?
+              nxagentIconWindow : nxagentDefaultWindows[0]))
+        {
+          *result = doCloseSession;
+        }
+      }
+    }
+  }
+
+  return 1;
+}
+
+int nxagentHandleKeyboardEvent(XEvent *X)
+{
+  XkbEvent *xkbev = (XkbEvent *) X;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleKeyboardEvent: Handling event with caps [%d] num [%d] locked [%d].\n",
+              nxagentXkbState.Caps, nxagentXkbState.Num, nxagentXkbState.Locked);
+  #endif
+
+  if (xkbev -> type == nxagentXkbInfo.EventBase + XkbEventCode &&
+          xkbev -> any.xkb_type == XkbStateNotify)
+  {
+    nxagentXkbState.Locked = xkbev -> state.locked_mods;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleKeyboardEvent: Updated XKB locked modifier bits to [%x].\n",
+                nxagentXkbState.Locked);
+    #endif
+
+    nxagentXkbState.Initialized = 1;
+
+    if (nxagentXkbState.Caps == 0 &&
+            (nxagentXkbState.Locked & CAPSFLAG_IN_EVENT))
+    {
+      nxagentXkbState.Caps = 1;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [66] to engage capslock.\n");
+      #endif
+
+      nxagentSendFakeKey(66);
+    }
+
+    if (nxagentXkbState.Caps == 1 &&
+          !(nxagentXkbState.Locked & CAPSFLAG_IN_EVENT))
+    {
+      nxagentXkbState.Caps = 0;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [66] to release capslock.\n");
+      #endif
+
+      nxagentSendFakeKey(66);
+    }
+
+    if (nxagentXkbState.Num == 0 &&
+            (nxagentXkbState.Locked & NUMFLAG_IN_EVENT))
+    {
+      nxagentXkbState.Num = 1;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [77] to engage numlock.\n");
+      #endif
+
+      nxagentSendFakeKey(77);
+    }
+
+    if (nxagentXkbState.Num == 1 &&
+            !(nxagentXkbState.Locked & NUMFLAG_IN_EVENT))
+    {
+      nxagentXkbState.Num = 0;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [77] to release numlock.\n");
+      #endif
+
+      nxagentSendFakeKey(77);
+    }
+
+    return 1;
+  }
+
+  return 0;
+}
+
+int nxagentHandleProxyEvent(XEvent *X)
+{
+  switch (X -> xclient.data.l[0])
+  {
+    case NXNoSplitNotify:
+    case NXStartSplitNotify:
+    {
+      /*
+       * We should never receive such events
+       * in the event loop, as they should
+       * be caught at the time the split is
+       * initiated.
+       */
+
+      #ifdef PANIC
+
+      int client = (int) X -> xclient.data.l[1];
+
+      if (X -> xclient.data.l[0] == NXNoSplitNotify)
+      {
+        fprintf(stderr, "nxagentHandleProxyEvent: PANIC! NXNoSplitNotify received "
+                    "with client [%d].\n", client);
+      }
+      else
+      {
+        fprintf(stderr, "nxagentHandleProxyEvent: PANIC! NXStartSplitNotify received "
+                    "with client [%d].\n", client);
+      }
+
+      #endif
+
+      return 1;
+    }
+    case NXCommitSplitNotify:
+    {
+      /*
+       * We need to commit an image. Image can be the
+       * result of a PutSubImage() generated by Xlib,
+       * so there can be more than a single image to
+       * commit, even if only one PutImage was perfor-
+       * med by the agent.
+       */
+
+      int client   = (int) X -> xclient.data.l[1];
+      int request  = (int) X -> xclient.data.l[2];
+      int position = (int) X -> xclient.data.l[3];
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleProxyEvent: NXCommitSplitNotify received with "
+                  "client [%d] request [%d] and position [%d].\n",
+                      client, request, position);
+      #endif
+
+      nxagentHandleCommitSplitEvent(client, request, position);
+
+      return 1;
+    }
+    case NXEndSplitNotify:
+    {
+      /*
+       * All images for the split were transferred and
+       * we need to restart the client.
+       */
+
+      int client = (int) X -> xclient.data.l[1];
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleProxyEvent: NXEndSplitNotify received with "
+                  "client [%d].\n", client);
+      #endif
+
+      nxagentHandleEndSplitEvent(client);
+
+      return 1;
+    }
+    case NXEmptySplitNotify:
+    {
+      /*
+       * All splits have been completed and none remain.
+       */
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleProxyEvent: NXEmptySplitNotify received.\n");
+      #endif
+
+      nxagentHandleEmptySplitEvent();
+
+      return 1;
+    }
+    case NXCollectPropertyNotify:
+    {
+      #ifdef TEST
+      int resource = (int) X -> xclient.data.l[1];
+
+      fprintf(stderr, "nxagentHandleProxyEvent: NXCollectPropertyNotify received with resource [%d].\n",
+                  resource);
+      #endif
+
+      nxagentHandleCollectPropertyEvent(X);
+
+      return 1;
+    }
+    case NXCollectGrabPointerNotify:
+    {
+      int resource = (int) X -> xclient.data.l[1];
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleProxyEvent: NXCollectGrabPointerNotify received with resource [%d].\n",
+                  resource);
+      #endif
+
+      nxagentHandleCollectGrabPointerEvent(resource);
+
+      return 1;
+    }
+    case NXCollectInputFocusNotify:
+    {
+      int resource = (int) X -> xclient.data.l[1];
+
+      /*
+       * This is not used at the present moment.
+       */
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleProxyEvent: NXCollectInputFocusNotify received with resource [%d].\n",
+                  resource);
+      #endif
+
+      nxagentHandleCollectInputFocusEvent(resource);
+
+      return 1;
+    }
+    default:
+    {
+      /*
+       *  Not a recognized ClientMessage event.
+       */
+
+      #ifdef WARNING
+      fprintf(stderr, "nxagentHandleProxyEvent: WARNING! Not a recognized ClientMessage proxy event [%d].\n",
+                  (int) X -> xclient.data.l[0]);
+      #endif
+
+      return 0;
+    }
+  }
+}
+
+/*
+ * In this function it is assumed that we never
+ * get a configure with both stacking order and
+ * geometry changed, this way we can ignore
+ * stacking changes if the geometry has changed.
+ */
+
+int nxagentCheckWindowConfiguration(XConfigureEvent* X)
+{
+  static int x = 0;
+  static int y = 0;
+  static int width = 0;
+  static int height = 0;
+  static Window win = None;
+  Bool geometryChanged = False;
+
+  XlibWindow root_return = 0;
+  XlibWindow parent_return = 0;
+  XlibWindow *children_return = NULL;
+  unsigned int nchildren_return = 0;
+  Status result;
+
+  WindowPtr pWin;
+
+  pWin = nxagentWindowPtr(X -> window);
+
+  /*
+   * This optimization has some problems to
+   * work in rootless mode inside NXWin. To 
+   * verify this you can launch xterm and
+   * another application, f.e. firefox. By
+   * raising xterm above firefox, the stack
+   * order seems to become incoherent showing
+   * the underneath window content in the
+   * overlapping area when the mouse botton is
+   * pressed with the pointer inside of such area.
+   *
+   *  if ((pWin != NULL) && X -> override_redirect == 0)
+   *  {
+   *    return 1;
+   *  }
+   *
+   */
+
+  if (win == X -> window)
+  {
+    if (x != X -> x ||
+            y != X -> y ||
+                width != X -> width ||
+                    height != X -> height)
+    {
+      geometryChanged = True;
+    }
+  }
+
+  win = X -> window;
+
+  x = X -> x;
+  y = X -> y;
+  width = X -> width;
+  height = X -> height;
+
+  if (geometryChanged)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCheckWindowConfiguration: Configure frame. No restack.\n");
+    #endif
+
+    return 1;
+  }
+
+  #ifdef TEST
+  {
+    WindowPtr pSib;
+
+    fprintf(stderr, "nxagentCheckWindowConfiguration: Before restacking top level window [%p]\n",
+                (void *) nxagentWindowPtr(X -> window));
+
+    for (pSib = WindowTable[0] -> firstChild; pSib; pSib = pSib -> nextSib)
+    {
+      fprintf(stderr, "nxagentCheckWindowConfiguration: Top level window: [%p].\n",
+                  (void *) pSib);
+    }
+  }
+  #endif
+
+  result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                          &root_return, &parent_return, &children_return, &nchildren_return);
+
+  if (result)
+  {
+    nxagentRootlessRestack(children_return, nchildren_return);
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCheckWindowConfiguration: WARNING! Failed QueryTree request.\n");
+    #endif
+  }
+
+  if (result && nchildren_return)
+  {
+    XFree(children_return);
+  }
+
+  #if 0
+  fprintf(stderr, "nxagentCheckWindowConfiguration: Trees match: %s\n",
+              nxagentRootlessTreesMatch() ? "Yes" : "No");
+  #endif
+
+  return 1;
+}
+
+int nxagentHandleConfigureNotify(XEvent* X)
+{
+  if (nxagentOption(Rootless) == True)
+  {
+    ClientPtr pClient;
+    WindowPtr pWinWindow;
+    WindowPtr pWin;
+    xEvent x;
+    int sendEventAnyway = 0;
+
+    pWinWindow = nxagentWindowPtr(X -> xconfigure.window);
+
+    #ifdef TEST
+    {
+      WindowPtr pWinEvent  = nxagentWindowPtr(X -> xconfigure.event);
+
+      fprintf(stderr, "nxagentHandleConfigureNotify: Generating window is [%p][%ld] target [%p][%ld].\n",
+                  (void *) pWinEvent, X -> xconfigure.event, (void *) pWinWindow, X -> xconfigure.window);
+    }
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleConfigureNotify: New configuration for window [%p][%ld] is [%d][%d][%d][%d] "
+                "send_event [%i].\n", (void *) pWinWindow, X -> xconfigure.window,
+                    X -> xconfigure.x, X -> xconfigure.y, X -> xconfigure.width,
+                        X -> xconfigure.height, X -> xconfigure.send_event);
+    #endif
+
+    if ((pWin = nxagentRootlessTopLevelWindow(X -> xconfigure.window)) != NULL)
+    {
+      /*
+       * Cheking for new geometry or stacking order changes.
+       */
+
+      nxagentCheckWindowConfiguration((XConfigureEvent*)X);
+
+      return 1;
+    }
+
+    if (nxagentWindowTopLevel(pWinWindow) && !X -> xconfigure.override_redirect)
+    {
+      XID values[5];
+      Mask mask = 0;
+
+      register XID *value = values;
+
+      pClient = wClient(pWinWindow);
+
+      if (X -> xconfigure.send_event || !nxagentWMIsRunning ||
+                X -> xconfigure.override_redirect)
+      {
+        *value++ = (XID)X -> xconfigure.x;
+        *value++ = (XID)X -> xconfigure.y;
+
+        /*
+         * nxagentWindowPriv(pWinWindow)->x = X -> xconfigure.x;
+         * nxagentWindowPriv(pWinWindow)->y = X -> xconfigure.y;
+         */
+
+        mask |= CWX | CWY;
+      }
+
+      *value++ = (XID)X -> xconfigure.width;
+      *value++ = (XID)X -> xconfigure.height;
+      *value++ = (XID)X -> xconfigure.border_width;
+
+      /*
+       * We don't need width and height here.
+       *
+       * nxagentWindowPriv(pWinWindow)->width = X -> xconfigure.width;
+       * nxagentWindowPriv(pWinWindow)->height = X -> xconfigure.height;
+       */
+
+      mask |= CWHeight | CWWidth | CWBorderWidth;
+
+      nxagentScreenTrap = 1;
+
+      ConfigureWindow(pWinWindow, mask, (XID *) values, pClient);
+
+      nxagentScreenTrap = 0;
+
+      nxagentCheckWindowConfiguration((XConfigureEvent*)X);
+
+      /*
+       * This workaround should help with
+       * Java 1.6.0 that seems to ignore
+       * non-synthetic events.
+       */
+
+      if (nxagentOption(ClientOs) == ClientOsWinnt)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleConfigureNotify: Apply workaround for NXWin.\n");
+        #endif
+
+        sendEventAnyway = 1;
+      }
+
+      if (sendEventAnyway || X -> xconfigure.send_event)
+      {
+        x.u.u.type = X -> xconfigure.type;
+        x.u.u.type |= 0x80;
+
+        x.u.configureNotify.event = pWinWindow -> drawable.id;
+        x.u.configureNotify.window = pWinWindow -> drawable.id;
+
+        if (pWinWindow -> nextSib)
+        {
+          x.u.configureNotify.aboveSibling = pWinWindow -> nextSib -> drawable.id;
+        }
+        else
+        {
+          x.u.configureNotify.aboveSibling = None;
+        }
+
+        x.u.configureNotify.x = X -> xconfigure.x;
+        x.u.configureNotify.y = X -> xconfigure.y;
+        x.u.configureNotify.width = X -> xconfigure.width;
+        x.u.configureNotify.height = X -> xconfigure.height;
+        x.u.configureNotify.borderWidth = X -> xconfigure.border_width;
+        x.u.configureNotify.override = X -> xconfigure.override_redirect;
+
+        TryClientEvents(pClient, &x, 1, 1, 1, 0);
+      }
+
+      return 1;
+    }
+  }
+  else
+  {
+    /*
+     * Save the position of the agent default window. Don't
+     * save the values if the agent is in fullscreen mode.
+     *
+     * If we use these values to restore the position of a
+     * window after that we have dynamically changed the
+     * fullscreen attribute, depending on the behaviour of
+     * window manager, we could be not able to place the
+     * window exactly in the requested position, so let the
+     * window manager do the job for us.
+     */
+
+    ScreenPtr pScreen = nxagentScreen(X -> xconfigure.window);
+
+    Bool doRandR = False;
+    struct timeval timeout;
+
+    if (X -> xconfigure.window == nxagentDefaultWindows[pScreen -> myNum])
+    {
+      if (nxagentOption(Fullscreen) == 0)
+      {
+        if (nxagentOption(DesktopResize) == 1)
+        {
+          if (nxagentOption(Width) != X -> xconfigure.width ||
+                nxagentOption(Height) != X -> xconfigure.height)
+          {
+            Bool newEvents = False;
+
+            doRandR = True;
+
+            NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+            do
+            {
+              newEvents = False;
+
+              timeout.tv_sec  = 0;
+              timeout.tv_usec = 500 * 1000;
+
+              nxagentWaitEvents(nxagentDisplay, &timeout);
+
+              /*
+               * This should also flush
+               * the NX link for us.
+               */
+
+              XSync(nxagentDisplay, 0);
+
+              while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+                                              ConfigureNotify, X))
+              {
+                newEvents = True;
+              }
+
+            } while (newEvents);
+          }
+        }
+
+        if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
+        {
+          nxagentChangeOption(X, X -> xconfigure.x);
+          nxagentChangeOption(Y, X -> xconfigure.y);
+        }
+
+        if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
+                (nxagentOption(Width) != X -> xconfigure.width ||
+                    nxagentOption(Height) != X -> xconfigure.height))
+        {
+          nxagentShadowResize = 1;
+        }
+
+        nxagentChangeOption(Width, X -> xconfigure.width);
+        nxagentChangeOption(Height, X -> xconfigure.height);
+
+        nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
+                                (int) nxagentOption(RootWidth));
+        nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
+                                (int) nxagentOption(RootHeight));
+
+        nxagentMoveViewport(pScreen, 0, 0);
+
+        if (nxagentOption(Shadow) == 1 ||
+                (nxagentOption(Width) == nxagentOption(RootWidth) &&
+                    nxagentOption(Height) == nxagentOption(RootHeight)))
+        {
+          doRandR = 0;
+        }
+
+        if (doRandR)
+        {
+          #ifdef TEST
+          fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
+                      nxagentOption(Width), nxagentOption(Height));
+          #endif
+
+          nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
+                                     nxagentOption(Width), nxagentOption(Height));
+        }
+      }
+
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+int nxagentHandleReparentNotify(XEvent* X)
+{
+  ScreenPtr pScreen = nxagentScreen(X -> xreparent.window);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleReparentNotify: Going to handle a new reparent event.\n");
+  #endif
+
+  if (nxagentOption(Rootless))
+  {
+    WindowPtr pWin;
+
+    XlibWindow w;
+    XlibWindow root_return = 0;
+    XlibWindow parent_return = 0;
+    XlibWindow *children_return = NULL;
+    unsigned int nchildren_return = 0;
+    Status result;
+
+    pWin = nxagentWindowPtr(X -> xreparent.window);
+
+    #ifdef TEST
+
+    {
+      WindowPtr pParent = nxagentWindowPtr(X -> xreparent.parent);
+      WindowPtr pEvent = nxagentWindowPtr(X -> xreparent.event);
+
+      fprintf(stderr, "nxagentHandleReparentNotify: event %p[%lx] window %p[%lx] parent %p[%lx] at (%d, %d)\n",
+                  (void*)pEvent, X -> xreparent.event, (void*)pWin, X -> xreparent.window,
+                          (void*)pParent, X -> xreparent.parent, X -> xreparent.x, X -> xreparent.y);
+    }
+
+    #endif
+
+    if (nxagentWindowTopLevel(pWin))
+    {
+      /*
+       * If the window manager reparents our top level
+       * window, we need to know the new top level
+       * ancestor.
+       */
+
+      w = None;
+      parent_return = X -> xreparent.parent;
+
+      while (parent_return != RootWindow(nxagentDisplay, 0))
+      {
+        w = parent_return;
+        result = XQueryTree(nxagentDisplay, w, &root_return,
+                                &parent_return, &children_return, &nchildren_return);
+
+        if (!result)
+        {
+          #ifdef WARNING
+          fprintf(stderr, "nxagentHandleReparentNotify: WARNING! Failed QueryTree request.\n");
+          #endif
+        }
+
+        if (result && children_return)
+        {
+          XFree(children_return);
+        }
+      }
+
+      if (w && !nxagentWindowPtr(w))
+      {
+        XSelectInput(nxagentDisplay, w, StructureNotifyMask);
+
+        nxagentRootlessAddTopLevelWindow(pWin, w);
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleReparentNotify: new top level window [%ld].\n", w);
+        fprintf(stderr, "nxagentHandleReparentNotify: reparented window [%ld].\n",
+                    X -> xreparent.window);
+        #endif
+
+        result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                                &root_return, &parent_return, &children_return, &nchildren_return);
+
+        if (result)
+        {
+          nxagentRootlessRestack(children_return, nchildren_return);
+        }
+        else
+        {
+          #ifdef WARNING
+          fprintf(stderr, "nxagentHandleReparentNotify: WARNING! Failed QueryTree request.\n");
+          #endif
+        }
+
+        if (result && nchildren_return)
+        {
+          XFree(children_return);
+        }
+      }
+      else
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleReparentNotify: Window at [%p] has been reparented to [%ld]"
+                    " top level parent [%ld].\n", (void *) pWin, X -> xreparent.parent, w);
+        #endif
+
+        nxagentRootlessDelTopLevelWindow(pWin);
+      }
+    }
+
+    return 1;
+  }
+  else
+  {
+    /*
+     * This code is supposed to detect if a window manager
+     * is running but in some cases it may be unreliable.
+     * Each window manager behaves differently so the check
+     * can fail for some less common WMs.
+     */
+
+    if (!nxagentWMIsRunning && nxagentOption(Fullscreen) &&
+            X -> xreparent.window == nxagentDefaultWindows[pScreen -> myNum])
+    {
+      #ifdef WARNING
+      fprintf(stderr, "Warning: The agent window was reparented. Is a "
+                  "window manager running?\n");
+      #endif
+
+      /*
+       * If no window manager is running and we are supposed to
+       * be in fullscreen mode then don't wait for the reparent
+       * event. We can assume that there is an undetected window
+       * manager and, as switching to fullscreen could have fail-
+       * ed, we try it again.
+       */
+
+      nxagentSwitchFullscreen(pScreen, True);
+
+      nxagentWMIsRunning = True;
+    }
+    else if (nxagentWMIsRunning && X -> xreparent.window ==
+                 nxagentDefaultWindows[pScreen -> myNum] && X -> xreparent.parent ==
+                     RootWindow(nxagentDisplay, (pScreen -> myNum)))
+    {
+      #ifdef WARNING
+
+      fprintf(stderr, "Warning: The agent window has been reparented to the root.\n");
+
+      fprintf(stderr, "Warning: No window manager seems to be running.\n");
+
+      #endif
+
+      /*
+       * The agent window was unexpectedly reparented
+       * to the root window. We assume that the window
+       * manager was terminated.
+       */
+
+      nxagentWMIsRunning = False;
+    }
+  }
+
+  return 1;
+}
+
+void nxagentEnableKeyboardEvents()
+{
+  int i;
+  Mask mask;
+
+  nxagentGetDefaultEventMask(&mask);
+
+  mask |= NXAGENT_KEYBOARD_EVENT_MASK;
+
+  nxagentSetDefaultEventMask(mask);
+
+  for (i = 0; i < nxagentNumScreens; i++)
+  {
+    XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+  }
+
+  XkbSelectEvents(nxagentDisplay, XkbUseCoreKbd,
+                      NXAGENT_KEYBOARD_EXTENSION_EVENT_MASK,
+                          NXAGENT_KEYBOARD_EXTENSION_EVENT_MASK);
+}
+
+void nxagentDisableKeyboardEvents()
+{
+  int i;
+  Mask mask;
+
+  nxagentGetDefaultEventMask(&mask);
+
+  mask &= ~NXAGENT_KEYBOARD_EVENT_MASK;
+
+  nxagentSetDefaultEventMask(mask);
+
+  for (i = 0; i < nxagentNumScreens; i++)
+  {
+    XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+  }
+
+  XkbSelectEvents(nxagentDisplay, XkbUseCoreKbd, 0x0, 0x0);
+}
+
+void nxagentEnablePointerEvents()
+{
+  int i;
+  Mask mask;
+
+  nxagentGetDefaultEventMask(&mask);
+
+  mask |= NXAGENT_POINTER_EVENT_MASK;
+
+  nxagentSetDefaultEventMask(mask);
+
+  for (i = 0; i < nxagentNumScreens; i++)
+  {
+    XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+  }
+}
+
+void nxagentDisablePointerEvents()
+{
+  int i;
+  Mask mask;
+
+  nxagentGetDefaultEventMask(&mask);
+
+  mask &= ~NXAGENT_POINTER_EVENT_MASK;
+
+  nxagentSetDefaultEventMask(mask);
+
+  for (i = 0; i < nxagentNumScreens; i++)
+  {
+    XSelectInput(nxagentDisplay, nxagentDefaultWindows[i], mask);
+  }
+}
+
+void nxagentSendFakeKey(int key)
+{
+  xEvent fake;
+  Time   now;
+
+  now = GetTimeInMillis();
+
+  fake.u.u.type = KeyPress;
+  fake.u.u.detail = key;
+  fake.u.keyButtonPointer.time = now;
+
+  mieqEnqueue(&fake);
+
+  fake.u.u.type = KeyRelease;
+  fake.u.u.detail = key;
+  fake.u.keyButtonPointer.time = now;
+
+  mieqEnqueue(&fake);
+}
+
+int nxagentInitKeyboardState()
+{
+  XEvent X;
+
+  unsigned int modifiers;
+
+  XkbEvent *xkbev = (XkbEvent *) &X;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitKeyboardState: Initializing XKB state.\n");
+  #endif
+
+  XkbGetIndicatorState(nxagentDisplay, XkbUseCoreKbd, &modifiers);
+
+  xkbev -> state.locked_mods = 0x0;
+
+  if (modifiers & CAPSFLAG_IN_REPLY)
+  {
+    xkbev -> state.locked_mods |= CAPSFLAG_IN_EVENT;
+  }
+
+  if (modifiers & NUMFLAG_IN_REPLY)
+  {
+    xkbev -> state.locked_mods |= NUMFLAG_IN_EVENT;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitKeyboardState: Assuming XKB locked modifier bits [%x].\n",
+              xkbev -> state.locked_mods);
+  #endif
+
+  xkbev -> type         = nxagentXkbInfo.EventBase + XkbEventCode;
+  xkbev -> any.xkb_type = XkbStateNotify;
+
+  nxagentHandleKeyboardEvent(&X);
+
+  return 1;
+}
+
+int nxagentWaitForResource(GetResourceFuncPtr pGetResource, PredicateFuncPtr pPredicate)
+{
+  int resource;
+
+  while ((resource = (*pGetResource)(nxagentDisplay)) == -1)
+  {
+    if (nxagentWaitEvents(nxagentDisplay, NULL) == -1)
+    {
+      return -1;
+    }
+
+    nxagentDispatchEvents(pPredicate);
+  }
+
+  return resource;
+}
+
+void nxagentGrabPointerAndKeyboard(XEvent *X)
+{
+  unsigned long now;
+
+  int resource;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentGrabPointerAndKeyboard: Grabbing pointer and keyboard with event at [%p].\n",
+              (void *) X);
+  #endif
+
+  if (X != NULL)
+  {
+    now = X -> xcrossing.time;
+  }
+  else
+  {
+    now = CurrentTime;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n");
+  #endif
+
+  XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
+                    True, GrabModeAsync, GrabModeAsync, now);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the pointer in context [B2].\n");
+  #endif
+
+  resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+                                        nxagentCollectGrabPointerPredicate);
+
+  NXCollectGrabPointer(nxagentDisplay, resource,
+                           nxagentFullscreenWindow, True, NXAGENT_POINTER_EVENT_MASK,
+                               GrabModeAsync, GrabModeAsync, None, None, now);
+
+  /*
+   * This should not be needed.
+   *
+   * XGrabKey(nxagentDisplay, AnyKey, AnyModifier, nxagentFullscreenWindow,
+   *              True, GrabModeAsync, GrabModeAsync);
+   */
+
+  if (X != NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to force focus in context [B4].\n");
+    #endif
+
+    XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
+                       RevertToParent, now);
+  }
+}
+
+void nxagentUngrabPointerAndKeyboard(XEvent *X)
+{
+  unsigned long now;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Ungrabbing pointer and keyboard with event at [%p].\n",
+              (void *) X);
+  #endif
+
+  if (X != NULL)
+  {
+    now = X -> xcrossing.time;
+  }
+  else
+  {
+    now = CurrentTime;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Going to ungrab the keyboard in context [B5].\n");
+  #endif
+
+  XUngrabKeyboard(nxagentDisplay, now);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to ungrab the pointer in context [B6].\n");
+  #endif
+
+  XUngrabPointer(nxagentDisplay, now);
+}
+
+void nxagentDeactivatePointerGrab()
+{
+  GrabPtr grab = inputInfo.pointer -> grab;
+
+  XButtonEvent X;
+
+  if (grab)
+  {
+    X.type = ButtonRelease;
+    X.serial = 0;
+    X.send_event = FALSE;
+    X.time = currentTime.milliseconds;
+    X.display = nxagentDisplay;
+    X.window = nxagentWindow(grab -> window);
+    X.root = RootWindow(nxagentDisplay, 0);
+    X.subwindow = 0;
+    X.x = X.y = X.x_root = X.y_root = 0;
+    X.state = 0x100;
+    X.button = 1;
+    X.same_screen = TRUE;
+
+    XPutBackEvent(nxagentDisplay, (XEvent*)&X);
+  }
+}
+
+Bool nxagentCollectGrabPointerPredicate(Display *display, XEvent *X, XPointer ptr)
+{
+  return (X -> xclient.window == 0 &&
+             X -> xclient.message_type == 0 &&
+                 X -> xclient.format == 32 &&
+                     X -> xclient.data.l[0] == NXCollectGrabPointerNotify);
+}
+
+void nxagentHandleCollectGrabPointerEvent(int resource)
+{
+  int status;
+
+  if (NXGetCollectedGrabPointer(nxagentDisplay, resource, &status) == 0)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentHandleCollectGrabPointerEvent: PANIC! Failed to get GrabPointer "
+                "reply for resource [%d].\n", resource);
+    #endif
+  }
+}
+
+void nxagentHandleCollectPropertyEvent(XEvent *X)
+{
+  Window window;
+  Atom property;
+  Atom atomReturnType;
+  int resultFormat;
+  unsigned long ulReturnItems;
+  unsigned long ulReturnBytesLeft;
+  unsigned char *pszReturnData = NULL;
+  int result;
+  int resource;
+
+  resource = X -> xclient.data.l[1];
+
+  if (X -> xclient.data.l[2] == False)
+  {
+    #ifdef DEBUG
+    fprintf (stderr, "nxagentHandleCollectPropertyEvent: Failed to get reply data for client [%d].\n",
+                 resource);
+    #endif
+
+    return;
+  }
+
+  if (resource == nxagentLastClipboardClient)
+  {
+    nxagentCollectPropertyEvent(resource);
+  }
+  else
+  {
+    result = NXGetCollectedProperty(nxagentDisplay,
+                                    resource,
+                                    &atomReturnType,
+                                    &resultFormat,
+                                    &ulReturnItems,
+                                    &ulReturnBytesLeft,
+                                    &pszReturnData);
+
+    if (result == True)
+    {
+      window = nxagentPropertyRequests[resource].window;
+      property = nxagentPropertyRequests[resource].property;
+
+      nxagentImportProperty(window, property, atomReturnType, resultFormat,
+                                ulReturnItems, ulReturnBytesLeft, pszReturnData);
+    }
+
+    if (result == 0)
+    {
+      #ifdef DEBUG
+      fprintf (stderr, "nxagentHandleCollectPropertyEvent: Failed to get reply data for client [%d].\n",
+                   resource);
+      #endif
+    }
+
+    if (pszReturnData != NULL)
+    {
+      XFree(pszReturnData);
+    }
+
+    return;
+  }
+}
+
+void nxagentSynchronizeExpose(void)
+{
+  WindowPtr pWin;
+
+  if (nxagentExposeQueue.length <= 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeExpose: PANIC! Called with nxagentExposeQueue.length [%d].\n",
+                nxagentExposeQueue.length);
+    #endif
+
+    return;
+  }
+
+  pWin = nxagentExposeQueueHead.pWindow;
+
+  if (pWin)
+  {
+    if ((nxagentExposeQueueHead.localRegion) != NullRegion)
+    {
+      REGION_TRANSLATE(pWin -> drawable.pScreen, (nxagentExposeQueueHead.localRegion),
+                           pWin -> drawable.x, pWin -> drawable.y);
+    }
+
+    if ((nxagentExposeQueueHead.remoteRegion) != NullRegion)
+    {
+      REGION_TRANSLATE(pWin -> drawable.pScreen, (nxagentExposeQueueHead.remoteRegion),
+                           pWin -> drawable.x, pWin -> drawable.y);
+    }
+
+    if ((nxagentExposeQueueHead.localRegion) != NullRegion &&
+             (nxagentExposeQueueHead.remoteRegion) != NullRegion)
+    {
+      REGION_SUBTRACT(pWin -> drawable.pScreen, (nxagentExposeQueueHead.remoteRegion),
+                          (nxagentExposeQueueHead.remoteRegion),
+                              (nxagentExposeQueueHead.localRegion));
+
+      if (REGION_NIL(nxagentExposeQueueHead.remoteRegion) == 0)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSynchronizeExpose: Going to call miWindowExposures"
+                    " for window [%ld] - rects [%ld].\n", nxagentWindow(pWin),
+                        REGION_NUM_RECTS(nxagentExposeQueueHead.remoteRegion));
+        #endif
+
+        miWindowExposures(pWin, nxagentExposeQueueHead.remoteRegion, NullRegion);
+      }
+    }
+  }
+
+  nxagentExposeQueueHead.pWindow = NULL;
+
+  if (nxagentExposeQueueHead.localRegion != NullRegion)
+  {
+    REGION_DESTROY(nxagentDefaultScreen, nxagentExposeQueueHead.localRegion);
+  }
+
+  nxagentExposeQueueHead.localRegion = NullRegion;
+
+  if (nxagentExposeQueueHead.remoteRegion != NullRegion)
+  {
+    REGION_DESTROY(nxagentDefaultScreen, nxagentExposeQueueHead.remoteRegion);
+  }
+
+  nxagentExposeQueueHead.remoteRegion = NullRegion;
+
+  nxagentExposeQueueHead.remoteRegionIsCompleted = False;
+
+  nxagentExposeQueue.start = (nxagentExposeQueue.start + 1) % EXPOSED_SIZE;
+
+  nxagentExposeQueue.length--;
+
+  return;
+}
+
+int nxagentLookupByWindow(WindowPtr pWin)
+{
+  int i;
+  int j;
+
+  for (j = 0; j < nxagentExposeQueue.length; j++)
+  {
+    i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+    if (nxagentExposeQueue.exposures[i].pWindow == pWin &&
+            !nxagentExposeQueue.exposures[i].remoteRegionIsCompleted)
+    {
+      return i; 
+    }
+  }
+
+  return -1;
+}
+
+void nxagentRemoveDuplicatedKeys(XEvent *X)
+{
+  _XQEvent *prev;
+  _XQEvent *qelt;
+
+  _XQEvent *qeltKeyRelease;
+  _XQEvent *prevKeyRelease;
+
+  KeyCode lastKeycode = X -> xkey.keycode;
+
+  qelt = nxagentDisplay -> head;
+
+  if (qelt == NULL)
+  {
+    #ifdef TEST
+
+    int more;
+
+    fprintf(stderr, "nxagentRemoveDuplicatedKeys: Trying to read more events "
+                "from the X server.\n");
+
+    more = nxagentReadEvents(nxagentDisplay);
+
+    if (more > 0)
+    {
+      fprintf(stderr, "nxagentRemoveDuplicatedKeys: Successfully read more events "
+                  "from the X server.\n");
+    }
+
+    #else
+
+    nxagentReadEvents(nxagentDisplay);
+
+    #endif
+
+    qelt = nxagentDisplay -> head;
+  }
+
+  if (qelt != NULL)
+  {
+    prev = qeltKeyRelease = prevKeyRelease = NULL;
+
+    LockDisplay(nxagentDisplay);
+
+    while (qelt != NULL)
+    {
+      if (qelt -> event.type == KeyRelease ||
+              qelt -> event.type == KeyPress)
+      {
+        if (qelt -> event.xkey.keycode != lastKeycode ||
+               (qelt -> event.type == KeyPress && qeltKeyRelease == NULL) ||
+                   (qelt -> event.type == KeyRelease && qeltKeyRelease != NULL))
+        {
+          break;
+        }
+
+        if (qelt -> event.type == KeyRelease)
+        {
+          prevKeyRelease = prev;
+
+          qeltKeyRelease = qelt;
+        }
+        else if (qelt -> event.type == KeyPress)
+        {
+          _XDeq(nxagentDisplay, prev, qelt);
+
+          qelt = prev -> next;
+
+          if (prev == qeltKeyRelease)
+          {
+            prev = prevKeyRelease;
+          }
+
+          _XDeq(nxagentDisplay, prevKeyRelease, qeltKeyRelease);
+
+          qeltKeyRelease = prevKeyRelease = NULL;
+
+          continue;
+        }
+      }
+
+      prev = qelt;
+
+      qelt = qelt -> next;
+    }
+
+    UnlockDisplay(nxagentDisplay);
+  }
+}
+
+void nxagentInitRemoteExposeRegion(void)
+{
+  if (nxagentRemoteExposeRegion == NULL)
+  {
+    nxagentRemoteExposeRegion = REGION_CREATE(pWin -> drawable.pScreen, NULL, 1);
+
+    if (nxagentRemoteExposeRegion == NULL)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentInitRemoteExposeRegion: PANIC! Failed to create expose region.\n");
+      #endif
+    }
+  }
+}
+
+void nxagentForwardRemoteExpose(void)
+{
+  if (REGION_NOTEMPTY(WindowTable[0] -> drawable.pScreen, nxagentRemoteExposeRegion))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentForwardRemoteExpose: Going to forward events.\n");
+    #endif
+
+    TraverseTree(WindowTable[0], nxagentClipAndSendExpose, (void *)nxagentRemoteExposeRegion);
+
+    /*
+     * Now this region should be empty.
+     */
+
+    REGION_EMPTY(WindowTable[0] -> drawable.pScreen, nxagentRemoteExposeRegion);
+  }
+}
+
+void nxagentAddRectToRemoteExposeRegion(BoxPtr rect)
+{
+  RegionRec exposeRegion;
+
+  if (nxagentRemoteExposeRegion == NULL)
+  {
+    return;
+  }
+
+  REGION_INIT(nxagentDefaultScreen, &exposeRegion, rect, 1);
+
+  REGION_UNION(nxagentDefaultScreen, nxagentRemoteExposeRegion,
+                   nxagentRemoteExposeRegion, &exposeRegion);
+
+  REGION_UNINIT(nxagentDefaultScreen, &exposeRegion);
+}
+
+int nxagentClipAndSendExpose(WindowPtr pWin, pointer ptr)
+{
+  RegionPtr exposeRgn;
+  RegionPtr remoteExposeRgn;
+  BoxRec box;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentClipAndSendExpose: Called.\n");
+  #endif
+
+  remoteExposeRgn = (RegionRec *) ptr;
+
+  if (pWin -> drawable.class != InputOnly)
+  {
+    exposeRgn = REGION_CREATE(pWin -> drawable.pScreen, NULL, 1);
+
+    box = *REGION_EXTENTS(pWin->drawable.pScreen, remoteExposeRgn);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClipAndSendExpose: Root expose extents: [%d] [%d] [%d] [%d].\n",
+                box.x1, box.y1, box.x2, box.y2);
+    #endif
+
+    box = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin -> clipList);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClipAndSendExpose: Clip list extents for window at [%p]: [%d] [%d] [%d] [%d].\n",
+                pWin, box.x1, box.y1, box.x2, box.y2);
+    #endif
+
+    REGION_INTERSECT(pWin -> drawable.pScreen, exposeRgn, remoteExposeRgn, &pWin -> clipList);
+
+    if (REGION_NOTEMPTY(pWin -> drawable.pScreen, exposeRgn))
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentClipAndSendExpose: Forwarding expose to window at [%p] pWin.\n",
+                  pWin);
+      #endif
+
+      /*
+       * The miWindowExposures() clears out the
+       * region parameters, so the subtract ope-
+       * ration must be done before calling it.
+       */
+
+      REGION_SUBTRACT(pWin -> drawable.pScreen, remoteExposeRgn, remoteExposeRgn, exposeRgn);
+
+      miWindowExposures(pWin, exposeRgn, NullRegion);
+    }
+
+    REGION_DESTROY(pWin -> drawable.pScreen, exposeRgn);
+  }
+
+  if (REGION_NOTEMPTY(pWin -> drawable.pScreen, remoteExposeRgn))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClipAndSendExpose: Region not empty. Walk children.\n");
+    #endif
+
+    return WT_WALKCHILDREN;
+  }
+  else
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentClipAndSendExpose: Region empty. Stop walking.\n");
+    #endif
+
+    return WT_STOPWALKING;
+  }
+}
+
+int nxagentUserInput(void *p)
+{
+  int result = 0;
+
+  /*
+   * This function is used as callback in
+   * the polling handler of agent in shadow
+   * mode. When inside the polling loop the
+   * handlers are never called, so we have
+   * to dispatch enqueued events to eventu-
+   * ally change the nxagentInputEvent sta-
+   * tus.
+   */
+
+  if (nxagentOption(Shadow) == 1 &&
+          nxagentPendingEvents(nxagentDisplay) > 0)
+  {
+    nxagentDispatchEvents(NULL);
+  }
+
+  if (nxagentInputEvent == 1)
+  {
+    nxagentInputEvent = 0;
+
+    result = 1;
+  }
+
+  /*
+   * The agent working in shadow mode synch-
+   * ronizes the remote X server even if a
+   * button/key is not released (i.e. when
+   * scrolling a long browser's page), in
+   * order to update the screen smoothly.
+   */
+
+  if (nxagentOption(Shadow) == 1)
+  {
+    return result;
+  }
+
+  if (result == 0)
+  {
+    /*
+     * If there is at least one button/key down,
+     * we are receiving an input. This is not a
+     * condition to break a synchronization loop
+     * if there is enough bandwidth.
+     */
+
+    if (nxagentCongestion > 0 &&
+            (inputInfo.pointer -> button -> buttonsDown > 0 ||
+                nxagentKeyDown > 0))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentUserInput: Buttons [%d] Keys [%d].\n",
+                  inputInfo.pointer -> button -> buttonsDown, nxagentKeyDown);
+      #endif
+
+      result = 1;
+    }
+  }
+
+  return result;
+}
+
+int nxagentHandleRRScreenChangeNotify(XEvent *X)
+{
+  XRRScreenChangeNotifyEvent *Xr;
+
+  Xr = (XRRScreenChangeNotifyEvent *) X;
+
+  nxagentResizeScreen(screenInfo.screens[DefaultScreen(nxagentDisplay)], Xr -> width, Xr -> height,
+                          Xr -> mwidth, Xr -> mheight);
+
+  nxagentShadowCreateMainWindow(screenInfo.screens[DefaultScreen(nxagentDisplay)], WindowTable[0],
+                                Xr -> width, Xr -> height);
+
+  nxagentShadowSetWindowsSize();
+
+  return 1;
+}
+
+/*
+ * Returns true if there is any event waiting to
+ * be dispatched. This function is critical for
+ * the performance because it is called very,
+ * very often. It must also handle the case when
+ * the display is down. The display descriptor,
+ * in fact, may have been reused by some other
+ * client.
+ */
+
+int nxagentPendingEvents(Display *dpy)
+{
+  if (_XGetIOError(dpy) != 0)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentPendingEvents: Returning error with display down.\n");
+    #endif
+
+    return -1;
+  }
+  else if (XQLength(dpy) > 0)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentPendingEvents: Returning true with [%d] events queued.\n",
+                XQLength(dpy));
+    #endif
+
+    return 1;
+  }
+  else
+  {
+    int result;
+    int readable;
+
+    result = NXTransReadable(dpy -> fd, &readable);
+
+    if (result == 0)
+    {
+      if (readable > 0)
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentPendingEvents: Returning true with [%d] bytes readable.\n",
+                    readable);
+        #endif
+
+        return 1;
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentPendingEvents: Returning false with [%d] bytes readable.\n",
+                  readable);
+      #endif
+
+      return 0;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentPendingEvents: WARNING! Error detected on the X display.\n");
+    #endif
+
+    NXForceDisplayError(dpy);
+
+    return -1;
+  }
+}
+
+/*
+ * Blocks until an event becomes
+ * available.
+ */
+
+int nxagentWaitEvents(Display *dpy, struct timeval *tm)
+{
+  XEvent ev;
+
+  NXFlushDisplay(dpy, NXFlushLink);
+
+  /*
+   * If the transport is not running we
+   * have to rely on Xlib to wait for an
+   * event. In this case the timeout is
+   * ignored.
+   */
+
+  if (NXTransRunning(NX_FD_ANY) == 1)
+  {
+    NXTransContinue(tm);
+  }
+  else
+  {
+    XPeekEvent(dpy, &ev);
+  }
+
+  /*
+   * Check if we encountered a display
+   * error. If we did, wait for the
+   * time requested by the caller.
+   */
+
+  if (NXDisplayError(dpy) == 1)
+  {
+    if (tm != NULL)
+    {
+      usleep(tm -> tv_sec * 1000 * 1000 +
+                 tm -> tv_usec);
+    }
+
+    return -1;
+  }
+
+  return 1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
new file mode 100644
index 000000000..4870f83e0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -0,0 +1,223 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Events_H__
+#define __Events_H__
+
+#include <X11/Xmd.h>
+
+#define ProcessedExpose (LASTEvent + 1)
+#define ProcessedNotify (LASTEvent + 2)
+
+#define EXPOSED_SIZE 256
+
+enum HandleEventResult
+{
+  doNothing = 0,
+  doMinimize,
+  doCloseSession,
+  doStartKbd,
+  doSwitchFullscreen,
+  doViewportLeft,
+  doViewportUp,
+  doViewportRight,
+  doViewportDown,
+  doSwitchResizeMode,
+  doSwitchDeferMode
+};
+
+extern CARD32 nxagentLastEventTime;
+
+/*
+ * Manage incoming events.
+ */
+
+typedef Bool (*PredicateFuncPtr)(Display*, XEvent*, XPointer);
+
+extern void nxagentDispatchEvents(PredicateFuncPtr);
+
+typedef int (*GetResourceFuncPtr)(Display*);
+
+int nxagentWaitForResource(GetResourceFuncPtr, PredicateFuncPtr);
+
+Bool nxagentCollectGrabPointerPredicate(Display *display, XEvent *X, XPointer ptr);
+
+int nxagentInputEventPredicate(Display *display, XEvent *event, XPointer parameter);
+
+/*
+ * Enable and disable notification of
+ * remote X server events.
+ */
+
+extern void nxagentEnableKeyboardEvents(void);
+extern void nxagentEnablePointerEvents(void);
+
+extern void nxagentDisableKeyboardEvents(void);
+extern void nxagentDisablePointerEvents(void);
+
+/*
+ * Manage default event mask.
+ */
+
+extern void nxagentInitDefaultEventMask(void);
+extern void nxagentGetDefaultEventMask(Mask *mask_return);
+extern void nxagentSetDefaultEventMask(Mask mask);
+extern void nxagentGetEventMask(WindowPtr pWin, Mask *mask_return);
+
+/*
+ * Bring keyboard device in known state. It needs
+ * a round-trip so it only gets called if a pre-
+ * vious XKB event did not implicitly initialized
+ * the internal state. This is unlikely to happen.
+ */
+
+extern int nxagentInitKeyboardState(void);
+
+/*
+ * Update the keyboard state according
+ * to focus and XKB events received
+ * from the remote X server.
+ */
+
+extern int nxagentHandleKeyboardEvent(XEvent *X);
+
+/*
+ * Handle sync and karma messages and
+ * other notification event coming
+ * from proxy.
+ */
+
+extern int nxagentHandleProxyEvent(XEvent *X);
+
+/*
+ * Other functions providing the ad-hoc
+ * handling of the remote X events.
+ */
+
+extern int nxagentHandleExposeEvent(XEvent *X);
+extern int nxagentHandleGraphicsExposeEvent(XEvent *X);
+extern int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult*);
+extern int nxagentHandlePropertyNotify(XEvent *X);
+extern int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult*);
+extern int nxagentHandleReparentNotify(XEvent *X);
+extern int nxagentHandleConfigureNotify(XEvent *X);
+
+/*
+ * Send a fake keystroke to the remote
+ * X server.
+ */
+
+extern void nxagentSendFakeKey(int key);
+
+/*
+ * Called to manage grab of pointer and
+ * keyboard when running in fullscreen
+ * mode.
+ */
+
+extern void nxagentGrabPointerAndKeyboard(XEvent *X);
+extern void nxagentUngrabPointerAndKeyboard(XEvent *X);
+
+extern void nxagentDeactivatePointerGrab(void);
+
+/*
+ * Handle the selection property received
+ * in the event loop.
+ */
+
+void nxagentCollectPropertyEvent(int resource);
+
+/*
+ * Synchronize expose events between agent and
+ * the real X server.
+ */
+
+typedef struct _ExposuresRec
+{
+  WindowPtr pWindow;
+  RegionPtr localRegion;
+  RegionPtr remoteRegion;
+  Bool remoteRegionIsCompleted;
+  int serial;
+  int synchronize;
+
+} ExposuresRec;
+
+extern RegionPtr nxagentRemoteExposeRegion;
+
+typedef struct _ExposeQueue
+{
+  unsigned int start;
+  int length;
+  ExposuresRec exposures[EXPOSED_SIZE];
+} ExposeQueue;
+
+extern void nxagentSynchronizeExpose(void);
+extern int nxagentLookupByWindow(WindowPtr pWin);
+extern void nxagentUpdateExposeArray(void);
+
+extern ExposeQueue nxagentExposeQueue;
+
+/*
+ * Handle the split related notifications.
+ */
+
+int nxagentWaitSplitEvent(int resource);
+
+void nxagentHandleNoSplitEvent(int resource);
+void nxagentHandleStartSplitEvent(int resource);
+void nxagentHandleCommitSplitEvent(int resource, int request, int position);
+void nxagentHandleEndSplitEvent(int resource);
+void nxagentHandleEmptySplitEvent(void);
+
+void nxagentInitRemoteExposeRegion(void);
+void nxagentAddRectToRemoteExposeRegion(BoxPtr);
+
+extern int nxagentUserInput(void *p);
+
+/*
+* We have to check these before launching the terminate
+ * dialog in rootless mode.
+ */
+
+extern Bool nxagentLastWindowDestroyed;
+extern Time nxagentLastWindowDestroyedTime;
+
+/*
+ * Set this flag if an user input event is received.
+ */
+
+extern int nxagentInputEvent;
+
+/*
+ * Event-handling utilities.
+ */
+
+Bool nxagentPendingEvents(Display *dpy);
+
+#define nxagentQueuedEvents(display) \
+    XQLength((display))
+
+#define nxagentReadEvents(display) \
+    XEventsQueued((display), QueuedAfterReading)
+
+#define nxagentCheckEvents(display, event, predicate, argument) \
+    XCheckIfEventNoFlush((display), (event), (predicate), (argument)) 
+
+int nxagentWaitEvents(Display *, struct timeval *);
+
+#endif /* __Events_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
new file mode 100644
index 000000000..f2954a3e9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -0,0 +1,197 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "micmap.h"
+#include "scrnintstr.h"
+#include "../../randr/randrstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Extensions.h"
+
+void GlxExtensionInit(void);
+void GlxWrapInitVisuals(void *procPtr);
+
+#ifdef __DARWIN__
+
+void DarwinHandleGUI(int argc, char *argv[])
+{
+}
+
+void DarwinGlxExtensionInit()
+{
+  GlxExtensionInit();
+}
+
+void DarwinGlxWrapInitVisuals(void *procPtr)
+{
+  GlxWrapInitVisuals(procPtr);
+}
+
+#endif
+
+void nxagentInitGlxExtension(VisualPtr *visuals, DepthPtr *depths,
+                                 int *numVisuals, int *numDepths, int *rootDepth,
+                                     VisualID *defaultVisual)
+{
+  miInitVisualsProcPtr initVisuals;
+
+  /*
+   * Initialize the visuals to use the GLX extension.
+   */
+
+  initVisuals = NULL;
+
+  GlxWrapInitVisuals(&initVisuals);
+
+  if (initVisuals(visuals, depths, numVisuals, numDepths,
+                      rootDepth, defaultVisual, 0, 0, 0) == 0)
+  {
+    fprintf(stderr, "Warning: Failed to initialize the GLX extension.\n");
+  }
+}
+
+void nxagentInitRandRExtension(ScreenPtr pScreen)
+{
+  rrScrPrivPtr pRandRScrPriv;
+
+  if (RRScreenInit(pScreen) == 0)
+  {
+    fprintf(stderr, "Warning: Failed to initialize the RandR extension.\n");
+  }
+
+  /*
+   * RRScreenInit sets these pointers to NULL,
+   * so requiring the server to set up its own
+   * replacements.
+   */
+
+  pRandRScrPriv = rrGetScrPriv(pScreen);
+
+  pRandRScrPriv -> rrGetInfo   = nxagentRandRGetInfo;
+  pRandRScrPriv -> rrSetConfig = nxagentRandRSetConfig;
+}
+
+int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
+{
+  RRScreenSizePtr pSize;
+
+  int width;
+  int height;
+
+  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 i;
+  int nSizes;
+
+  int mmWidth;
+  int mmHeight;
+
+  /*
+   * Rotation is not supported.
+   */
+
+  *pRotations = RR_Rotate_0;
+
+  /*
+   * Register all the supported sizes. The third
+   * parameter is the refresh rate.
+   */
+
+  maxWidth  = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+  maxHeight = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+
+  nSizes = sizeof w / sizeof(int);
+
+  /*
+   * Add current and max sizes.
+   */
+
+  w[nSizes - 1] = pScreen -> width;
+  h[nSizes - 1] = pScreen -> height;
+
+  w[nSizes - 2] = maxWidth;
+  h[nSizes - 2] = maxHeight;
+
+  /*
+   * Compute default size.
+   */
+
+  w[0] = w[2];
+  h[0] = h[2];
+
+  for (i = 3; i < nSizes - 1; i++)
+  {
+    if ((w[i] <= maxWidth * 3 / 4) && 
+            (h[i] <= maxHeight * 3 / 4) &&
+                (w[i] >= w[0]) &&
+                    (h[i] >= h[0]))
+    {
+      w[0] = w[i];
+      h[0] = h[i];
+    }
+  }
+
+  for (i = 0; i < nSizes; i++)
+  {
+    width = w[i];
+    height = h[i];
+
+    mmWidth  = (width * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+    if (mmWidth < 1)
+    {
+      mmWidth = 1;
+    }
+
+    mmHeight = (height * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+    if (mmHeight < 1)
+    {
+      mmHeight = 1;
+    }
+
+    pSize = RRRegisterSize(pScreen, width, height, mmWidth, mmHeight);
+
+    if (pSize == NULL)
+    {
+      return 0;
+    }
+
+    RRRegisterRate (pScreen, pSize, 60);
+  }
+
+  RRSetCurrentConfig(pScreen, RR_Rotate_0, 60, pSize);
+
+  return 1;
+}
+
+int nxagentRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+                              int rate, RRScreenSizePtr pSize)
+{
+  /*
+   * Whatever size is OK for us.
+   */
+
+  return nxagentResizeScreen(pScreen, pSize -> width, pSize -> height,
+                                 pSize -> mmWidth, pSize -> mmHeight);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
new file mode 100644
index 000000000..f76229867
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
@@ -0,0 +1,35 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * Initialize the additional extensions.
+ */
+
+void nxagentInitGlxExtension(VisualPtr *visuals, DepthPtr *depths,
+                                 int *numVisuals, int *numDepths, int *rootDepth,
+                                     VisualID *defaultVisual);
+
+void nxagentInitRandRExtension(ScreenPtr pScreen);
+
+/*
+ * Basic interface to the RandR extension.
+ */
+
+int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations);
+
+int nxagentRandRSetConfig(ScreenPtr pScreen, Rotation rotation,
+                              int rate, RRScreenSizePtr pSize);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
new file mode 100644
index 000000000..ff968bcc5
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -0,0 +1,1690 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 "scrnintstr.h"
+#include "dixstruct.h"
+#include "../../../../include/fonts/font.h"
+#include "fontstruct.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "opaque.h"
+
+#include "Agent.h"
+
+#include "Display.h"
+#include "Font.h"
+#include "Error.h"
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include "resource.h"
+#include "Reconnect.h"
+
+#include "Args.h"
+
+#include "NXlib.h"
+#include "NXalert.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#define NXAGENT_DEFAULT_FONT_DIR      "/usr/X11R6/lib/X11/fonts"
+#define NXAGENT_ALTERNATE_FONT_DIR    "/usr/share/X11/fonts"
+#define NXAGENT_ALTERNATE_FONT_DIR_2  "/usr/share/fonts/X11"
+#define NXAGENT_ALTERNATE_FONT_DIR_3  "/usr/share/fonts"
+
+#define NXAGENT_DEFAULT_FONT_PATH  \
+"/usr/X11R6/lib/X11/fonts/misc/,/usr/X11R6/lib/X11/fonts/Speedo/,\
+/usr/X11R6/lib/X11/fonts/Type1/,/usr/X11R6/lib/X11/fonts/75dpi/,\
+/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/"
+
+#define NXAGENT_ALTERNATE_FONT_PATH  \
+"/usr/share/X11/fonts/misc/,/usr/share/X11/fonts/Speedo/,\
+/usr/share/X11/fonts/Type1/,/usr/share/X11/fonts/75dpi/,\
+/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/"
+
+#define NXAGENT_ALTERNATE_FONT_PATH_2  \
+"/usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Speedo/,\
+/usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,\
+/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/"
+
+#define NXAGENT_ALTERNATE_FONT_PATH_3  \
+"/usr/share/fonts/misc/,/usr/share/fonts/Speedo/,\
+/usr/share/fonts/Type1/,/usr/share/fonts/75dpi/,\
+/usr/share/fonts/100dpi/,/usr/share/fonts/TTF/"
+
+#undef NXAGENT_FONTCACHE_DEBUG
+#undef NXAGENT_RECONNECT_FONT_DEBUG
+#undef NXAGENT_FONTMATCH_DEBUG
+
+#define FIELDS 14
+
+static int reconnectFlexibility;
+
+static void nxagentCleanCacheAfterReconnect(void);
+static void nxagentFontReconnect(FontPtr, XID, pointer);
+static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontPtr pFont);
+static XFontStruct *nxagentLoadQueryFont(register Display *dpy , char *fontName , FontPtr pFont);
+int nxagentFreeFont(XFontStruct *fs);
+static Bool nxagentGetFontServerPath(char * fontServerPath);
+
+RESTYPE RT_NX_FONT;
+
+#ifdef NXAGENT_RECONNECT_FONT_DEBUG
+static void printFontCacheDump(char*);
+#endif
+
+typedef struct _nxagentFontRec
+{
+  char *name;
+  int  status;
+} nxagentFontRec, *nxagentFontRecPtr;
+
+typedef struct _nxagentFontList
+{
+  nxagentFontRecPtr *list;
+  int length;
+  int listSize;
+} nxagentFontList, *nxagentFontListPtr;
+
+nxagentFontList nxagentRemoteFontList = {NULL, (int)0, (int)0};
+
+int nxagentFontPrivateIndex;
+
+typedef struct _nxCacheFontEntry
+{
+  Atom atom;
+  XFontStruct *font_struct;
+  char *name;
+} nxCacheFontEntryRec, *nxCacheFontEntryRecPtr;
+
+static struct _nxagentFontCache
+{
+  nxCacheFontEntryRecPtr *entry;
+  int index;
+  int size;
+} nxagentFontCache = { NULL, (int) 0, (int) 0 };
+
+#define CACHE_ENTRY_PTR (nxagentFontCache.entry)
+#define CACHE_INDEX (nxagentFontCache.index)
+#define CACHE_SIZE (nxagentFontCache.size)
+#define CACHE_ENTRY(A) (CACHE_ENTRY_PTR[A])
+#define CACHE_FSTRUCT(A) (CACHE_ENTRY(A) -> font_struct)
+#define CACHE_NAME(A) (CACHE_ENTRY(A) -> name)
+#define CACHE_ATOM(A) (CACHE_ENTRY(A) -> atom)
+
+static struct _nxagentFailedToReconnectFonts
+{
+  FontPtr *font;
+  XID *id;
+  int size;
+  int index;
+} nxagentFailedToReconnectFonts = {NULL, NULL, 0, 0};
+
+/*
+ * This is used if nxagentFullGeneration is true
+ * in CloseDisplay().
+ */
+
+void nxagentFreeFontCache(void)
+{
+  int i;
+
+  #ifdef NXAGENT_FONTCACHE_DEBUG
+  fprintf(stderr, "Font: Freeing nxagent font cache\n");
+  #endif
+
+  if (CACHE_INDEX == 0)
+    return;
+
+  #ifdef NXAGENT_FONTCACHE_DEBUG
+  fprintf(stderr, "Font: Freeing nxagent font cache, there are [%d] entries.\n", CACHE_INDEX);
+  #endif
+
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+    #ifdef NXAGENT_FONTCACHE_DEBUG
+    fprintf(stderr, "Font: Freeing nxagent font cache entry [%d] entry pointer is [%p], name [%s]\n",
+                i, CACHE_ENTRY(i), CACHE_NAME(i));
+    #endif
+
+    if (CACHE_FSTRUCT(i))
+    {
+      nxagentFreeFont(CACHE_FSTRUCT(i));
+    }
+
+    xfree(CACHE_NAME(i));
+    xfree(CACHE_ENTRY(i));
+  }
+
+  xfree(CACHE_ENTRY_PTR);
+  CACHE_ENTRY_PTR = NULL;
+  CACHE_INDEX = 0;
+  CACHE_SIZE = 0;
+
+  #ifdef NXAGENT_FONTCACHE_DEBUG
+  fprintf(stderr, "Font: nxagent font cache fully freed\n");
+  #endif
+
+  return;
+}
+
+void nxagentListRemoteFonts(const char *searchPattern, const int maxNames)
+{
+  int i, q, p;
+
+  char **xList;
+  int  xLen = 0;
+
+  const char *patterns[] = {"*", "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"};
+  int patternsQt = 2;
+
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    return;
+  }
+
+  /*
+   * Avoid querying again the remote
+   * fonts.
+   */
+
+  if (nxagentRemoteFontList.length > 0)
+  {
+    return;
+  }
+
+  /*
+   * We can't retrieve the full remote font
+   * list with a single query, because the
+   * number of dashes in the pattern acts as
+   * a rule to select how to search for the
+   * font names, so the pattern '*' is useful
+   * to retrive the font aliases, while the
+   * other one will select the 'real' fonts.
+   */
+
+  for (p = 0; p < patternsQt; p++)
+  {
+    xList = XListFonts(nxagentDisplay, patterns[p], maxNames, &xLen);
+
+    #ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "nxagentListRemoteFonts: NXagent remote list [%s] has %d elements.\n", patterns[p], xLen);
+    #endif
+
+    /*
+     * Add the ListFont request pattern to the list with
+     * the last requested maxnames.
+     */
+
+    nxagentListRemoteAddName(searchPattern, maxNames);
+
+    for (i = 0; i < xLen; i++)
+    {
+      q = 1;
+
+      nxagentListRemoteAddName(xList[i], q);
+    }
+
+    XFreeFontNames(xList);
+  }
+
+  #ifdef NXAGENT_FONTMATCH_DEBUG
+
+  fprintf(stderr, "nxagentListRemoteFonts: Printing remote font list.\n");
+
+  for (i = 0; i < nxagentRemoteFontList.length; i++)
+  {
+    fprintf(stderr, "Font# %d, \"%s\"\n", i, nxagentRemoteFontList.list[i]->name);
+  }
+
+  fprintf(stderr, "nxagentListRemoteFonts: End of list\n");
+
+  #endif
+}
+
+void nxagentListRemoteAddName(const char *name, int status)
+{
+  int pos;
+
+  if (nxagentFontFind(name, &pos))
+  {
+     if (nxagentRemoteFontList.list[pos]->status < status)
+     {
+       nxagentRemoteFontList.list[pos]->status = status;
+
+       #ifdef NXAGENT_FONTMATCH_DEBUG
+       fprintf(stderr, "Font: Font# %d, [%s] change status to %s\n",
+                   pos, nxagentRemoteFontList.list[pos]->name,nxagentRemoteFontList.list[pos]->status?"OK":"deleted");
+       #endif
+     }
+     return;
+  }
+
+  if (nxagentRemoteFontList.length == nxagentRemoteFontList.listSize)
+  {
+     nxagentRemoteFontList.list = xrealloc(nxagentRemoteFontList.list, sizeof(nxagentFontRecPtr)
+                                               * (nxagentRemoteFontList.listSize + 1000));
+
+     if (nxagentRemoteFontList.list == NULL)
+     {
+         FatalError("Font: remote list memory re-allocation failed!.\n");
+     }
+
+     nxagentRemoteFontList.listSize += 1000;
+  }
+
+  if (pos < nxagentRemoteFontList.length)
+  {
+    #ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Font: Going to move list from %p to %p len = %d!.\n",
+                &nxagentRemoteFontList.list[pos], &nxagentRemoteFontList.list[pos+1],
+                    (nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr));
+    #endif
+
+    memmove(&nxagentRemoteFontList.list[pos+1],
+                &nxagentRemoteFontList.list[pos],
+                    (nxagentRemoteFontList.length - pos) * sizeof(nxagentFontRecPtr));
+  }
+
+  if ((nxagentRemoteFontList.list[pos] = xalloc(sizeof(nxagentFontRec))))
+  {
+    nxagentRemoteFontList.list[pos]->name = xalloc(strlen(name) +1);
+    if (nxagentRemoteFontList.list[pos]->name == NULL)
+    {
+       fprintf(stderr, "Font: remote list name memory allocation failed!.\n");
+       return;
+    }
+  }
+  else
+  {
+     fprintf(stderr, "Font: remote list record memory allocation failed!.\n");
+     return;
+  }
+  strcpy(nxagentRemoteFontList.list[pos]->name,name);
+  nxagentRemoteFontList.list[pos]->status = status;
+  nxagentRemoteFontList.length++;
+
+  #ifdef NXAGENT_FONTMATCH_DEBUG
+  fprintf(stderr, "Font: remote font list added [%s] in position [%d] as %s !.\n",
+              name, pos, status ? "OK" : "deleted");
+  fprintf(stderr, "Font: remote font list total len is [%d] Size is [%d] !.\n",
+              nxagentRemoteFontList.length, nxagentRemoteFontList.listSize);
+  #endif
+}
+
+static void nxagentFreeRemoteFontList(nxagentFontList *listRec)
+{
+  int l;
+
+  for (l = 0; l < listRec -> length; l++)
+  {
+    if (listRec -> list[l])
+    {
+      xfree(listRec -> list[l] -> name);
+      listRec -> list[l] -> name = NULL;
+
+      xfree(listRec -> list[l]);
+      listRec -> list[l] = NULL;
+    }
+  }
+
+  listRec -> length = listRec -> listSize = 0;
+
+  free(listRec -> list);
+  listRec -> list = NULL;
+
+  return;
+}
+
+Bool nxagentFontFind(const char *name, int *pos)
+{
+ int low,high,res,iter,lpos;
+
+ if (!nxagentRemoteFontList.length)
+ {
+    *pos=0;
+    return False;
+ }
+ low = 0;
+ high = nxagentRemoteFontList.length - 1;
+ iter = 0;
+ res = 1;
+ lpos = nxagentRemoteFontList.length;
+ while (low <= high)
+ {
+   *pos = (high + low)/2;
+   iter ++;
+   res = strcasecmp(nxagentRemoteFontList.list[*pos]->name,name);
+   if (res > 0)
+   {
+      high = *pos - 1;
+      lpos = *pos;
+      continue;
+   }
+   else if (res < 0)
+   {
+      low = *pos + 1;
+      lpos = low;
+      continue;
+   }
+   break;
+ }
+ *pos = (res == 0)?*pos:lpos;
+
+ #ifdef NXAGENT_FONTMATCH_DEBUG
+ if (res == 0)
+   fprintf(stderr, "Font: font found in %d iterations in pos = %d\n", iter, *pos);
+ else
+   fprintf(stderr, "Font: not font found in %d iterations insertion pos is = %d\n", iter, *pos);
+ #endif
+
+ return (res == 0);
+
+}
+
+Bool nxagentFontLookUp(const char *name)
+{
+  int i;
+  if (name)
+    if (!strlen(name))
+       return 0;
+  if (nxagentFontFind(name, &i))
+    return (nxagentRemoteFontList.list[i]->status > 0);
+  else
+    return 0;
+}
+
+Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+  pointer priv;
+  Atom name_atom, value_atom;
+  int nprops;
+  FontPropPtr props;
+  int i;
+  char *name;
+  char *origName = (char*) pScreen;
+
+  FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL);
+
+  if (requestingClient && XpClientIsPrintClient(requestingClient, NULL))
+    return True;
+
+  name_atom = MakeAtom("FONT", 4, True);
+  value_atom = 0L;
+
+  nprops = pFont->info.nprops;
+  props = pFont->info.props;
+
+  for (i = 0; i < nprops; i++)
+    if ((Atom)props[i].name == name_atom) {
+      value_atom = props[i].value;
+      break;
+    }
+
+  if (!value_atom) return False;
+
+  name = (char *)NameForAtom(value_atom);
+
+  #ifdef NXAGENT_FONTCACHE_DEBUG
+  fprintf(stderr, "Font: nxagentRealizeFont, realizing font: %s\n", validateString(name));
+  fprintf(stderr, "                                 atom: %ld\n", value_atom);
+  fprintf(stderr, "Font: Cache dump:\n");
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+      fprintf(stderr, "nxagentFontCache.entry[%d]->name: %s font_struct at %p\n",
+                  i, CACHE_NAME(i), CACHE_FSTRUCT(i));
+  }
+  #endif
+
+  if (!name) return False;
+
+  if ((strcasecmp(origName, name) != 0) && !strchr(origName,'*'))
+  {
+     #ifdef NXAGENT_FONTMATCH_DEBUG
+     fprintf(stderr, "Font: Changing font name to realize from [%s] to [%s]\n",
+                 validateString(name), origName);
+     #endif
+
+     name = origName;
+  }
+
+  priv = (pointer)xalloc(sizeof(nxagentPrivFont));
+  FontSetPrivate(pFont, nxagentFontPrivateIndex, priv);
+
+  nxagentFontPriv(pFont) -> mirrorID = 0;
+
+  for (i = 0; i < nxagentFontCache.index; i++)
+  {
+/*      if (value_atom == CACHE_ATOM(i))*/
+     if (strcasecmp(CACHE_NAME(i), name) == 0)
+     {
+        #ifdef NXAGENT_FONTCACHE_DEBUG
+        fprintf(stderr, "Font: nxagentFontCache hit [%s] = [%s]!\n", CACHE_NAME(i), validateString(name));
+        #endif
+
+        break;
+     }
+  }
+
+  if (i < CACHE_INDEX)
+  {
+      nxagentFontPriv(pFont)->font_struct = CACHE_FSTRUCT(i);
+      strcpy(nxagentFontPriv(pFont)->fontName, name);
+  }
+  else
+  {
+      #ifdef NXAGENT_FONTCACHE_DEBUG
+      fprintf(stderr, "Font: nxagentFontCache fail.\n");
+      #endif
+
+      if (CACHE_INDEX == CACHE_SIZE)
+      {
+        CACHE_ENTRY_PTR = xrealloc(CACHE_ENTRY_PTR, sizeof(nxCacheFontEntryRecPtr) * (CACHE_SIZE + 100));
+
+        if (CACHE_ENTRY_PTR == NULL)
+        {
+           FatalError("Font: Cache list memory re-allocation failed.\n");
+        }
+
+        CACHE_SIZE += 100;
+     }
+
+     CACHE_ENTRY(CACHE_INDEX) = xalloc(sizeof(nxCacheFontEntryRec));
+
+     if (CACHE_ENTRY(CACHE_INDEX) == NULL)
+     {
+        return False;
+     }
+
+     CACHE_NAME(CACHE_INDEX) = xalloc(strlen(name) + 1);
+
+     if (CACHE_NAME(CACHE_INDEX) == NULL)
+     {
+        return False;
+     }
+
+     #ifdef NXAGENT_FONTMATCH_DEBUG
+     fprintf(stderr, "Font: Going to realize font [%s],[%s] on real X server.\n", validateString(name), origName);
+     #endif
+
+     if (nxagentRemoteFontList.length == 0 && (NXDisplayError(nxagentDisplay) == 0))
+     {
+       nxagentListRemoteFonts("*", nxagentMaxFontNames);
+     }
+
+     nxagentFontPriv(pFont)->font_struct = nxagentLoadQueryFont(nxagentDisplay, name, pFont);
+     strcpy(nxagentFontPriv(pFont)->fontName, name);
+     if (nxagentFontPriv(pFont)->font_struct != NULL)
+     {
+       CACHE_ATOM(i) = value_atom;
+       strcpy(CACHE_NAME(i), name);
+       CACHE_FSTRUCT(i) = nxagentFontPriv(pFont)->font_struct;
+       CACHE_INDEX++;
+
+       nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+       AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+       #ifdef NXAGENT_FONTCACHE_DEBUG
+       fprintf(stderr, "Font: nxagentFontCache adds font [%s] in pos. [%d].\n",
+                   validateString(name), CACHE_INDEX - 1);
+       #endif
+     }
+  }
+
+  #ifdef NXAGENT_FONTMATCH_DEBUG
+
+  if (nxagentFontPriv(pFont)->font_struct == NULL)
+  {
+    if (nxagentFontLookUp(name) == False)
+    {
+      fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s, not in our remote list\n",
+                  validateString(name));
+    }
+    else
+    {
+      fprintf(stderr, "Font: nxagentRealizeFont failed with font Font=%s but the font is in our remote list\n",
+                  validateString(name));
+    }
+  }
+  else
+      fprintf(stderr, "Font: nxagentRealizeFont OK realizing font Font=%s\n",
+                  validateString(name));
+
+  #endif
+
+  return (nxagentFontPriv(pFont)->font_struct != NULL);
+}
+
+Bool nxagentUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+  if (nxagentFontPriv(pFont))
+  {
+    if (NXDisplayError(nxagentDisplay) == 0)
+    {
+      if (nxagentFontStruct(pFont))
+      {
+         int i;
+
+         for (i = 0; i < CACHE_INDEX; i++)
+         {
+           if (CACHE_FSTRUCT(i) == nxagentFontStruct(pFont))
+           {
+             #ifdef NXAGENT_FONTCACHE_DEBUG
+             fprintf(stderr, "nxagentUnrealizeFont: Not freeing the font in cache.\n");
+             #endif
+
+             break;
+           }
+         }
+
+         if (i == CACHE_INDEX)
+         {
+           /*
+            * This font is not in the cache.
+            */
+
+           #ifdef NXAGENT_FONTCACHE_DEBUG
+           fprintf(stderr, "nxagentUnrealizeFont: Freeing font not found in cache '%d'\n",
+                       CACHE_ATOM(i));
+           #endif
+
+           XFreeFont(nxagentDisplay, nxagentFontStruct(pFont));
+         }
+       }
+    }
+
+    if (nxagentFontPriv(pFont) -> mirrorID)
+      FreeResource(nxagentFontPriv(pFont) -> mirrorID, RT_NONE);
+
+    xfree(nxagentFontPriv(pFont));
+    FontSetPrivate(pFont, nxagentFontPrivateIndex, NULL);
+  }
+
+  return True;
+}
+
+int nxagentDestroyNewFontResourceType(pointer p, XID id)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyNewFontResourceType: Destroying mirror id [%ld] for font at [%p].\n",
+              nxagentFontPriv((FontPtr) p) -> mirrorID, (void *) p);
+  #endif
+
+/*
+FIXME: It happens that this resource had been already
+       destroied. We should verify if the same font is
+       assigned both to the server client and another
+       client. We had a crash when freeing server client
+       resources.
+*/
+  if (nxagentFontPriv((FontPtr) p) != NULL)
+  {
+    nxagentFontPriv((FontPtr) p) -> mirrorID = None;
+  }
+
+  return 1;
+}
+
+static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontPtr pFont)
+{
+  XFontStruct *fontStruct;
+
+  char *substFontBuf;
+
+  /*  X Logical Font Description Conventions
+   *  require 14 fields in the font names.
+   *
+   */
+  char *searchFields[FIELDS+1];
+  char *fontNameFields[FIELDS+1];
+  int i;
+  int j;
+  int numSearchFields = 0;
+  int numFontFields = 0;
+  int weight = 0;
+  int tempWeight = 1;
+  int fieldOrder[14] = {  4,  /* Slant       */
+                         11,  /* Spacing     */
+                         12,  /* Width info  */
+                         13,  /* Charset     */
+                         14,  /* Language    */
+                          7,  /* Height      */
+                          6,  /* Add-style   */
+                          3,  /* Weight      */
+                          2,  /* Name        */
+                          1,  /* Foundry     */
+                          9,  /* DPI_x       */
+                          5,  /* Set-width   */
+                          8,  /* Point size  */
+                         10   /* DPI_y       */
+                       }; 
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentLoadBestQueryFont: Searching font '%s' .\n", fontName);
+  #endif
+
+  substFontBuf = (char *) xalloc(sizeof(char) * 512);
+
+
+  numFontFields = nxagentSplitString(fontName, fontNameFields, FIELDS, "-");
+
+  memcpy(substFontBuf, "fixed\0", strlen("fixed") + 1);
+
+  if (numFontFields <= FIELDS)
+  {
+    #ifdef WARNING
+    if (nxagentVerbose == 1)
+    {
+      fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Font name in non standard format. \n");
+    }
+    #endif
+  }
+  else
+  {
+    for (i = 1 ; i < nxagentRemoteFontList.length ; i++)
+    {
+      numSearchFields = nxagentSplitString(nxagentRemoteFontList.list[i]->name, searchFields, FIELDS+1, "-");
+
+
+      /* The following code attemps to find an accurate approximation
+       * of the missing font. The current candidate and the missing font are
+       * compared on the 14 fields of the X Logical Font Description Convention.
+       * The selection is performed by the analysis of the matching fields,
+       * shifting left the value of the Weight variable on the right matches
+       * and shifting right the value of the Weight on the wrong ones;
+       * due a probability of overmuch right shifting, the starting weight is set
+       * to a high value. At the end of matching the selected font is the one
+       * with the bigger final Weight. The shift operation has been used instead
+       * of other operation for a performance issue.
+       * In some check the shift is performed by more than one position, because
+       * of the relevance of the field; for example a correct slant or a matching
+       * charset is more relevant than the size.
+       */
+
+      if (numSearchFields > FIELDS)
+      {
+
+        tempWeight = 0;
+
+        for (j = 0; j < FIELDS; j++)
+        {
+          if (strcasecmp(searchFields[fieldOrder[j]], fontNameFields[fieldOrder[j]]) == 0 ||
+                  strcmp(searchFields[fieldOrder[j]], "") == 0 ||
+                      strcmp(fontNameFields[fieldOrder[j]], "") != 0 ||
+                          strcmp(searchFields[fieldOrder[j]], "*") == 0 ||
+                              strcmp(fontNameFields[fieldOrder[j]], "*") == 0)
+          {
+            tempWeight ++;
+          }
+
+          tempWeight <<= 1;
+        }
+
+      }
+
+      if (tempWeight > weight)
+      {
+        /* Found more accurate font  */
+
+        weight = tempWeight;
+        memcpy(substFontBuf, nxagentRemoteFontList.list[i]->name, strlen(nxagentRemoteFontList.list[i]->name));
+        substFontBuf[strlen(nxagentRemoteFontList.list[i]->name)] = '\0';
+
+        #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+        fprintf(stderr, "nxagentLoadBestQueryFont: Weight '%d' of more accurate font '%s' .\n", weight, substFontBuf);
+        #endif
+      }
+    }
+  }
+
+  #ifdef WARNING
+  if (nxagentVerbose == 1)
+  {
+    fprintf(stderr, "nxagentLoadBestQueryFont: WARNING! Failed to load font '%s'. Replacing with '%s'.\n",
+                fontName, substFontBuf);
+  }
+  #endif
+
+  fontStruct = nxagentLoadQueryFont(dpy, substFontBuf, pFont);
+
+  free (substFontBuf);
+
+  return fontStruct;
+}
+
+static void nxagentFontDisconnect(FontPtr pFont, XID param1, pointer param2)
+{
+  nxagentPrivFont *privFont;
+  Bool *pBool = (Bool*)param2;
+  int i;
+
+  if (pFont == NULL || !*pBool)
+    return;
+
+  privFont = nxagentFontPriv(pFont);
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentFontDisconnect: pFont %p, XID %lx\n",
+              (void *) pFont, privFont -> font_struct ? nxagentFont(pFont) : 0);
+  #endif
+
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+    if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
+    {
+      #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+      fprintf(stderr, "nxagentFontDisconnect: font %s found in cache at position %d\n",
+              privFont -> fontName, i);
+      #endif
+
+      privFont -> font_struct = NULL;
+      return;
+    }
+  }
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentFontDisconnect: WARNING font %s not found in cache freeing it now\n",
+              privFont -> fontName);
+  #endif
+
+  if (privFont -> font_struct)
+  {
+     XFreeFont(nxagentDisplay, privFont -> font_struct);
+     privFont -> font_struct = NULL;
+  }
+}
+
+static void nxagentCollectFailedFont(FontPtr fpt, XID id)
+{
+
+  if (nxagentFailedToReconnectFonts.font == NULL)
+  {
+    nxagentFailedToReconnectFonts.size = 8;
+
+    nxagentFailedToReconnectFonts.font = malloc(nxagentFailedToReconnectFonts.size *
+                                                    sizeof(FontPtr));
+
+    nxagentFailedToReconnectFonts.id = malloc(nxagentFailedToReconnectFonts.size * sizeof(XID));
+
+    if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL)
+    {
+      FatalError("Font: font not reconnected memory allocation failed!.\n");
+    }
+
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "nxagentCollectFailedFont: allocated [%d] bytes.\n",
+                8 * (sizeof(FontPtr)+ sizeof(XID)));
+    #endif
+  }
+  else if (nxagentFailedToReconnectFonts.index == nxagentFailedToReconnectFonts.size - 1)
+  {
+    nxagentFailedToReconnectFonts.size *= 2;
+
+    nxagentFailedToReconnectFonts.font = realloc(nxagentFailedToReconnectFonts.font,
+                                                     nxagentFailedToReconnectFonts.size *
+                                                         sizeof(FontPtr));
+
+    nxagentFailedToReconnectFonts.id = realloc(nxagentFailedToReconnectFonts.id,
+                                                   nxagentFailedToReconnectFonts.size *
+                                                         sizeof(XID));
+
+    if (nxagentFailedToReconnectFonts.font == NULL || nxagentFailedToReconnectFonts.id == NULL)
+    {
+      FatalError("Font: font not reconnected memory re-allocation failed!.\n");
+    }
+
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr,"nxagentCollectFailedFont: reallocated memory.\n ");
+    #endif
+  }
+
+  nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index] = fpt;
+
+  nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index] = id;
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentCollectFailedFont: font not reconnected at [%p], "
+              "put in nxagentFailedToReconnectFonts.font[%d] = [%p], with XID = [%lu].\n",
+              (void*) fpt, nxagentFailedToReconnectFonts.index,
+              (void *)nxagentFailedToReconnectFonts.font[nxagentFailedToReconnectFonts.index],
+              nxagentFailedToReconnectFonts.id[nxagentFailedToReconnectFonts.index]);
+  #endif
+
+  nxagentFailedToReconnectFonts.index++;
+}
+
+static void nxagentFontReconnect(FontPtr pFont, XID param1, pointer param2)
+{
+  int i;
+  nxagentPrivFont *privFont;
+  Bool *pBool = (Bool*)param2;
+
+  if (pFont == NULL)
+    return;
+
+  privFont = nxagentFontPriv(pFont);
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentFontReconnect: pFont %p - XID %lx - name %s\n",
+              (void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0,
+                  privFont -> fontName);
+  #endif
+
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+    if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
+    {
+      #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+      fprintf(stderr, "\tfound in cache");
+      #endif
+
+      if (!CACHE_FSTRUCT(i))
+      {
+        #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+        fprintf(stderr, " --- font struct not valid\n");
+        #endif
+
+        break;
+      }
+
+      nxagentFontStruct(pFont) = CACHE_FSTRUCT(i);
+
+      return;
+    }
+  }
+
+  if (i == CACHE_INDEX)
+  {
+    FatalError("nxagentFontReconnect: font not found in cache.");
+  }
+
+  privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+
+  if ((privFont -> font_struct == NULL) && reconnectFlexibility)
+  {
+    privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+  }
+
+  if (privFont->font_struct != NULL)
+  {
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid);
+    #endif
+
+    CACHE_FSTRUCT(i) = privFont -> font_struct;
+  }
+  else
+  {
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "nxagentFontReconnect: failed\n");
+    #endif
+
+    nxagentCollectFailedFont(pFont, param1);
+
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "nxagentFontReconnect: reconnection of font [%s] failed.\n",
+                privFont -> fontName);
+    #endif
+
+    nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT,
+                                 "Couldn't restore the font '%s'", privFont -> fontName);
+
+    *pBool = False;
+  }
+
+  return;
+}
+
+static void nxagentFreeCacheBeforeReconnect(void)
+{
+  int i;
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  printFontCacheDump("nxagentFreeCacheBeforeReconnect");
+  #endif
+
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+    if (CACHE_FSTRUCT(i))
+    {
+      nxagentFreeFont(CACHE_FSTRUCT(i));
+      CACHE_FSTRUCT(i) = NULL;
+    }
+  }
+}
+
+static void nxagentCleanCacheAfterReconnect(void)
+{
+  int i, j;
+  int real_size = CACHE_INDEX;
+  nxCacheFontEntryRecPtr swapEntryPtr;
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  printFontCacheDump("nxagentCleanCacheAfterReconnect");
+  #endif
+
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+    if(CACHE_FSTRUCT(i) == NULL)
+    {
+      XFree(CACHE_NAME(i));
+      real_size--;
+    }
+  }
+
+  for (i = 0; i < real_size; i++)
+  {
+      /* Find - first bad occurrence if exist. */
+      while ((i < real_size) && CACHE_FSTRUCT(i)) i++;
+
+      /* Really nothing more to do. */
+      if (i == real_size)
+        break;
+
+      /*
+       * Find - first good occurrence (moving backward from right end) entry in
+       *        order to replace the bad one.
+       */
+      for (j = CACHE_INDEX - 1; CACHE_FSTRUCT(j) == NULL; j--);
+
+      /*
+       * Now we can swap the two entry
+       * and reduce the Cache index
+       */
+      swapEntryPtr = CACHE_ENTRY(i);
+      CACHE_ENTRY(i) = CACHE_ENTRY(j);
+      CACHE_ENTRY(j) = swapEntryPtr;
+  }
+
+  CACHE_INDEX = real_size;
+}
+
+#ifdef NXAGENT_RECONNECT_FONT_DEBUG
+static void printFontCacheDump(char* msg)
+{
+  int i;
+
+  fprintf(stderr, "%s - begin -\n", msg);
+
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+    if (CACHE_FSTRUCT(i))
+    {
+      fprintf(stderr, "\tXID %lx - %s\n", CACHE_FSTRUCT(i) -> fid, CACHE_NAME(i));
+    }
+    else
+    {
+      fprintf(stderr, "\tdestroyed   - %s\n", CACHE_NAME(i));
+    }
+  }
+  fprintf(stderr, "%s - end   -\n", msg);
+}
+#endif
+
+Bool nxagentReconnectAllFonts(void *p0)
+{
+  int cid;
+  Bool fontSuccess = True;
+
+  reconnectFlexibility = *((int *) p0);
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG)
+  fprintf(stderr, "nxagentReconnectAllFonts\n");
+  #endif
+
+  /*
+   * The resource type RT_NX_FONT is created on the
+   * server client only, so we can avoid to loop
+   * through all the clients.
+   */
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT,
+                                (FindResType) nxagentFontReconnect, &fontSuccess);
+
+  for (cid = 0; cid < MAXCLIENTS; cid++)
+  {
+    if (clients[cid])
+    {
+      FindClientResourcesByType(clients[cid], RT_FONT,
+                                    (FindResType) nxagentFontReconnect, &fontSuccess);
+    }
+  }
+
+  if (fontSuccess)
+  {
+    nxagentCleanCacheAfterReconnect();
+  }
+
+  return fontSuccess;
+}
+
+static void nxagentFailedFontReconnect(FontPtr pFont, XID param1, pointer param2)
+{
+  int i;
+  nxagentPrivFont *privFont;
+  Bool *pBool = (Bool*)param2;
+
+  if (pFont == NULL)
+    return;
+
+  privFont = nxagentFontPriv(pFont);
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentFailedFontReconnect: pFont %p - XID %lx - name %s\n",
+              (void*) pFont, (privFont -> font_struct) ? nxagentFont(pFont) : 0,
+                  privFont -> fontName);
+  #endif
+
+  for (i = 0; i < CACHE_INDEX; i++)
+  {
+    if (strcasecmp(CACHE_NAME(i), privFont -> fontName) == 0)
+    {
+      #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+      fprintf(stderr, "\tfound in cache");
+      #endif
+
+      if (!CACHE_FSTRUCT(i))
+      {
+        #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+        fprintf(stderr, " --- font struct not valid\n");
+        #endif
+
+        break;
+      }
+
+      nxagentFontStruct(pFont) = CACHE_FSTRUCT(i);
+
+      return;
+    }
+  }
+
+  if (i == CACHE_INDEX)
+  {
+    FatalError("nxagentFailedFontReconnect: font not found in cache.");
+  }
+
+  privFont -> font_struct = nxagentLoadQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+
+  if (privFont -> font_struct == NULL)
+  {
+    privFont -> font_struct = nxagentLoadBestQueryFont(nxagentDisplay, privFont -> fontName, pFont);
+  }
+
+  if (privFont->font_struct != NULL)
+  {
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "\tXID %lx\n", privFont -> font_struct -> fid);
+    #endif
+
+    CACHE_FSTRUCT(i) = privFont -> font_struct;
+  }
+  else
+  {
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "nxagentFailedFontReconnect: failed\n");
+    #endif
+
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "nxagentFailedFontReconnect: reconnection of font [%s] failed.\n",
+                privFont -> fontName);
+    #endif
+
+    nxagentSetReconnectError(FAILED_RESUME_FONTS_ALERT,
+                                 "Couldn't restore the font '%s'", privFont -> fontName);
+
+    *pBool = False;
+  }
+
+  return;
+}
+
+static void nxagentFreeFailedToReconnectFonts()
+{
+  if (nxagentFailedToReconnectFonts.font != NULL)
+  {
+    free(nxagentFailedToReconnectFonts.font);
+    nxagentFailedToReconnectFonts.font = NULL;
+  }
+
+  if (nxagentFailedToReconnectFonts.id != NULL)
+  {
+    free(nxagentFailedToReconnectFonts.id);
+    nxagentFailedToReconnectFonts.id = NULL;
+  }
+
+  nxagentFailedToReconnectFonts.size = 0;
+  nxagentFailedToReconnectFonts.index = 0;
+}
+
+Bool nxagentReconnectFailedFonts(void *p0)
+{
+  int i;
+  int attempt = 1;
+  const int maxAttempt = 5;
+
+  char **fontPaths, **localFontPaths, **newFontPaths;
+  char fontServerPath[256];
+  int nPaths = 0;
+
+  Bool repeat = True;
+  Bool fontSuccess = True;
+
+  reconnectFlexibility = *((int *) p0);
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentReconnectFailedFonts: \n");
+  #endif
+
+  if (nxagentGetFontServerPath(fontServerPath) == False)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentReconnectFailedFonts: WARNING! "
+                "Font server tunneling not retrieved.\n");
+    #endif
+  }
+
+  #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+  fprintf(stderr, "nxagentReconnectFailedFonts: font server path [%s]\n", fontServerPath);
+  #endif
+
+  fontPaths = XGetFontPath(nxagentDisplay, &nPaths);
+
+  if ((newFontPaths =  malloc((nPaths + 1) * sizeof(char *))) == NULL)
+  {
+    FatalError("nxagentReconnectFailedFonts: malloc failed.");
+  }
+
+  memcpy(newFontPaths, fontPaths, nPaths * sizeof(char*));
+
+  localFontPaths = newFontPaths;
+  localFontPaths += nPaths;
+  *localFontPaths = fontServerPath;
+
+  while(repeat)
+  {
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "nxagentReconnectFailedFonts: attempt [%d].\n", attempt);
+    #endif
+
+    repeat = False;
+
+    XSetFontPath(nxagentDisplay, newFontPaths, nPaths  + 1);
+    nxagentFreeRemoteFontList(&nxagentRemoteFontList);
+    nxagentListRemoteFonts("*", nxagentMaxFontNames);
+
+    for(i = 0; i < nxagentFailedToReconnectFonts.index; i++)
+    {
+      fontSuccess = True;
+
+      if(nxagentFailedToReconnectFonts.font[i])
+      {
+        nxagentFailedFontReconnect(nxagentFailedToReconnectFonts.font[i],
+                                       nxagentFailedToReconnectFonts.id[i],
+                                           &fontSuccess);
+
+        if (fontSuccess)
+        {
+          nxagentFailedToReconnectFonts.font[i] = NULL;
+        }
+        else
+        {
+          repeat = True;
+        }
+
+      }
+    }
+
+    attempt++;
+
+    if (attempt > maxAttempt)
+    {
+      nxagentFreeFailedToReconnectFonts();
+
+      XSetFontPath(nxagentDisplay, fontPaths, nPaths);
+      nxagentFreeRemoteFontList(&nxagentRemoteFontList);
+      nxagentListRemoteFonts("*", nxagentMaxFontNames);
+
+      XFreeFontPath(fontPaths);
+      free(newFontPaths);
+
+      return False;
+    }
+  }
+
+  nxagentFreeFailedToReconnectFonts();
+
+  XSetFontPath(nxagentDisplay, fontPaths, nPaths);
+
+  XFreeFontPath(fontPaths);
+  free(newFontPaths);
+
+  nxagentCleanCacheAfterReconnect();
+
+  return True;
+}
+
+Bool nxagentDisconnectAllFonts()
+{
+  int cid;
+  Bool fontSuccess = True;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_FONT_DEBUG)
+  fprintf(stderr, "nxagentDisconnectAllFonts\n");
+  #endif
+
+  nxagentFreeRemoteFontList(&nxagentRemoteFontList);
+  nxagentFreeCacheBeforeReconnect();
+
+  /*
+   * The resource type RT_NX_FONT is created on the
+   * server client only, so we can avoid to loop
+   * through all the clients.
+   */
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_FONT,
+                                (FindResType) nxagentFontDisconnect, &fontSuccess);
+
+  for(cid = 0; cid < MAXCLIENTS; cid++)
+  {
+    if( clients[cid] && fontSuccess )
+    {
+      FindClientResourcesByType(clients[cid], RT_FONT,
+                                    (FindResType) nxagentFontDisconnect, &fontSuccess);
+    }
+  }
+
+  return True;
+}
+
+static Bool nxagentGetFontServerPath(char * fontServerPath)
+{
+  char path[256];
+
+  if (NXGetFontParameters(nxagentDisplay, 256, path) == True)
+  {
+    if (*path != '\0')
+    {
+      strncpy(fontServerPath, path + 1, *path);
+
+      *(fontServerPath + *path) = '\0';
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentGetFontServerPath: Got path [%s].\n",
+                  fontServerPath);
+      #endif
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentGetFontServerPath: WARNING! Font server tunneling not enabled.\n");
+      #endif
+
+      return False;
+    }
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentGetFontServerPath: WARNING! Failed to get path for font server tunneling.\n");
+    #endif
+
+    return False;
+  }
+
+  return True;
+}
+
+void nxagentVerifyDefaultFontPath(void)
+{
+  struct stat dirStat;
+  static char *fontPath;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentVerifyDefaultFontPath: Going to search for one or more valid font paths.\n");
+  #endif
+
+  fontPath = malloc(strlen(defaultFontPath) + 1);
+
+  if (fontPath == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: WARNING! Unable to allocate memory for a new font path. "
+                "Using the default font path [%s].\n", validateString(defaultFontPath));
+    #endif
+
+    return;
+  }
+
+  /*
+   * Set the default font path as the first choice.
+   */
+
+  strcpy(fontPath, defaultFontPath);
+
+  if (stat(NXAGENT_DEFAULT_FONT_DIR, &dirStat) == 0 &&
+          S_ISDIR(dirStat.st_mode) != 0)
+  {
+    /*
+     * Let's use the old "/usr/X11R6/lib/X11/fonts" style.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+                validateString(NXAGENT_DEFAULT_FONT_DIR));
+    #endif
+
+    if (*fontPath != '\0')
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_DEFAULT_FONT_PATH) + 2);
+      strcat(fontPath, ",");
+    }
+    else
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_DEFAULT_FONT_PATH) + 1);
+    }
+
+    strcat(fontPath, NXAGENT_DEFAULT_FONT_PATH);
+  }
+
+  if (stat(NXAGENT_ALTERNATE_FONT_DIR, &dirStat) == 0 &&
+          S_ISDIR(dirStat.st_mode) != 0)
+  {
+    /*
+     * Let's use the new "/usr/share/X11/fonts" path.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+                validateString(NXAGENT_ALTERNATE_FONT_DIR));
+    #endif
+
+    if (*fontPath != '\0')
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH) + 2);
+      strcat(fontPath, ",");
+    }
+    else
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH) + 1);
+    }
+
+    strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH);
+  }
+
+  if (stat(NXAGENT_ALTERNATE_FONT_DIR_2, &dirStat) == 0 &&
+          S_ISDIR(dirStat.st_mode) != 0)
+  {
+    /*
+     * Let's use the "/usr/share/fonts/X11" path.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+                validateString(NXAGENT_ALTERNATE_FONT_DIR_2));
+    #endif
+
+    if (*fontPath != '\0')
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_2) + 2);
+      strcat(fontPath, ",");
+    }
+    else
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_2) + 1);
+    }
+
+    strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_2);
+  }
+
+  if (stat(NXAGENT_ALTERNATE_FONT_DIR_3, &dirStat) == 0 &&
+          S_ISDIR(dirStat.st_mode) != 0)
+  {
+    /*
+     * Let's use the "/usr/share/fonts" path.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+                validateString(NXAGENT_ALTERNATE_FONT_DIR_3));
+    #endif
+
+    if (*fontPath != '\0')
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_3) + 2);
+      strcat(fontPath, ",");
+    }
+    else
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_3) + 1);
+    }
+
+    strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_3);
+  }
+
+  if (*fontPath == '\0') 
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: WARNING! Can't find a valid font directory.\n");
+
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: WARNING! Using font path [%s].\n",
+                validateString(defaultFontPath));
+    #endif
+  }
+  else
+  {
+    defaultFontPath = fontPath;
+ 
+    #ifdef TEST
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: Using font path [%s].\n",
+                validateString(defaultFontPath));
+    #endif
+ }
+
+  return;
+}
+
+XFontStruct* nxagentLoadQueryFont(register Display *dpy, char *name, FontPtr pFont)
+{
+  XFontStruct* fs;
+  xCharInfo *xcip;
+
+  fs = (XFontStruct *) malloc (sizeof (XFontStruct));
+
+  if (fs == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontStruct.\n");
+    #endif
+
+    return (XFontStruct *)NULL;
+  }
+
+    #ifdef NXAGENT_RECONNECT_FONT_DEBUG
+    fprintf(stderr, "nxagentLoadQueryFont: Looking for font '%s'.\n", name);
+    #endif
+
+  if (nxagentFontLookUp(name) == 0)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentLoadQueryFont: WARNING! Font not found '%s'.\n", name);
+    #endif
+
+    Xfree(fs);
+
+    return (XFontStruct *) NULL;
+  }
+
+  fs -> ext_data           = NULL;                      /* Hook for extension to hang data.*/
+  fs -> fid                = XLoadFont(dpy, name);      /* Font id for this font. */
+  fs -> direction          = pFont->info.drawDirection; /* Hint about the direction font is painted. */
+  fs -> min_char_or_byte2  = pFont->info.firstCol;      /* First character. */
+  fs -> max_char_or_byte2  = pFont->info.lastCol;       /* Last character. */
+  fs -> min_byte1          = pFont->info.firstRow;      /* First row that exists. */
+  fs -> max_byte1          = pFont->info.lastRow;       /* Last row that exists. */
+  fs -> all_chars_exist    = pFont->info.allExist;      /* Flag if all characters have nonzero size. */
+  fs -> default_char       = pFont->info.defaultCh;     /* Char to print for undefined character. */
+  fs -> n_properties       = pFont->info.nprops;        /* How many properties there are. */
+
+  /*
+   * If no properties defined for the font, then it is bad
+   * font, but shouldn't try to read nothing.
+   */
+
+  if (fs -> n_properties > 0)
+  {
+    register long nbytes;
+
+    nbytes = pFont -> info.nprops * sizeof(XFontProp);
+    fs -> properties = (XFontProp *) Xalloc((unsigned) nbytes);
+
+    if (fs -> properties == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentLoadQueryFont: WARNING! Failed allocation of XFontProp.");
+      #endif
+
+      Xfree((char *) fs);
+      return (XFontStruct *) NULL;
+    }
+
+    memmove(fs -> properties, pFont -> info.props, nbytes);
+  }
+
+  xcip = (xCharInfo *) &pFont -> info.ink_minbounds;
+
+  fs -> min_bounds.lbearing      = cvtINT16toShort(xcip -> leftSideBearing);
+  fs -> min_bounds.rbearing      = cvtINT16toShort(xcip -> rightSideBearing);
+  fs -> min_bounds.width         = cvtINT16toShort(xcip -> characterWidth);
+  fs -> min_bounds.ascent        = cvtINT16toShort(xcip -> ascent);
+  fs -> min_bounds.descent       = cvtINT16toShort(xcip -> descent);
+  fs -> min_bounds.attributes    = xcip -> attributes;
+
+  xcip = (xCharInfo *) &pFont -> info.ink_maxbounds;
+
+  fs -> max_bounds.lbearing      = cvtINT16toShort(xcip -> leftSideBearing);
+  fs -> max_bounds.rbearing      = cvtINT16toShort(xcip -> rightSideBearing);
+  fs -> max_bounds.width         = cvtINT16toShort(xcip -> characterWidth);
+  fs -> max_bounds.ascent        = cvtINT16toShort(xcip -> ascent);
+  fs -> max_bounds.descent       = cvtINT16toShort(xcip -> descent);
+  fs -> max_bounds.attributes    = xcip -> attributes;
+
+  fs -> per_char           = NULL;                              /* First_char to last_char information. */
+  fs -> ascent             = pFont->info.fontAscent;            /* Logical extent above baseline for spacing. */
+  fs -> descent            = pFont->info.fontDescent;           /* Logical decent below baseline for spacing. */
+
+  return fs;
+}
+
+int nxagentFreeFont(XFontStruct *fs)
+{
+
+  if (fs -> per_char)
+  {
+    #ifdef USE_XF86BIGFONT
+    _XF86BigfontFreeFontMetrics(fs);
+    #else
+    Xfree ((char *) fs->per_char);
+    #endif
+  }
+
+  if (fs -> properties)
+  {
+    Xfree (fs->properties);
+  }
+
+  XFree(fs);
+
+  return 1;
+}
+
+
+int nxagentSplitString(char *string, char *fields[], int nfields, char *sep)
+{
+  int seplen;
+  int fieldlen;
+  int last;
+  int len;
+  int i;
+
+  char *current;
+  char *next;
+
+  seplen = strlen(sep);
+  len = strlen(string);
+
+  current = string;
+
+  i = 0;
+  last = 0;
+
+  for (;;)
+  {
+    next = NULL;
+
+    if (current < string + len)
+    {
+      next = strstr(current, sep);
+    }
+
+    if (next == NULL)
+    {
+      next = string + len;
+      last = 1;
+    }
+
+    fieldlen = next - current;
+
+    if (i < nfields)
+    {
+      fields[i] = (char *) malloc(fieldlen + 1);
+      strncpy(fields[i], current, fieldlen);
+      *(fields[i] + fieldlen) = 0;
+    }
+
+    current = next + seplen;
+
+    i++;
+
+    if (last == 1)
+    {
+      break;
+    }
+  }
+
+  return i;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.h b/nx-X11/programs/Xserver/hw/nxagent/Font.h
new file mode 100644
index 000000000..3ae086b44
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.h
@@ -0,0 +1,77 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Font_H__
+#define __Font_H__
+
+#include "fontstruct.h"
+#include "resource.h"
+
+extern RESTYPE RT_NX_FONT;
+
+extern int nxagentFontPrivateIndex;
+
+typedef struct
+{
+  XFontStruct *font_struct;
+  char fontName[256];
+  XID mirrorID;
+} nxagentPrivFont;
+
+extern const int nxagentMaxFontNames;
+
+#define nxagentFontPriv(pFont) \
+  ((nxagentPrivFont *)FontGetPrivate(pFont, nxagentFontPrivateIndex))
+
+#define nxagentFontStruct(pFont) (nxagentFontPriv(pFont)->font_struct)
+
+#define nxagentFont(pFont) (nxagentFontStruct(pFont)->fid)
+
+Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont);
+Bool nxagentUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
+
+void nxagentFreeFontCache(void);
+
+void nxagentListRemoteFonts(const char *searchPattern, const int maxNames);
+int nxagentFontLookUp(const char *name);
+Bool nxagentFontFind(const char *name, int *pos);
+void nxagentListRemoteAddName(const char *name, int status);
+
+int nxagentDestroyNewFontResourceType(pointer p, XID id);
+
+Bool nxagentDisconnectAllFonts(void);
+Bool nxagentReconnectAllFonts(void *p0);
+
+void nxagentVerifyDefaultFontPath(void);
+
+int nxagentSplitString(char *string, char *fields[], int nfields, char *sep);
+
+#endif /* __Font_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GC.c b/nx-X11/programs/Xserver/hw/nxagent/GC.c
new file mode 100644
index 000000000..4ca069790
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GC.c
@@ -0,0 +1,1712 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 "X.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "fontstruct.h"
+#include "mistruct.h"
+#include "region.h"
+
+#include "Agent.h"
+
+#include "Display.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Image.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "Font.h"
+#include "Colormap.h"
+#include "Trap.h"
+#include "Screen.h"
+#include "Pixels.h"
+
+#include "../../fb/fb.h"
+
+RESTYPE RT_NX_GC;
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+int nxagentGCPrivateIndex;
+
+nxagentGraphicContextsPtr nxagentGraphicContexts;
+int nxagentGraphicContextsSize;
+
+void nxagentDisconnectGraphicContexts(void);
+GCPtr nxagentCreateGraphicContext(int depth);
+
+static void nxagentReconnectGC(void*, XID, void*);
+static void nxagentReconnectClip(GCPtr, int, pointer, int);
+static int  nxagentCompareRegions(RegionPtr, RegionPtr);
+
+struct nxagentGCRec
+{
+  GCPtr pGC;
+  XlibGC gc;
+  struct nxagentGCRec *next;
+};
+
+static struct
+{
+  struct nxagentGCRec *first;
+  struct nxagentGCRec *last;
+  int size;
+} nxagentGCList = { NULL, NULL, 0 };
+
+static struct nxagentGCRec *nxagentGetFirstGC(void);
+
+static void nxagentRestoreGCList(void);
+
+static GCFuncs nxagentFuncs =
+{
+  nxagentValidateGC,
+  nxagentChangeGC,
+  nxagentCopyGC,
+  nxagentDestroyGC,
+  nxagentChangeClip,
+  nxagentDestroyClip,
+  nxagentCopyClip,
+};
+
+static GCOps nxagentOps =
+{
+  nxagentFillSpans,
+  nxagentSetSpans,
+  nxagentPutImage,
+  nxagentCopyArea,
+  nxagentCopyPlane,
+  nxagentPolyPoint,
+  nxagentPolyLines,
+  nxagentPolySegment,
+  nxagentPolyRectangle,
+  nxagentPolyArc,
+  nxagentFillPolygon,
+  nxagentPolyFillRect,
+  nxagentPolyFillArc,
+  nxagentPolyText8,
+  nxagentPolyText16,
+  nxagentImageText8,
+  nxagentImageText16,
+  nxagentImageGlyphBlt,
+  nxagentPolyGlyphBlt,
+  nxagentPushPixels
+};
+
+Bool nxagentCreateGC(GCPtr pGC)
+{
+  FbGCPrivPtr pPriv;
+
+  pGC->clientClipType = CT_NONE;
+  pGC->clientClip = NULL;
+
+  pGC->funcs = &nxagentFuncs;
+  pGC->ops = &nxagentOps;
+
+  pGC->miTranslate = 1;
+
+  if (pGC -> stipple && !nxagentPixmapIsVirtual(pGC -> stipple))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentCreateGC: GC at [%p] got real stipple at [%p] switched to virtual.\n",
+                (void*)pGC, (void*)pGC -> stipple);
+    #endif
+
+    pGC -> stipple = nxagentVirtualPixmap(pGC -> stipple);
+  }
+
+  /*
+   * We create the GC based on the default
+   * drawables. The proxy knows this and
+   * optimizes the encoding of the create
+   * GC message to include the id of the
+   * drawable in the checksum.
+   */
+
+  nxagentGCPriv(pGC)->gc = XCreateGC(nxagentDisplay,
+                                     nxagentDefaultDrawables[pGC->depth],
+                                     0L, NULL);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateGC: GC [%p]\n", (void *) pGC);
+  #endif
+
+  pPriv = (pGC)->devPrivates[fbGCPrivateIndex].ptr;
+
+  fbGetRotatedPixmap(pGC) = 0;
+  fbGetExpose(pGC) = 1;
+  fbGetFreeCompClip(pGC) = 0;
+  fbGetCompositeClip(pGC) = 0;
+
+  pPriv->bpp = BitsPerPixel (pGC->depth);
+
+  nxagentGCPriv(pGC)->nClipRects = 0;
+
+  memset(&(nxagentGCPriv(pGC) -> lastServerValues), 0, sizeof(XGCValues));
+
+  /*
+   * Init to default GC values.
+   */
+
+  nxagentGCPriv(pGC) -> lastServerValues.background = 1;
+
+  nxagentGCPriv(pGC) -> lastServerValues.plane_mask = ~0;
+
+  nxagentGCPriv(pGC) -> lastServerValues.graphics_exposures = 1;
+
+  nxagentGCPriv(pGC) -> lastServerValues.dashes = 4;
+
+  nxagentGCPriv(pGC) -> mid = FakeClientID(serverClient -> index);
+
+  nxagentGCPriv(pGC) -> pPixmap = NULL;
+
+  AddResource(nxagentGCPriv(pGC) -> mid, RT_NX_GC, (pointer) pGC);
+
+  return True;
+}
+
+void nxagentValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+  PixmapPtr lastTile, lastStipple;
+
+  DrawablePtr pVirtual = (pDrawable -> type == DRAWABLE_PIXMAP) ?
+                          nxagentVirtualDrawable(pDrawable) :
+                          pDrawable;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentValidateGC: Going to validate GC at [%p] for drawable at [%p] with changes [%lx].\n",
+              (void *) pGC, (void *) pDrawable, changes);
+  #endif
+
+  pGC->lastWinOrg.x = pDrawable->x;
+  pGC->lastWinOrg.y = pDrawable->y;
+
+  if (!pGC -> tileIsPixel && !nxagentPixmapIsVirtual(pGC -> tile.pixmap))
+  {
+    pGC -> tile.pixmap = nxagentVirtualPixmap(pGC -> tile.pixmap); 
+  }
+
+  lastTile = pGC -> tile.pixmap;
+
+  lastStipple = pGC->stipple;
+  
+  if (lastStipple)
+  {
+    pGC->stipple = nxagentVirtualPixmap(pGC->stipple);
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentValidateGC: Drawable at [%p] has type [%s] virtual [%p] bits per pixel [%d].\n",
+              (void *) pDrawable, (pDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+                  (void *) pVirtual, pVirtual -> bitsPerPixel);
+  #endif
+
+  if (pVirtual -> bitsPerPixel == 0)
+  {
+    /*
+     * Don't enter fbValidateGC() with 0 bpp
+     * or agent will block in a endless loop.
+     */
+
+    #ifdef WARNING
+    fprintf(stderr, "nxagentValidateGC: WARNING! Virtual drawable at [%p] has invalid bits per pixel.\n",
+                (void *) pVirtual);
+
+    fprintf(stderr, "nxagentValidateGC: WARNING! While validating GC at [%p] for drawable at [%p] with changes [%lx].\n",
+                (void *) pGC, (void *) pDrawable, changes);
+
+    fprintf(stderr, "nxagentValidateGC: WARNING! Bad drawable at [%p] has type [%s] virtual [%p] bits per pixel [%d].\n",
+                (void *) pDrawable, (pDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+                    (void *) pVirtual, pVirtual -> bitsPerPixel);
+    #endif
+  }
+  else
+  {
+    fbValidateGC(pGC, changes, pVirtual);
+  }
+
+  if (pGC->tile.pixmap != lastTile)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentValidateGC: WARNING! Transforming pixmap at [%p] virtual at [%p] "
+                "in virtual pixmap.\n", (void *) nxagentPixmapPriv(pGC -> tile.pixmap) -> pRealPixmap,
+                    (void *) nxagentPixmapPriv(pGC -> tile.pixmap) -> pRealPixmap);
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentValidateGC: GC [%p] new tile [%p] from fb set as virtual\n",
+                (void *) pGC, (void *) pGC->tile.pixmap);
+    #endif
+
+    nxagentPixmapIsVirtual(pGC->tile.pixmap) = True;
+    nxagentRealPixmap(pGC->tile.pixmap) = nxagentRealPixmap(lastTile);
+
+    if (nxagentRealPixmap(lastTile))
+    {
+      nxagentPixmapPriv(nxagentRealPixmap(lastTile))->pVirtualPixmap = pGC->tile.pixmap;
+    }
+  }
+
+  pGC->stipple = lastStipple;
+}
+
+void nxagentChangeGC(GCPtr pGC, unsigned long mask)
+{
+  #ifdef TEST
+  static int nDiscarded;
+  #endif
+
+  XGCValues values;
+
+  int changeFlag = 0;
+
+  if (mask & GCFunction)
+  {
+    values.function = pGC->alu;
+
+    changeFlag |= nxagentTestGC(values.function, function);
+  }
+
+  if (mask & GCPlaneMask)
+  {
+    values.plane_mask = pGC->planemask;
+
+    changeFlag += nxagentTestGC(values.plane_mask, plane_mask);
+  }
+
+  if (mask & GCForeground)
+  {
+    values.foreground = nxagentPixel(pGC->fgPixel);
+
+    changeFlag += nxagentTestGC(values.foreground, foreground);
+  }
+
+  if (mask & GCBackground)
+  {
+    values.background = nxagentPixel(pGC->bgPixel);
+
+    changeFlag += nxagentTestGC(values.background, background);
+  }
+
+  if (mask & GCLineWidth)
+  {
+    values.line_width = pGC->lineWidth;
+
+    changeFlag += nxagentTestGC(values.line_width, line_width);
+  }
+
+  if (mask & GCLineStyle)
+  {
+    values.line_style = pGC->lineStyle;
+
+    changeFlag += nxagentTestGC(values.line_style, line_style);
+  }
+
+  if (mask & GCCapStyle)
+  {
+    values.cap_style = pGC->capStyle;
+
+    changeFlag += nxagentTestGC(values.cap_style, cap_style);
+  }
+
+  if (mask & GCJoinStyle)
+  {
+    values.join_style = pGC->joinStyle;
+
+    changeFlag += nxagentTestGC(values.join_style, join_style);
+  }
+
+  if (mask & GCFillStyle)
+  {
+    values.fill_style = pGC->fillStyle;
+
+    changeFlag += nxagentTestGC(values.fill_style, fill_style);
+  }
+
+  if (mask & GCFillRule)
+  {
+    values.fill_rule = pGC->fillRule;
+
+    changeFlag += nxagentTestGC(values.fill_rule, fill_rule);
+  }
+
+  if (mask & GCTile)
+  {
+    if (pGC->tileIsPixel)
+    {
+      mask &= ~GCTile;
+    }
+    else
+    {
+      if (nxagentDrawableStatus((DrawablePtr) pGC -> tile.pixmap) == NotSynchronized &&
+              nxagentGCTrap == 0)
+      {
+        /*
+         * If the tile is corrupted and is not too
+         * much large, it can be synchronized imme-
+         * diately. In the other cases, the tile is
+         * cleared with a solid color to become usa-
+         * ble. This approach should solve the high
+         * delay on slow links waiting for a back-
+         * ground tile to be synchronized.
+         */
+
+        if (nxagentOption(DeferLevel) >= 2 &&
+               (pGC -> tile.pixmap -> drawable.width > 240 ||
+                    pGC -> tile.pixmap -> drawable.height > 240))
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentChangeGC: WARNING! Going to fill with solid color the corrupted tile at [%p] "
+                      "for GC at [%p] with size [%dx%d].\n", (void *) pGC -> tile.pixmap, (void *)pGC,
+                          ((DrawablePtr) pGC -> tile.pixmap) -> width, ((DrawablePtr) pGC -> tile.pixmap) -> height);
+          #endif
+
+          nxagentFillRemoteRegion((DrawablePtr) pGC -> tile.pixmap, nxagentCorruptedRegion((DrawablePtr) pGC -> tile.pixmap));
+        }
+        else
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentChangeGC: WARNING! Synchronizing GC at [%p] due the tile at [%p] with size [%dx%d].\n",
+                      (void *)pGC, (void *)pGC -> tile.pixmap, ((DrawablePtr) pGC -> tile.pixmap) -> width,
+                          ((DrawablePtr) pGC -> tile.pixmap) -> height);
+          #endif
+
+          nxagentSynchronizeDrawable((DrawablePtr) pGC -> tile.pixmap, DO_WAIT, NEVER_BREAK, NULL);
+        }
+      }
+
+      values.tile = nxagentPixmap(pGC->tile.pixmap);
+
+      pGC->tile.pixmap = nxagentVirtualPixmap(pGC->tile.pixmap);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentChangeGC: New tile on GC [%p] tile is [%p]\n",
+                  (void *) pGC, (void *) pGC->tile.pixmap);
+      #endif
+
+      changeFlag += nxagentTestGC(values.tile, tile);
+    }
+  }
+
+  if (mask & GCStipple)
+  {
+    if (nxagentDrawableStatus((DrawablePtr) pGC -> stipple) == NotSynchronized &&
+            nxagentGCTrap == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentChangeGC: WARNING! Synchronizing GC at [%p] due the stipple at [%p].\n",
+                  (void *)pGC, (void *)pGC -> stipple);
+      #endif
+
+      nxagentSynchronizeDrawable((DrawablePtr) pGC -> stipple, DO_WAIT, NEVER_BREAK, NULL);
+    }
+
+    values.stipple = nxagentPixmap(pGC->stipple);
+
+    pGC->stipple = nxagentVirtualPixmap(pGC->stipple);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentChangeGC: New stipple on GC [%p] stipple is [%p]\n",
+                (void *) pGC, (void *) pGC->stipple);
+    #endif
+
+    changeFlag += nxagentTestGC(values.stipple, stipple);
+  }
+
+  if (mask & GCTileStipXOrigin)
+  {
+    values.ts_x_origin = pGC->patOrg.x;
+
+    changeFlag += nxagentTestGC(values.ts_x_origin, ts_x_origin);
+  }
+
+  if (mask & GCTileStipYOrigin)
+  {
+    values.ts_y_origin = pGC->patOrg.y;
+
+    changeFlag += nxagentTestGC(values.ts_y_origin, ts_y_origin);
+  }
+
+  if (mask & GCFont)
+  {
+    if (!nxagentFontStruct(pGC -> font))
+    {
+      mask &= ~GCFont;
+    }
+    else
+    {
+      values.font = nxagentFont(pGC->font);
+
+      changeFlag += nxagentTestGC(values.font, font);
+    }
+  } 
+
+  if (mask & GCSubwindowMode)
+  {
+    values.subwindow_mode = pGC->subWindowMode;
+
+    changeFlag += nxagentTestGC(values.subwindow_mode, subwindow_mode);
+  }
+
+  if (mask & GCGraphicsExposures)
+  {
+    values.graphics_exposures = pGC->graphicsExposures;
+
+    changeFlag += nxagentTestGC(values.graphics_exposures, graphics_exposures);
+  }
+
+  if (mask & GCClipXOrigin)
+  {
+    values.clip_x_origin = pGC->clipOrg.x;
+
+    changeFlag += nxagentTestGC(values.clip_x_origin, clip_x_origin);
+  }
+
+  if (mask & GCClipYOrigin)
+  {
+    values.clip_y_origin = pGC->clipOrg.y;
+
+    changeFlag += nxagentTestGC(values.clip_y_origin, clip_y_origin);
+  }
+
+  if (mask & GCClipMask)
+  {
+    /*
+     * This is handled in the change clip.
+     */
+
+    mask &= ~GCClipMask;
+  }
+
+  if (mask & GCDashOffset)
+  {
+    values.dash_offset = pGC->dashOffset;
+
+    changeFlag += nxagentTestGC(values.dash_offset, dash_offset);
+  }
+
+  if (mask & GCDashList)
+  {
+    mask &= ~GCDashList;
+
+    if (nxagentGCTrap == 0)
+    {
+      XSetDashes(nxagentDisplay, nxagentGC(pGC),
+                     pGC->dashOffset, (char *)pGC->dash, pGC->numInDashList);
+    }
+  }
+
+  if (mask & GCArcMode)
+  {
+    values.arc_mode = pGC->arcMode;
+
+    changeFlag += nxagentTestGC(values.arc_mode, arc_mode);
+  }
+
+  if (nxagentGCTrap == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentChangeGC: Skipping change of GC at [%p] on the real X server.\n",
+                (void *) pGC);
+    #endif
+
+    return;
+  }
+
+  if (mask && changeFlag)
+  {
+    XChangeGC(nxagentDisplay, nxagentGC(pGC), mask, &values);
+  }
+  #ifdef TEST
+  else if (mask)
+  {
+    fprintf(stderr, "nxagentChangeGC: Discarded [%d] Mask [%lu]\n", ++nDiscarded, mask);
+  }
+  #endif
+}
+
+void nxagentCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentCopyGC: Copying the GC with source at [%p] destination "
+              "at [%p] mask [%lu].\n", pGCSrc, pGCDst, mask);
+  #endif
+
+  /*
+   * The MI function doesn't do anything.
+   *
+   * miCopyGC(pGCSrc, mask, pGCDst);
+   */
+
+  XCopyGC(nxagentDisplay, nxagentGC(pGCSrc), mask, nxagentGC(pGCDst));
+
+  /*
+   * Copy the private foreground field
+   * of the GC if GCForeground is set.
+   */
+
+  nxagentCopyGCPriv(GCForeground,foreground,pGCSrc,mask,pGCDst);
+}
+
+void nxagentDestroyGC(GCPtr pGC)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyGC: GC at [%p].\n", (void *) pGC);
+  #endif
+
+  if (nxagentGCPriv(pGC) -> mid != 0)
+  {
+    FreeResource(nxagentGCPriv(pGC) -> mid, RT_NONE);
+  }
+
+  XFreeGC(nxagentDisplay, nxagentGC(pGC));
+
+  miDestroyGC(pGC);
+}
+
+void nxagentChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
+{
+  int i, size;
+  BoxPtr pBox;
+  XRectangle *pRects;
+  int clipsMatch = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentChangeClip: Going to change clip on GC [%p]\n",
+              (void *) pGC);
+  #endif
+
+  switch (type)
+  {
+    case CT_NONE:
+    {
+      clipsMatch = (pGC -> clientClipType == None);
+
+      break;
+    }
+    case CT_REGION:
+    {
+      clipsMatch = nxagentCompareRegions(pGC -> clientClip, (RegionPtr) pValue);
+
+      break;
+    }
+    case CT_UNSORTED:
+    case CT_YSORTED:
+    case CT_YXSORTED:
+    case CT_YXBANDED:
+    {
+      RegionPtr pReg = RECTS_TO_REGION(pGC->pScreen, nRects, (xRectangle *)pValue, type);
+
+      clipsMatch = nxagentCompareRegions(pGC -> clientClip, pReg);
+
+      REGION_DESTROY(pGC->pScreen, pReg);
+
+      break;
+    }
+    default:
+    {
+      clipsMatch = 0;
+
+      break;
+    }
+  }
+
+  nxagentDestroyClipHelper(pGC);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentChangeClip: Type [%d] regions clipsMatch [%d].\n",
+              type, clipsMatch);
+  #endif
+
+  switch (type)
+  {
+    case CT_NONE:
+    {
+      if (clipsMatch == 0 && nxagentGCTrap == 0)
+      {
+        XSetClipMask(nxagentDisplay, nxagentGC(pGC), None);
+      }
+
+      break;
+    }
+    case CT_REGION:
+    {
+      if (clipsMatch == 0 && nxagentGCTrap == 0)
+      {
+        nRects = REGION_NUM_RECTS((RegionPtr)pValue);
+        size = nRects * sizeof(*pRects);
+        pRects = (XRectangle *) xalloc(size);
+        pBox = REGION_RECTS((RegionPtr)pValue);
+
+        for (i = nRects; i-- > 0;)
+        {
+          pRects[i].x = pBox[i].x1;
+          pRects[i].y = pBox[i].y1;
+          pRects[i].width = pBox[i].x2 - pBox[i].x1;
+          pRects[i].height = pBox[i].y2 - pBox[i].y1;
+        }
+
+        XSetClipRectangles(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y,
+                               pRects, nRects, Unsorted);
+        xfree((char *) pRects);
+      }
+
+      break;
+    }
+    case CT_PIXMAP:
+    {
+      if (nxagentGCTrap == 0)
+      {
+        XSetClipMask(nxagentDisplay, nxagentGC(pGC),
+                         nxagentPixmap((PixmapPtr)pValue));
+      }
+
+      pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr) pValue);
+
+      nxagentGCPriv(pGC)->pPixmap = (PixmapPtr)pValue;
+
+      pValue = pGC->clientClip;
+
+      type = CT_REGION;
+
+      break;
+    }
+    case CT_UNSORTED:
+    {
+      if (clipsMatch == 0 && nxagentGCTrap == 0)
+      {    
+        XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                               pGC->clipOrg.x, pGC->clipOrg.y,
+                                   (XRectangle *)pValue, nRects, Unsorted);
+      }
+
+      break;
+    }
+    case CT_YSORTED:
+    {
+      if (clipsMatch == 0 && nxagentGCTrap == 0)
+      {
+        XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                           pGC->clipOrg.x, pGC->clipOrg.y,
+                           (XRectangle *)pValue, nRects, YSorted);
+      }
+
+      break;
+    }
+    case CT_YXSORTED:
+    {
+      if (clipsMatch == 0 && nxagentGCTrap == 0)
+      {
+        XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                           pGC->clipOrg.x, pGC->clipOrg.y,
+                           (XRectangle *)pValue, nRects, YXSorted);
+      }
+
+      break;
+    }
+    case CT_YXBANDED:
+    {
+      if (clipsMatch == 0 && nxagentGCTrap == 0)
+      {
+        XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                         pGC->clipOrg.x, pGC->clipOrg.y,
+                         (XRectangle *)pValue, nRects, YXBanded);
+      }
+
+      break;
+    }
+  }
+
+  switch(type)
+  {
+    case CT_UNSORTED:
+    case CT_YSORTED:
+    case CT_YXSORTED:
+    case CT_YXBANDED:
+    {
+      /*
+       * Other parts of the server can only
+       * deal with CT_NONE, CT_PIXMAP and
+       * CT_REGION client clips.
+       */
+
+      pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nRects,
+                                                  (xRectangle *)pValue, type);
+      xfree(pValue);
+
+      pValue = pGC->clientClip;
+
+      type = CT_REGION;
+
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
+
+  pGC->clientClipType = type;
+  pGC->clientClip = pValue;
+
+  nxagentGCPriv(pGC)->nClipRects = nRects;
+}
+
+void nxagentDestroyClip(GCPtr pGC)
+{
+  miDestroyClip(pGC);
+
+  if (pGC->clientClipType == CT_PIXMAP)
+  {
+    (*pGC->pScreen->DestroyPixmap)((PixmapPtr) (pGC->clientClip));
+  }
+
+  nxagentDestroyClipHelper(pGC);
+
+  if (nxagentGCTrap == 0)
+  {
+    XSetClipMask(nxagentDisplay, nxagentGC(pGC), None);
+  }
+
+  pGC->clientClipType = CT_NONE;
+  pGC->clientClip = NULL;
+
+  nxagentGCPriv(pGC)->nClipRects = 0;
+}
+
+void nxagentDestroyClipHelper(GCPtr pGC)
+{
+  switch (pGC->clientClipType)
+  {
+    default:
+    case CT_NONE:
+      break;
+    case CT_REGION:
+      REGION_DESTROY(pGC->pScreen, pGC->clientClip);
+      break;
+    case CT_PIXMAP:
+      nxagentDestroyPixmap((PixmapPtr)pGC->clientClip);
+      break;
+  }
+
+  if (nxagentGCPriv(pGC)->pPixmap != NULL)
+  {
+    nxagentDestroyPixmap(nxagentGCPriv(pGC)->pPixmap);
+    nxagentGCPriv(pGC)->pPixmap = NULL;
+  }
+}
+
+void nxagentCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
+{
+  RegionPtr pRgn;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCopyClip: Going to copy clip from GC [%p] to GC [%p]\n",
+              (void *) pGCDst, (void *) pGCSrc);
+  #endif
+
+  switch (pGCSrc->clientClipType)
+  {
+    case CT_REGION:
+      if (nxagentGCPriv(pGCSrc)->pPixmap == NULL)
+      {
+        pRgn = REGION_CREATE(pGCDst->pScreen, NULL, 1);
+        REGION_COPY(pGCDst->pScreen, pRgn, pGCSrc->clientClip);
+        nxagentChangeClip(pGCDst, CT_REGION, pRgn, 0);
+      }
+      else
+      {
+        nxagentGCPriv(pGCSrc)->pPixmap->refcnt++;
+
+        nxagentChangeClip(pGCDst, CT_PIXMAP, nxagentGCPriv(pGCSrc)->pPixmap, 0);
+      }
+      break;
+    case CT_PIXMAP:
+
+      #ifdef WARNING
+      fprintf(stderr, "nxagentCopyClip: WARNING! Not incrementing counter for virtual pixmap at [%p].\n",
+                  (void *) nxagentVirtualPixmap((PixmapPtr) pGCSrc->clientClip));
+      #endif
+
+      ((PixmapPtr) pGCSrc->clientClip)->refcnt++;
+
+      nxagentChangeClip(pGCDst, CT_PIXMAP, pGCSrc->clientClip, 0);
+
+      break;
+
+    case CT_NONE:
+      nxagentDestroyClip(pGCDst);
+      break;
+
+  }
+}
+
+static struct nxagentGCRec *nxagentGetFirstGC()
+{
+  struct nxagentGCRec *tmp = nxagentGCList.first;
+
+  if (nxagentGCList.size)
+  {
+    nxagentGCList.first = nxagentGCList.first -> next;
+    nxagentGCList.size--;
+
+    if (nxagentGCList.size == 0)
+    {
+      nxagentGCList.last = NULL;
+    }
+  }
+
+  return tmp;
+}
+
+static void nxagentFreeGCRec(struct nxagentGCRec *t)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentFreeGCRec: Freeing record at %p GC freed at %p.\n",
+              (void *) t, (void *) t -> gc);
+  #endif
+
+  xfree(t -> gc);
+
+  free(t);
+}
+
+static void nxagentRestoreGCRec(struct nxagentGCRec *t)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentRestoreGCRec: Freeing record at %p GC freed at %p.\n",
+              (void*)t, (void*)t -> gc);
+  #endif
+
+  if (nxagentGC(t -> pGC))
+  {
+    xfree(nxagentGC(t -> pGC));
+  }
+
+  nxagentGC(t -> pGC) = t -> gc;
+
+  free(t);
+}
+
+static void nxagentAddGCToList(GCPtr pGC)
+{
+  struct nxagentGCRec *tempGC = malloc(sizeof(struct nxagentGCRec));
+
+  if (tempGC == NULL)
+  {
+    FatalError("nxagentAddGCToList: malloc failed.");
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentAddGCToList: Adding GC %p to list at memory %p list size is %d.\n",
+              (void *) pGC, (void *) tempGC, nxagentGCList.size);
+  #endif
+
+  tempGC -> pGC = pGC;
+  tempGC -> gc = nxagentGC(pGC);
+  tempGC -> next = NULL;
+
+  if (nxagentGCList.size == 0 || nxagentGCList.first == NULL || nxagentGCList.last == NULL)
+  {
+    nxagentGCList.first = tempGC;
+  }
+  else
+  {
+    nxagentGCList.last -> next = tempGC;
+  }
+
+  nxagentGCList.last = tempGC;
+  nxagentGCList.size++;
+}
+
+void nxagentFreeGCList()
+{
+  struct nxagentGCRec *tempGC;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentFreeGCList: List size is %d first elt at %p last elt at %p.\n",
+              nxagentGCList.size, (void*)nxagentGCList.first, (void*)nxagentGCList.last);
+  #endif
+
+  while ((tempGC = nxagentGetFirstGC()))
+  {
+    nxagentFreeGCRec(tempGC);
+  }
+}
+
+static void nxagentRestoreGCList()
+{
+  struct nxagentGCRec *tempGC;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRestoreGCList: List size is %d first elt at %p last elt at %p.\n",
+              nxagentGCList.size, (void*)nxagentGCList.first, (void*)nxagentGCList.last);
+  #endif
+
+  while ((tempGC = nxagentGetFirstGC()))
+  {
+    nxagentRestoreGCRec(tempGC);
+  }
+}
+
+int nxagentDestroyNewGCResourceType(pointer p, XID id)
+{
+  /*
+   * Address of the destructor is set in Init.c.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyNewGCResourceType: Destroying mirror id [%ld] for GC at [%p].\n",
+              nxagentGCPriv((GCPtr) p) -> mid, (void *) p);
+  #endif
+
+  nxagentGCPriv((GCPtr) p) -> mid = None;
+
+  return 1;
+}
+
+static void nxagentReconnectGC(void *param0, XID param1, pointer param2)
+{
+  XGCValues values;
+  unsigned long valuemask;
+  GCPtr pGC = (GCPtr) param0;
+  Bool *pBool = (Bool*)param2;
+
+  if (pGC == NULL || !*pBool)
+  {
+    return;
+  }
+
+  if (nxagentGC(pGC))
+  {
+    nxagentAddGCToList(pGC);
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentReconnectGC: GCRec %p doesn't have a valid pointer to GC data.\n", (void*)pGC);
+    #endif
+  }
+
+  #ifdef DEBUG 
+  fprintf(stderr, "nxagentReconnectGC: GC at [%p].\n", (void *) pGC);
+  #endif
+
+  valuemask = 0;
+  memset(&values,0,sizeof(XGCValues));
+  values.function = pGC->alu;
+  valuemask |= GCFunction;
+  values.plane_mask = pGC->planemask;
+  valuemask |= GCPlaneMask;
+  values.foreground = nxagentPixel(pGC->fgPixel);
+  valuemask |= GCForeground;
+  values.background = nxagentPixel(pGC->bgPixel);
+  valuemask |= GCBackground;
+
+  values.line_width = pGC->lineWidth;
+  valuemask |= GCLineWidth;
+  values.line_style = pGC->lineStyle;
+  valuemask |= GCLineStyle;
+  values.cap_style = pGC->capStyle;
+  valuemask |= GCCapStyle;
+  values.join_style = pGC->joinStyle;
+  valuemask |= GCJoinStyle;
+  values.fill_style = pGC->fillStyle;
+  valuemask |= GCFillStyle;
+  values.fill_rule = pGC->fillRule;
+  valuemask |= GCFillRule;
+
+  if (!pGC -> tileIsPixel  && (pGC -> tile.pixmap != NULL))
+  {
+    if (nxagentPixmapIsVirtual(pGC -> tile.pixmap))
+    {
+      values.tile = nxagentPixmap(nxagentRealPixmap(pGC -> tile.pixmap));
+    }
+    else
+    {
+      values.tile = nxagentPixmap(pGC -> tile.pixmap);
+    }
+
+    valuemask |= GCTile;
+  }
+
+  if (pGC->stipple != NULL)
+  {
+    if (nxagentPixmapIsVirtual(pGC -> stipple))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentReconnectGC: Reconnecting virtual stipple [%p] for GC [%p].\n",
+                  (void *) pGC -> stipple, (void *) pGC);
+      #endif
+
+      if (nxagentPixmap(nxagentRealPixmap(pGC -> stipple)) == 0)
+      {
+        nxagentReconnectPixmap(nxagentRealPixmap(pGC -> stipple), 0, pBool);
+      }
+
+      values.stipple = nxagentPixmap(nxagentRealPixmap(pGC -> stipple));
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentReconnectGC: Reconnecting stipple [%p] for GC [%p].\n",
+                  (void *) pGC -> stipple, (void *) pGC);
+      #endif
+
+      if (nxagentPixmap(pGC -> stipple) == 0)
+      {
+        nxagentReconnectPixmap(pGC -> stipple, 0, pBool);
+      }
+
+      values.stipple = nxagentPixmap(pGC->stipple);
+    }
+    valuemask |= GCStipple;
+  }
+
+  values.ts_x_origin = pGC->patOrg.x;
+  valuemask |= GCTileStipXOrigin;
+  values.ts_y_origin = pGC->patOrg.y;
+  valuemask |= GCTileStipYOrigin;
+
+  if (pGC->font != NULL)
+  {
+    values.font = nxagentFont(pGC->font);
+    valuemask |= GCFont;
+  }
+
+  values.subwindow_mode = pGC->subWindowMode;
+  valuemask |= GCSubwindowMode;
+  values.graphics_exposures = pGC->graphicsExposures;
+  valuemask |= GCGraphicsExposures;
+  values.clip_x_origin = pGC->clipOrg.x;
+  valuemask |= GCClipXOrigin;
+  values.clip_y_origin = pGC->clipOrg.y;
+  valuemask |= GCClipYOrigin;
+  valuemask |= GCClipMask;
+  values.dash_offset = pGC->dashOffset;
+  valuemask |= GCDashOffset;
+
+  if (pGC->dash != NULL)
+  {
+    values.dashes = *pGC->dash;
+    valuemask |= GCDashList;
+  }
+
+  values.arc_mode = pGC->arcMode;
+  valuemask |= GCArcMode;
+
+  if ((nxagentGC(pGC) = XCreateGC(nxagentDisplay,
+                                  nxagentDefaultDrawables[pGC->depth],
+                                  valuemask, &values)) == NULL)
+  {
+    *pBool = False;
+  }
+
+  nxagentReconnectClip(pGC,
+                       pGC -> clientClipType,
+                       pGC -> clientClip, nxagentGCPriv(pGC) -> nClipRects);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+}
+
+Bool nxagentReconnectAllGCs(void *p0)
+{
+  int flexibility;
+  int cid;
+  Bool GCSuccess = True;
+
+  flexibility = *(int*)p0;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectAllGCs\n");
+  #endif
+
+  /*
+   * The resource type RT_NX_GC is created on the
+   * server client only, so we can avoid to loop
+   * through all the clients.
+   */
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_GC, nxagentReconnectGC, &GCSuccess);
+
+  for (cid = 0; (cid < MAXCLIENTS) && GCSuccess; cid++)
+  {
+    if (clients[cid])
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentReconnectAllGCs: Going to reconnect GC of client [%d].\n", cid);
+      #endif
+
+      FindClientResourcesByType(clients[cid], RT_GC, nxagentReconnectGC, &GCSuccess);
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectAllGCs: GCs reconnection completed.\n");
+  #endif
+
+  return GCSuccess;
+}
+
+void nxagentDisconnectGC(pointer p0, XID x1, pointer p2)
+{
+  GCPtr pGC = (GCPtr) p0;
+  Bool* pBool = (Bool*) p2;
+
+  if (!*pBool || !pGC)
+  {
+    if (!pGC) 
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentDisconnectGC: WARNING! pGC is NULL.\n");
+      #endif
+    }
+
+    return;
+  }
+
+  if (pGC -> stipple)
+  {
+    PixmapPtr pMap = pGC -> stipple;
+
+    nxagentDisconnectPixmap(nxagentRealPixmap(pMap), 0, pBool);
+  }
+} 
+
+Bool nxagentDisconnectAllGCs()
+{
+  int cid;
+  Bool success = True;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentDisconnectAllGCs\n");
+  #endif
+
+  /*
+   * The resource type RT_NX_GC is created on the
+   * server client only, so we can avoid to loop
+   * through all the clients.
+   */
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_GC,
+                                (FindResType) nxagentDisconnectGC, &success);
+
+  for (cid = 0; (cid < MAXCLIENTS) && success; cid++)
+  {
+    if (clients[cid])
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDisconnectAllGCs: Going to disconnect GC of client [%d].\n", cid);
+      #endif
+
+      FindClientResourcesByType(clients[cid], RT_GC,
+                                    (FindResType) nxagentDisconnectGC, &success);
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectAllGCs: GCs disconnection completed.\n");
+  #endif
+
+  nxagentRestoreGCList();
+
+  nxagentDisconnectGraphicContexts();
+
+  return success;
+}
+
+static void nxagentReconnectClip(GCPtr pGC, int type, pointer pValue, int nRects)
+{
+  int i, size;
+  BoxPtr pBox;
+  XRectangle *pRects;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectClip: going to change clip on GC [%p]\n",
+              (void *) pGC);
+  #endif
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectClip: Type is [%s].\n", (type == CT_NONE) ?
+              "CT_NONE" : (type == CT_REGION) ? "CT_REGION" : (type == CT_PIXMAP) ?
+                  "CT_REGION" : "UNKNOWN");
+  #endif
+
+  switch(type)
+    {
+    case CT_NONE:
+      XSetClipMask(nxagentDisplay, nxagentGC(pGC), None);
+      break;
+
+    case CT_REGION:
+      if (nxagentGCPriv(pGC)->pPixmap == NULL)
+      {
+        nRects = REGION_NUM_RECTS((RegionPtr)pValue);
+        size = nRects * sizeof(*pRects);
+        pRects = (XRectangle *) xalloc(size);
+        pBox = REGION_RECTS((RegionPtr)pValue);
+        for (i = nRects; i-- > 0;) {
+          pRects[i].x = pBox[i].x1;
+          pRects[i].y = pBox[i].y1;
+          pRects[i].width = pBox[i].x2 - pBox[i].x1;
+          pRects[i].height = pBox[i].y2 - pBox[i].y1;
+        }
+
+        /*
+         * Originally, the clip origin area were 0,0 
+         * but it didn't work with kedit and family,
+         * because it got the clip mask of the pixmap
+         * all traslated.
+         */
+
+        XSetClipRectangles(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y,
+                           pRects, nRects, Unsorted);
+        xfree((char *) pRects);
+      }
+      else
+      {
+        XSetClipMask(nxagentDisplay, nxagentGC(pGC),
+                         nxagentPixmap(nxagentGCPriv(pGC)->pPixmap));
+
+        XSetClipOrigin(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y);
+      }
+
+      break;
+
+    case CT_PIXMAP:
+
+      XSetClipMask(nxagentDisplay, nxagentGC(pGC),
+                       nxagentPixmap((PixmapPtr)pValue));
+
+      XSetClipOrigin(nxagentDisplay, nxagentGC(pGC), pGC -> clipOrg.x, pGC -> clipOrg.y);
+
+      pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr) pValue);
+
+      nxagentGCPriv(pGC)->pPixmap = (PixmapPtr)pValue;
+
+      pValue = pGC->clientClip;
+
+      type = CT_REGION;
+
+      break;
+
+    case CT_UNSORTED:
+      XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                         pGC->clipOrg.x, pGC->clipOrg.y,
+                         (XRectangle *)pValue, nRects, Unsorted);
+      break;
+
+    case CT_YSORTED:
+      XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                         pGC->clipOrg.x, pGC->clipOrg.y,
+                         (XRectangle *)pValue, nRects, YSorted);
+      break;
+
+    case CT_YXSORTED:
+      XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                         pGC->clipOrg.x, pGC->clipOrg.y,
+                         (XRectangle *)pValue, nRects, YXSorted);
+      break;
+
+    case CT_YXBANDED:
+      XSetClipRectangles(nxagentDisplay, nxagentGC(pGC),
+                         pGC->clipOrg.x, pGC->clipOrg.y,
+                         (XRectangle *)pValue, nRects, YXBanded);
+      break;
+    }
+
+  switch(type)
+    {
+    default:
+      break;
+
+    case CT_UNSORTED:
+    case CT_YSORTED:
+    case CT_YXSORTED:
+    case CT_YXBANDED:
+
+      /*
+       * other parts of server can only deal with CT_NONE,
+       * CT_PIXMAP and CT_REGION client clips.
+       */
+
+      pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nRects,
+                                                  (xRectangle *)pValue, type);
+      xfree(pValue);
+      pValue = pGC->clientClip;
+      type = CT_REGION;
+
+      break;
+    }
+
+  pGC->clientClipType = type;
+  pGC->clientClip = pValue;
+
+ nxagentGCPriv(pGC)->nClipRects = nRects;
+}
+
+static int nxagentCompareRegions(RegionPtr r1, RegionPtr r2)
+{
+  int i;
+
+ /*
+  *  It returns 1 if regions are equal, 0 otherwise
+  */
+
+  if (r1 == NULL && r2 == NULL)
+  {
+    return 1;
+  }
+
+  if ((r1 == NULL) || (r2 == NULL))
+  {
+    return 0;
+  }
+
+  if (REGION_NUM_RECTS(r1) !=  REGION_NUM_RECTS(r2))
+  {
+    return 0;
+  }
+  else if (REGION_NUM_RECTS(r1) == 0)
+  {
+    return 1;
+  }
+  else if ((*REGION_EXTENTS(pScreen, r1)).x1 !=  (*REGION_EXTENTS(pScreen, r2)).x1) return 0;
+  else if ((*REGION_EXTENTS(pScreen, r1)).x2 !=  (*REGION_EXTENTS(pScreen, r2)).x2) return 0;
+  else if ((*REGION_EXTENTS(pScreen, r1)).y1 !=  (*REGION_EXTENTS(pScreen, r2)).y1) return 0;
+  else if ((*REGION_EXTENTS(pScreen, r1)).y2 !=  (*REGION_EXTENTS(pScreen, r2)).y2) return 0;
+  else
+  {
+    for (i = 0; i < REGION_NUM_RECTS(r1); i++)
+    {
+      if (REGION_RECTS(r1)[i].x1 !=  REGION_RECTS(r2)[i].x1) return 0;
+      else if (REGION_RECTS(r1)[i].x2 !=  REGION_RECTS(r2)[i].x2) return 0;
+      else if (REGION_RECTS(r1)[i].y1 !=  REGION_RECTS(r2)[i].y1) return 0;
+      else if (REGION_RECTS(r1)[i].y2 !=  REGION_RECTS(r2)[i].y2) return 0;
+    }
+  }
+
+  return 1;
+}
+
+/*
+ * This function have to be called in the place
+ * of GetScratchGC if the GC will be used to per-
+ * form operations also on the remote X Server.
+ * This is why we call the XChangeGC at the end of
+ * the function.
+ */
+GCPtr nxagentGetScratchGC(unsigned depth, ScreenPtr pScreen)
+{
+  GCPtr pGC;
+  XGCValues values;
+  unsigned long mask;
+  int nxagentSaveGCTrap;
+
+  /*
+   * The GC trap is temporarily disabled in
+   * order to allow the remote clipmask reset
+   * requested by GetScratchGC().
+   */
+
+  nxagentSaveGCTrap = nxagentGCTrap;
+
+  nxagentGCTrap = 0;
+
+  pGC = GetScratchGC(depth, pScreen);
+
+  nxagentGCTrap = nxagentSaveGCTrap;
+
+  if (pGC == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentGetScratchGC: Failed to retrieve the scratch GC.\n");
+    #endif
+
+    return NULL;
+  }
+
+  mask = 0;
+
+  values.function = pGC -> alu;
+  mask |= GCFunction;
+
+  values.plane_mask = pGC -> planemask;
+  mask |= GCPlaneMask;
+
+  values.foreground = nxagentPixel(pGC -> fgPixel);
+  mask |= GCForeground;
+
+  values.background = nxagentPixel(pGC -> bgPixel);
+  mask |= GCBackground;
+
+  values.line_width = pGC -> lineWidth;
+  mask |= GCLineWidth;
+
+  values.line_style = pGC -> lineStyle;
+  mask |= GCLineStyle;
+
+  values.cap_style = pGC -> capStyle;
+  mask |= GCCapStyle;
+
+  values.join_style = pGC -> joinStyle;
+  mask |= GCJoinStyle;
+
+  values.fill_style = pGC -> fillStyle;
+  mask |= GCFillStyle;
+
+  values.fill_rule = pGC -> fillRule;
+  mask |= GCFillRule;
+
+  values.arc_mode = pGC -> arcMode;
+  mask |= GCArcMode;
+
+  values.ts_x_origin = pGC -> patOrg.x;
+  mask |= GCTileStipXOrigin;
+
+  values.ts_y_origin = pGC -> patOrg.y;
+  mask |= GCTileStipYOrigin;
+
+  values.subwindow_mode = pGC -> subWindowMode;
+  mask |= GCSubwindowMode;
+
+  values.graphics_exposures = pGC -> graphicsExposures;
+  mask |= GCGraphicsExposures;
+
+  /*
+   * The GCClipMask is set to none inside
+   * the GetScratchGC() function.
+   */
+
+  values.clip_x_origin = pGC -> clipOrg.x;
+  mask |= GCClipXOrigin;
+
+  values.clip_y_origin = pGC -> clipOrg.y;
+  mask |= GCClipYOrigin;
+
+  XChangeGC(nxagentDisplay, nxagentGC(pGC), mask, &values);
+
+  memset(&(nxagentGCPriv(pGC) -> lastServerValues), 0, sizeof(XGCValues));
+
+  return pGC;
+}
+
+/*
+ * This function is only a wrapper for
+ * FreeScratchGC.
+ */
+void nxagentFreeScratchGC(GCPtr pGC)
+{
+  if (pGC == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFreeScratchGC: WARNING! pGC is NULL.\n");
+    #endif
+
+    return;
+  }
+
+  FreeScratchGC(pGC);
+}
+
+/*
+ * The GCs belonging to this list are used
+ * only in the synchronization put images,
+ * to be sure they preserve the default va-
+ * lues and to avoid XChangeGC() requests.
+ */
+
+GCPtr nxagentGetGraphicContext(DrawablePtr pDrawable)
+{
+  int i;
+  int result;
+
+  for (i = 0; i < nxagentGraphicContextsSize; i++)
+  {
+    if (pDrawable -> depth == nxagentGraphicContexts[i].depth)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentGetGraphicContext: Found a valid GC at [%p] for depth [%d].\n",
+                  (void *) nxagentGraphicContexts[i].pGC, pDrawable -> depth);
+      #endif
+
+      /*
+       * Reconnect the GC if needed.
+       */
+
+      if (nxagentGraphicContexts[i].dirty == 1)
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentGetGraphicContext: Going to reconnect the GC.\n");
+        #endif
+
+        result = 1;
+
+        nxagentReconnectGC(nxagentGraphicContexts[i].pGC, (XID) 0, &result);
+
+        if (result == 0)
+        {
+          #ifdef WARNING
+          fprintf(stderr, "nxagentGetGraphicContext: WARNING! Failed to reconnect the GC.\n");
+          #endif
+
+          return NULL;
+        }
+
+        nxagentGraphicContexts[i].dirty = 0;
+      }
+
+      return nxagentGraphicContexts[i].pGC;
+    }
+  }
+
+  return nxagentCreateGraphicContext(pDrawable -> depth);
+}
+
+GCPtr nxagentCreateGraphicContext(int depth)
+{
+  GCPtr pGC;
+
+  nxagentGraphicContextsPtr nxagentGCs;
+
+  XID attributes[2];
+
+  /*
+   * We have not found a GC, so we have
+   * to spread the list and add a new GC.
+   */
+
+  nxagentGCs = xrealloc(nxagentGraphicContexts, (nxagentGraphicContextsSize + 1) * sizeof(nxagentGraphicContextsRec));
+   
+  if (nxagentGCs == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreateGraphicContext: Cannot allocate memory for a GC.\n");
+    #endif
+
+    return NULL;
+  }
+
+  nxagentGraphicContexts = nxagentGCs;
+
+  pGC = CreateScratchGC(nxagentDefaultScreen, depth);
+
+  if (pGC == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreateGraphicContext: Failed to create a GC for depth [%d].\n",
+                depth);
+    #endif
+
+    return NULL;
+  }
+
+  /*
+   * Color used in nxagentFillRemoteRegion().
+   */
+
+  attributes[0] = 0xc1c1c1;
+
+  if (depth == 15 || depth == 16)
+  {
+    Color32to16(attributes[0]);
+  }
+
+  /*
+   * The IncludeInferiors property is useful to
+   * solve problems when synchronizing windows
+   * covered by an invisible child.
+   */
+
+  attributes[1] = IncludeInferiors;
+
+  ChangeGC(pGC, GCForeground | GCSubwindowMode, attributes);
+
+  nxagentGraphicContexts[nxagentGraphicContextsSize].pGC   = pGC;
+  nxagentGraphicContexts[nxagentGraphicContextsSize].depth = depth;
+  nxagentGraphicContexts[nxagentGraphicContextsSize].dirty = 0;
+
+  nxagentGraphicContextsSize++;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentCreateGraphicContext: GC [%p] for depth [%d] added to the list of size [%d].\n",
+              (void *) pGC, depth, nxagentGraphicContextsSize);
+  #endif
+
+  return pGC;
+}
+
+/*
+ * This initialization is called in the InitOutput()
+ * function immediately after opening the screen,
+ * which is used to create the GCs. 
+ */
+
+void nxagentAllocateGraphicContexts(void)
+{
+  int *depths;
+
+  int i;
+
+  depths = nxagentDepths;
+
+  for (i = 0; i < nxagentNumDepths; i++)
+  {
+    nxagentCreateGraphicContext(*depths);
+
+    depths++;
+  }
+}
+
+void nxagentDisconnectGraphicContexts(void)
+{
+  int i;
+
+  for (i = 0; i < nxagentGraphicContextsSize; i++)
+  {
+    nxagentGraphicContexts[i].dirty = 1;
+  }
+
+  return;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
new file mode 100644
index 000000000..7a6432a8e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -0,0 +1,1995 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Composite.h"
+#include "Display.h"
+#include "Visual.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+#include "Image.h"
+#include "Font.h"
+#include "Events.h"
+#include "Client.h"
+#include "Trap.h"
+#include "Holder.h"
+#include "Args.h"
+#include "Screen.h"
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+/*
+ * Temporarily set/reset the trap.
+ */
+
+static int nxagentSaveGCTrap;
+
+#define SET_GC_TRAP() \
+{ \
+  nxagentSaveGCTrap = nxagentGCTrap;\
+\
+  nxagentGCTrap = 1; \
+}
+
+#define RESET_GC_TRAP() \
+{ \
+  nxagentGCTrap = nxagentSaveGCTrap; \
+}
+ 
+/*
+ * This is currently unused.
+ */
+
+RegionPtr nxagentBitBlitHelper(GC *pGC);
+
+/*
+ * The NX agent implementation of the
+ * X server's graphics functions.
+ */
+
+void nxagentFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans,
+                          xPoint *pPoints, int *pWidths, int fSorted)
+{
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to FillSpans on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    fbFillSpans(nxagentVirtualDrawable(pDrawable), pGC, nSpans, pPoints, pWidths, fSorted);
+  }
+  else
+  {
+    fbFillSpans(pDrawable, pGC, nSpans, pPoints, pWidths, fSorted);
+  }
+}
+
+void nxagentSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc,
+                         xPoint *pPoints, int *pWidths, int nSpans, int fSorted)
+{
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to SetSpans on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    fbSetSpans(nxagentVirtualDrawable(pDrawable), pGC, pSrc, pPoints, pWidths, nSpans, fSorted);
+  }
+  else
+  {
+    fbSetSpans(pDrawable, pGC, pSrc, pPoints, pWidths, nSpans, fSorted);
+  } 
+}
+
+void nxagentGetSpans(DrawablePtr pDrawable, int maxWidth, xPoint *pPoints,
+                         int *pWidths, int nSpans, char *pBuffer)
+{
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: going to GetSpans on FB pixmap [%p].\n",
+                (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    fbGetSpans(nxagentVirtualDrawable(pDrawable), maxWidth, pPoints, pWidths, nSpans, pBuffer);
+  }
+  else
+  {
+    fbGetSpans(pDrawable, maxWidth, pPoints, pWidths, nSpans, pBuffer);
+  }
+}
+
+void nxagentQueryBestSize(int class, unsigned short *pwidth,
+                              unsigned short *pheight, ScreenPtr pScreen)
+{
+  unsigned width, test;
+
+  switch(class)
+  {
+    case CursorShape:
+      if (*pwidth > pScreen->width)
+        *pwidth = pScreen->width;
+      if (*pheight > pScreen->height)
+        *pheight = pScreen->height;
+      break;
+    case TileShape:
+    case StippleShape:
+      width = *pwidth;
+      if (!width) break;
+      /* Return the closes power of two not less than what they gave me */
+      test = 0x80000000;
+      /* Find the highest 1 bit in the width given */
+      while(!(test & width))
+         test >>= 1;
+      /* If their number is greater than that, bump up to the next
+       *  power of two */
+      if((test - 1) & width)
+         test <<= 1;
+      *pwidth = test;
+      /* We don't care what height they use */
+      break;
+  }
+}
+
+RegionPtr nxagentBitBlitHelper(GC *pGC)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentBitBlitHelper: Called for GC at [%p].\n", (void *) pGC);
+  #endif
+
+  /*
+   * Force NullRegion. We consider enough the graphics
+   * expose events generated internally by the nxagent
+   * server.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentBitBlitHelper: WARNING! Skipping check on exposures events.\n");
+  #endif
+
+  return NullRegion;
+}
+
+/*
+ * The deferring of X_RenderCompositeTrapezoids caused
+ * an ugly effect on pulldown menu: as the background
+ * may be not synchronized, the text floats in an invi-
+ * sible window. To avoid such effects, we use a system
+ * to guess if the destination target of a copy area
+ * is a popup, by assuming that those kind of windows
+ * use the override redirect property.
+ */
+
+int nxagentWindowIsPopup(DrawablePtr pDrawable)
+{
+  WindowPtr parent;
+
+  int windowIsPopup;
+  int level;
+
+  if (pDrawable -> type != DRAWABLE_WINDOW)
+  {
+    return 0;
+  }
+
+  windowIsPopup = 0;
+
+  if (((WindowPtr) pDrawable) -> overrideRedirect == 1)
+  {
+    windowIsPopup = 1;
+  }
+  else
+  {
+    parent = ((WindowPtr) pDrawable) -> parent;
+
+    /*
+     * Go up on the tree until a parent
+     * exists or 4 windows has been che-
+     * cked. This seems a good limit to
+     * up children's popup.
+     */
+
+    level = 0;
+
+    while (parent != NULL && ++level <= 4)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentWindowIsPopup: Window [%p] has parent [%p] in tree with OverrideRedirect [%d] "
+                  " Level [%d].\n", (void *) pDrawable, (void *) parent, parent -> overrideRedirect, level);
+      #endif
+
+      if (parent -> overrideRedirect == 1)
+      {
+        windowIsPopup = 1;
+
+        break;
+      }
+
+      parent = parent -> parent;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentWindowIsPopup: Window [%p] %s to be a popup.\n", (void *) pDrawable,
+              windowIsPopup == 1 ? "seems" : "does not seem");
+  #endif
+
+  return windowIsPopup;
+}
+
+/*
+ * This function returns 1 if the
+ * XCopyArea request must be skipped.
+ */
+
+int nxagentDeferCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+                            GCPtr pGC, int srcx, int srcy, int width,
+                                int height, int dstx, int dsty)
+{
+  RegionPtr pSrcRegion;
+  RegionPtr pClipRegion, pCorruptedRegion;
+  RegionRec corruptedRegion, tmpRegion;
+
+  /*
+   * If the destination drawable is a popup
+   * window, we try to synchronize the source
+   * drawable to show a nice menu. Anyway if
+   * this synchronization breaks, the copy area
+   * is handled in the normal way.
+   */
+
+/*
+FIXME: The popup could be synchronized with one
+       single put image, clipped to the corrup-
+       ted region. As an intermediate step, the
+       pixmap to synchronize could be copied on
+       a cleared scratch pixmap, in order to
+       have a solid color in the clipped regions.
+*/
+
+  if (nxagentOption(DeferLevel) >= 2 &&
+          pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+              nxagentPixmapContainTrapezoids((PixmapPtr) pSrcDrawable) == 1 &&
+                  nxagentWindowIsPopup(pDstDrawable) == 1)
+  {
+    pSrcRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy, width, height);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDeferCopyArea: Copying to a popup menu. Source region [%d,%d,%d,%d].\n",
+                pSrcRegion -> extents.x1, pSrcRegion -> extents.y1,
+                    pSrcRegion -> extents.x2, pSrcRegion -> extents.y2);
+    #endif
+
+    REGION_INIT(pSrcDrawable -> pScreen, &corruptedRegion, NullBox, 1);
+
+    REGION_INTERSECT(pSrcDrawable -> pScreen, &corruptedRegion,
+                         pSrcRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+    if (REGION_NIL(&corruptedRegion) == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDeferCopyArea: Forcing the synchronization of source drawable at [%p].\n",
+                  (void *) pSrcDrawable);
+      #endif
+
+      nxagentSynchronizeRegion(pSrcDrawable, &corruptedRegion, EVENT_BREAK, NULL);
+    }
+
+    REGION_UNINIT(pSrcDrawable -> pScreen, &corruptedRegion);
+
+    nxagentFreeRegion(pSrcDrawable, pSrcRegion);
+
+    if (nxagentDrawableStatus(pSrcDrawable) == Synchronized)
+    {
+      return 0;
+    }
+  }
+
+  /*
+   * We are going to decide if the source drawable
+   * must be synchronized before using it, or if
+   * the copy will be clipped to the synchronized
+   * source region.
+   */
+
+  if ((pDstDrawable -> type == DRAWABLE_PIXMAP &&
+          nxagentOption(DeferLevel) > 0) || nxagentOption(DeferLevel) >= 2)
+  {
+    pClipRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy,
+                                          width, height);
+
+    /*
+     * We called this variable pCorruptedRegion
+     * because in the worst case the corrupted
+     * region will be equal to the destination
+     * region. The GC's clip mask is used to
+     * narrow the destination.
+     */
+
+    pCorruptedRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty,
+                                               width, height);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDeferCopyArea: Copy area source region is [%d,%d,%d,%d].\n",
+                pClipRegion -> extents.x1, pClipRegion -> extents.y1,
+                    pClipRegion -> extents.x2, pClipRegion -> extents.y2);
+    #endif
+
+    REGION_SUBTRACT(pSrcDrawable -> pScreen, pClipRegion, pClipRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDeferCopyArea: Usable copy area source region is [%d,%d,%d,%d].\n",
+                pClipRegion -> extents.x1, pClipRegion -> extents.y1,
+                    pClipRegion -> extents.x2, pClipRegion -> extents.y2);
+    #endif
+
+    if (pGC -> clientClip == NULL || pGC -> clientClipType != CT_REGION)
+    {
+      #ifdef WARNING
+
+      if (pGC -> clientClipType != CT_NONE)
+      {
+        fprintf(stderr, "nxagentDeferCopyArea: WARNING! pGC [%p] has a clip type [%d].\n",
+                    (void *) pGC, pGC -> clientClipType);
+      }
+
+      #endif
+
+      REGION_TRANSLATE(pSrcDrawable -> pScreen, pClipRegion, dstx - srcx, dsty - srcy);
+    }
+    else
+    {
+      REGION_INIT(pDstDrawable -> pScreen, &tmpRegion, NullBox, 1);
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentDeferCopyArea: Going to modify the original GC [%p] with clip mask "
+                  "[%d,%d,%d,%d] and origin [%d,%d].\n",
+                      (void *) pGC,
+                      ((RegionPtr) pGC -> clientClip) -> extents.x1, ((RegionPtr) pGC -> clientClip) -> extents.y1,
+                      ((RegionPtr) pGC -> clientClip) -> extents.x2, ((RegionPtr) pGC -> clientClip) -> extents.y2,
+                      pGC -> clipOrg.x, pGC -> clipOrg.y);
+      #endif
+
+      REGION_COPY(pDstDrawable -> pScreen, &tmpRegion, (RegionPtr) pGC -> clientClip);
+
+      if (pGC -> clipOrg.x != 0 || pGC -> clipOrg.y != 0)
+      {
+        REGION_TRANSLATE(pDstDrawable -> pScreen, &tmpRegion, pGC -> clipOrg.x, pGC -> clipOrg.y);
+      }
+
+      REGION_TRANSLATE(pSrcDrawable -> pScreen, pClipRegion, dstx - srcx, dsty - srcy);
+
+      REGION_INTERSECT(pSrcDrawable -> pScreen, pClipRegion, &tmpRegion, pClipRegion);
+
+      REGION_UNINIT(pSrcDrawable -> pScreen, &tmpRegion);
+    }
+
+    /*
+     * The corrupted region on the destination
+     * drawable is composed by the areas of the
+     * destination that we are not going to copy.
+     */
+
+    REGION_SUBTRACT(pSrcDrawable -> pScreen, pCorruptedRegion, pCorruptedRegion, pClipRegion);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDeferCopyArea: Recomputed clip region is [%d,%d,%d,%d][%ld].\n",
+                pClipRegion -> extents.x1, pClipRegion -> extents.y1,
+                    pClipRegion -> extents.x2, pClipRegion -> extents.y2,
+                        REGION_NUM_RECTS(pClipRegion));
+
+    fprintf(stderr, "nxagentDeferCopyArea: Inherited corrupted region is [%d,%d,%d,%d][%ld].\n",
+                pCorruptedRegion -> extents.x1, pCorruptedRegion -> extents.y1,
+                    pCorruptedRegion -> extents.x2, pCorruptedRegion -> extents.y2,
+                        REGION_NUM_RECTS(pCorruptedRegion));
+    #endif
+
+    /*
+     * The destination drawable inherits both the
+     * synchronized and the corrupted region.
+     */
+
+    if (REGION_NIL(pClipRegion) == 0)
+    {
+      nxagentUnmarkCorruptedRegion(pDstDrawable, pClipRegion);
+    }
+
+    if (REGION_NIL(pCorruptedRegion) == 0)
+    {
+      nxagentMarkCorruptedRegion(pDstDrawable, pCorruptedRegion);
+    }
+
+    if (REGION_NIL(pClipRegion) == 0)
+    {
+      GCPtr  targetGC;
+
+      CARD32 targetAttributes[2];
+
+      /*
+       * As we want to copy only the synchronized
+       * areas of the source drawable, we create
+       * a new GC copying the original one and
+       * setting a new clip mask.
+       */
+
+      targetGC = GetScratchGC(pDstDrawable -> depth, pDstDrawable -> pScreen);
+
+      ValidateGC(pDstDrawable, targetGC);
+
+      CopyGC(pGC, targetGC, GCFunction | GCPlaneMask | GCSubwindowMode |
+                 GCClipXOrigin | GCClipYOrigin | GCClipMask | GCForeground |
+                     GCBackground | GCGraphicsExposures);
+
+      if (REGION_NUM_RECTS(pClipRegion) == 1)
+      {
+        /*
+         * If the region to copy is formed by one
+         * rectangle, we change only the copy coor-
+         * dinates.
+         */
+
+         srcx = srcx + pClipRegion -> extents.x1 - dstx;
+         srcy = srcy + pClipRegion -> extents.y1 - dsty;
+
+         dstx = pClipRegion -> extents.x1;
+         dsty = pClipRegion -> extents.y1;
+
+         width  = pClipRegion -> extents.x2 - pClipRegion -> extents.x1;
+         height = pClipRegion -> extents.y2 - pClipRegion -> extents.y1;
+      }
+      else
+      {
+        /*
+         * Setting the clip mask origin. This
+         * operation must precede the clip chan-
+         * ge, because the origin information is
+         * used in the XSetClipRectangles().
+         */
+
+        targetAttributes[0] = 0;
+        targetAttributes[1] = 0;
+
+        ChangeGC(targetGC, GCClipXOrigin | GCClipYOrigin, targetAttributes);
+
+        /*
+         * Setting the new clip mask.
+         */
+
+        nxagentChangeClip(targetGC, CT_REGION, pClipRegion, 0);
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDeferCopyArea: Going to execute a copy area with clip mask "
+                    "[%d,%d,%d,%d] and origin [%d,%d].\n", ((RegionPtr) targetGC -> clientClip) -> extents.x1,
+                        ((RegionPtr) targetGC -> clientClip) -> extents.y1,
+                            ((RegionPtr) targetGC -> clientClip) -> extents.x2,
+                                ((RegionPtr) targetGC -> clientClip) -> extents.y2,
+                                    targetGC -> clipOrg.x, targetGC -> clipOrg.y);
+        #endif
+      }
+
+      XCopyArea(nxagentDisplay, nxagentDrawable(pSrcDrawable), nxagentDrawable(pDstDrawable),
+                    nxagentGC(targetGC), srcx, srcy, width, height, dstx, dsty);
+
+      nxagentChangeClip(targetGC, CT_NONE, NullRegion, 0);
+
+      FreeScratchGC(targetGC);
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDeferCopyArea: The clipped region is NIL. CopyArea skipped.\n");
+      #endif
+
+      /*
+       * The pClipRegion is destroyed calling nxagentChangeClip(),
+       * so we deallocate it explicitly only if we don't change
+       * the clip.
+       */
+
+      nxagentFreeRegion(pSrcDrawable, pClipRegion);
+    }
+
+    nxagentFreeRegion(pSrcDrawable, pCorruptedRegion);
+
+    return 1;
+  }
+  else
+  {
+    pSrcRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy, width, height);
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDeferCopyArea: Source region [%d,%d,%d,%d].\n",
+                pSrcRegion -> extents.x1, pSrcRegion -> extents.y1,
+                    pSrcRegion -> extents.x2, pSrcRegion -> extents.y2);
+    #endif
+
+    REGION_INIT(pSrcDrawable -> pScreen, &corruptedRegion, NullBox, 1);
+
+    REGION_INTERSECT(pSrcDrawable -> pScreen, &corruptedRegion,
+                         pSrcRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+    if (REGION_NIL(&corruptedRegion) == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDeferCopyArea: Forcing the synchronization of source drawable at [%p].\n",
+                  (void *) pSrcDrawable);
+      #endif
+
+      nxagentSynchronizeRegion(pSrcDrawable, &corruptedRegion /*pSrcRegion*/, NEVER_BREAK, NULL);
+    }
+
+    REGION_UNINIT(pSrcDrawable -> pScreen, &corruptedRegion);
+
+    nxagentFreeRegion(pSrcDrawable, pSrcRegion);
+  }
+
+  return 0;
+}
+
+RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+                               GCPtr pGC, int srcx, int srcy, int width,
+                                   int height, int dstx, int dsty)
+{
+  int leftPad = 0;
+  unsigned int format;
+  unsigned long planeMask = 0xffffffff;
+
+  RegionPtr pDstRegion;
+
+  int skip = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCopyArea: Image src [%s:%p], dst [%s:%p] (%d,%d) -> (%d,%d) size (%d,%d)\n",
+              (pSrcDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW", (void *) pSrcDrawable,
+                      (pDstDrawable -> type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW", 
+                          (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
+  #endif
+
+  if (nxagentGCTrap == 1 || nxagentShmTrap == 1)
+  {
+    if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+            pDstDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable), 
+                          nxagentVirtualDrawable(pDstDrawable),
+                            pGC, srcx, srcy, width, height, dstx, dsty);
+    }
+    else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable,
+                            pGC, srcx, srcy, width, height, dstx, dsty);
+    }
+    else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      return fbCopyArea(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable),
+                            pGC, srcx, srcy, width, height, dstx, dsty);
+    }
+    else
+    {
+      return fbCopyArea(pSrcDrawable, pDstDrawable,
+                            pGC, srcx, srcy, width, height, dstx, dsty);
+    }
+
+    return NullRegion;
+  }
+
+  /*
+   * Try to detect if the copy area is to a window
+   * that is unmapped or fully covered. Similarly
+   * to the check in Image.c, this is of little use.
+   */
+
+  if (nxagentOption(IgnoreVisibility) == 0 && pDstDrawable -> type == DRAWABLE_WINDOW &&
+          (nxagentWindowIsVisible((WindowPtr) pDstDrawable) == 0 ||
+              (nxagentDefaultWindowIsVisible() == 0 && nxagentCompositeEnable == 0)))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCopyArea: Prevented operation on fully obscured window at [%p].\n",
+                (void *) pDstDrawable);
+    #endif
+
+    return NullRegion;
+  }
+
+  /*
+   * If the pixmap is on shared memory, we can't
+   * know if the pixmap content is changed and
+   * so have to translate the operation in a put
+   * image operation. This can seriously affect
+   * the performance.
+   */
+
+  if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+         nxagentIsShmPixmap((PixmapPtr) pSrcDrawable))
+  {
+    char *data;
+    int depth, length;
+
+    depth  = pSrcDrawable -> depth;
+
+    format = (depth == 1) ? XYPixmap : ZPixmap;
+
+    length = nxagentImageLength(width, height, format, leftPad, depth);
+
+    if ((data = xalloc(length)) == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentCopyArea: WARNING! Failed to allocate memory for the operation.\n");
+      #endif
+
+      return NullRegion;
+    }
+
+    fbGetImage(nxagentVirtualDrawable(pSrcDrawable), srcx, srcy, width, height, format, planeMask, data);
+
+    /*
+     * If the source is a shared memory pixmap,
+     * put the image directly to the destination.
+     */
+
+    nxagentPutImage(pDstDrawable, pGC, depth, dstx, dsty,
+                        width, height, leftPad, format, data);
+
+    #ifdef TEST
+    fprintf(stderr,"nxagentCopyArea: Realize Pixmap %p virtual %p x %d y %d w %d h %d\n",
+               (void *) pSrcDrawable, (void *) nxagentVirtualDrawable(pSrcDrawable),
+                   srcx, srcy, width, height);
+    #endif
+
+    xfree(data);
+
+    /*
+     * If the source is a shared memory pixmap, the
+     * content of the framebuffer has been placed
+     * directly on the destination so we can skip
+     * the copy area operation.
+     */
+
+    skip = 1;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCopyArea: Image src [%s:%p], dst [%s:%p] sx %d sy %d dx %d dy %d size w %d h %d\n",
+              ((pSrcDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW", (void *) pSrcDrawable,
+                   ((pDstDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+                       (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
+  #endif
+
+  if (skip == 0 && nxagentDrawableStatus(pSrcDrawable) == NotSynchronized)
+  {
+    skip = nxagentDeferCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
+                                   width, height, dstx, dsty);
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentCopyArea: Source drawable at [%p] already synchronized.\n",
+                (void *) pSrcDrawable);
+  }
+  #endif
+
+  if (skip == 0)
+  {
+    XCopyArea(nxagentDisplay, nxagentDrawable(pSrcDrawable), nxagentDrawable(pDstDrawable),
+                  nxagentGC(pGC), srcx, srcy, width, height, dstx, dsty);
+
+    /*
+     * The copy area restored the synchroni-
+     * zation status of destination drawable.
+     */
+
+    if (nxagentDrawableStatus(pDstDrawable) == NotSynchronized)
+    {
+      pDstRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty, width, height);
+
+      nxagentUnmarkCorruptedRegion(pDstDrawable, pDstRegion);
+
+      nxagentFreeRegion(pDstDrawable, pDstRegion);
+    }
+  }
+
+  if (nxagentDrawableContainGlyphs(pSrcDrawable) == 1)
+  {
+    nxagentSetDrawableContainGlyphs(pDstDrawable, 1);
+  }
+
+  if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    nxagentIncreasePixmapUsageCounter((PixmapPtr) pSrcDrawable);
+  }
+
+  if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+          pDstDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCopyArea: Going to copy area from virtual pixmap [%p] to [%p]\n",
+                (void *) nxagentVirtualDrawable(pSrcDrawable),
+                    (void *) nxagentVirtualDrawable(pDstDrawable));
+    #endif
+
+    return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable), 
+                          nxagentVirtualDrawable(pDstDrawable),
+                              pGC, srcx, srcy, width, height, dstx, dsty);
+  }
+  else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCopyArea: Going to copy area from virtual pixmap [%p] to window [%p]\n",
+                (void *) nxagentVirtualDrawable(pSrcDrawable),
+                    (void *) pDstDrawable);
+    #endif
+
+    return fbCopyArea(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable,
+                          pGC, srcx, srcy, width, height, dstx, dsty);
+  }
+  else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    /*
+     * If we are here the source drawable
+     * must be a window.
+     */
+
+    if (((WindowPtr) pSrcDrawable) -> viewable)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Going to copy area from window [%p] to virtual pixmap [%p]\n",
+                  (void *) pSrcDrawable, (void *) nxagentVirtualDrawable(pDstDrawable));
+      #endif
+
+      return fbCopyArea(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable),
+                            pGC, srcx, srcy, width, height, dstx, dsty);
+    }
+  }
+  else
+  {
+    /*
+     * If we are here the source drawable
+     * must be a window.
+     */
+
+    if (((WindowPtr) pSrcDrawable) -> viewable)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Going to copy area from window [%p] to window [%p]\n",
+                  (void *) pSrcDrawable, (void *) pDstDrawable);
+      #endif
+
+      return fbCopyArea(pSrcDrawable, pDstDrawable,
+                            pGC, srcx, srcy, width, height, dstx, dsty);
+    }
+  }
+
+  return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, 
+                               srcx, srcy, width, height, dstx, dsty, 0);
+}
+
+RegionPtr nxagentCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+                               GCPtr pGC, int srcx, int srcy, int width, int height,
+                                   int dstx, int dsty, unsigned long plane)
+{
+  unsigned int format;
+  int leftPad = 0;
+  unsigned long planeMask = 0xffffffff;
+
+  RegionPtr pSrcRegion, pDstRegion;
+  RegionRec corruptedRegion;
+
+  int skip = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCopyPlane: Image src [%s:%p], dst [%s:%p] (%d,%d) -> (%d,%d) size (%d,%d)\n",
+              ((pSrcDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW", (void *) pSrcDrawable,
+                      ((pDstDrawable)->type == DRAWABLE_PIXMAP) ? "PIXMAP" : "WINDOW",
+                          (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
+  #endif
+
+  if (nxagentGCTrap == 1 || nxagentShmTrap == 1)
+  {
+    if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+            pDstDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable), 
+                           nxagentVirtualDrawable(pDstDrawable),
+                             pGC, srcx, srcy, width, height, dstx, dsty, plane);
+    }
+    else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable,
+                             pGC, srcx, srcy, width, height, dstx, dsty, plane);
+    }
+    else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      return fbCopyPlane(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable),
+                             pGC, srcx, srcy, width, height, dstx, dsty, plane);
+    }
+    else
+    {
+      return fbCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
+                             dstx, dsty, plane);
+    }
+
+    return NullRegion;
+  }
+
+  /*
+   * If the pixmap is on shared memory, we can't
+   * know if the pixmap content is changed and
+   * so have to translate the operation in a put
+   * image operation. This can seriously affect
+   * the performance.
+   */
+
+  if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
+         nxagentIsShmPixmap((PixmapPtr) pSrcDrawable))
+  {
+    char *data;
+    int depth, length;
+
+    depth  = pSrcDrawable -> depth;
+
+    format = (depth == 1) ? XYPixmap : ZPixmap;
+
+    length = nxagentImageLength(width, height, format, leftPad, depth);
+
+    if ((data = xalloc(length)) == NULL)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentCopyPlane: WARNING! Failed to allocate memory for the operation.\n");
+      #endif
+
+      return 0;
+    }
+
+    fbGetImage(nxagentVirtualDrawable(pSrcDrawable), srcx, srcy, width, height, format, planeMask, data);
+
+    /*
+     * If the source is a shared memory pixmap,
+     * put the image directly to the destination.
+     */
+
+    nxagentPutImage(pDstDrawable, pGC, depth, dstx, dsty,
+                        width, height, leftPad, format, data);
+
+    #ifdef TEST
+    fprintf(stderr,"nxagentCopyPlane: Synchronize Pixmap %p virtual %p x %d y %d w %d h %d \n",
+               (void *) pSrcDrawable, (void *) nxagentVirtualDrawable(pSrcDrawable),
+                   srcx, srcy, width, height);
+    #endif
+
+    xfree(data);
+
+    /*
+     * If the source is a shared memory pixmap, the
+     * content of the framebuffer has been placed
+     * directly on the destination so we can skip
+     * the copy plane operation.
+     */
+
+    skip = 1;
+  }
+
+  if (skip == 0 && nxagentDrawableStatus(pSrcDrawable) == NotSynchronized)
+  {
+    if (pDstDrawable -> type == DRAWABLE_PIXMAP &&
+            nxagentOption(DeferLevel) > 0)
+    {
+      pDstRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty, width, height);
+
+      nxagentMarkCorruptedRegion(pDstDrawable, pDstRegion);
+
+      nxagentFreeRegion(pDstDrawable, pDstRegion);
+
+      skip = 1;
+    }
+    else
+    {
+      pSrcRegion = nxagentCreateRegion(pSrcDrawable, NULL, srcx, srcy, width, height);
+
+      REGION_INIT(pSrcDrawable -> pScreen, &corruptedRegion, NullBox, 1);
+
+      REGION_INTERSECT(pSrcDrawable -> pScreen, &corruptedRegion,
+                           pSrcRegion, nxagentCorruptedRegion(pSrcDrawable));
+
+      if (REGION_NIL(&corruptedRegion) == 0)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentCopyPlane: Forcing the synchronization of source drawable at [%p].\n",
+                    (void *) pSrcDrawable);
+        #endif
+
+        nxagentSynchronizeRegion(pSrcDrawable, &corruptedRegion /*pSrcRegion*/, NEVER_BREAK, NULL);
+
+        pDstRegion = nxagentCreateRegion(pDstDrawable, pGC, dstx, dsty, width, height);
+
+        nxagentUnmarkCorruptedRegion(pDstDrawable, pDstRegion);
+
+        nxagentFreeRegion(pDstDrawable, pDstRegion);
+      }
+
+      REGION_UNINIT(pSrcDrawable -> pScreen, &corruptedRegion);
+
+      nxagentFreeRegion(pSrcDrawable, pSrcRegion);
+    }
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentCopyPlane: Source drawable at [%p] already synchronized.\n",
+                (void *) pSrcDrawable);
+  }
+  #endif
+
+  if (skip == 0)
+  {
+    XCopyPlane(nxagentDisplay,
+                   nxagentDrawable(pSrcDrawable), nxagentDrawable(pDstDrawable),
+                       nxagentGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
+  }
+
+  if ((pSrcDrawable)->type == DRAWABLE_PIXMAP &&
+          (pDstDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCopyPlane: going to copy plane from FB pixmap [%p] to [%p].\n",
+                (void *) nxagentVirtualDrawable(pSrcDrawable),
+                    (void *) nxagentVirtualDrawable(pDstDrawable));
+    #endif
+
+    return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable), 
+                         nxagentVirtualDrawable(pDstDrawable),
+                           pGC, srcx, srcy, width, height, dstx, dsty, plane);
+  }
+  else if (pSrcDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    return fbCopyPlane(nxagentVirtualDrawable(pSrcDrawable), pDstDrawable, pGC,
+                            srcx, srcy, width, height, dstx, dsty, plane);
+  }
+  else if (pDstDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    return fbCopyPlane(pSrcDrawable, nxagentVirtualDrawable(pDstDrawable), pGC,
+                            srcx, srcy, width, height, dstx, dsty, plane);
+  }
+  else
+  {
+    return fbCopyPlane(pSrcDrawable, pDstDrawable, pGC,
+                            srcx, srcy, width, height, dstx, dsty, plane);
+  }
+
+  return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, 
+                               srcx, srcy, width, height, dstx, dsty, plane);
+}
+
+void nxagentPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                          int nPoints, xPoint *pPoints)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentPolyPoint: Drawable at [%p] GC at [%p] Points [%d].\n",
+              (void *) pDrawable, (void *) pGC, nPoints);
+  #endif
+
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      fbPolyPoint(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+    }
+    else
+    {
+      fbPolyPoint(pDrawable, pGC, mode, nPoints, pPoints);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly point on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly point enters with virtual pixmap [%p] parent is [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawPoints(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                        nxagentGC(pGC), (XPoint *) pPoints, nPoints, mode);
+      }
+    }
+    else
+    {
+      XDrawPoints(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                      (XPoint *) pPoints, nPoints, mode);
+    }
+
+    fbPolyPoint(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+
+    return;
+  }
+  else
+  {
+    XDrawPoints(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                    (XPoint *) pPoints, nPoints, mode);
+
+    fbPolyPoint(pDrawable, pGC, mode, nPoints, pPoints);
+  }
+}
+
+void nxagentPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                          int nPoints, xPoint *pPoints)
+{
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      fbPolyLine(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+    }
+    else
+    {
+      fbPolyLine(pDrawable, pGC, mode, nPoints, pPoints);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly line on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly lines enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                       (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawLines(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                       nxagentGC(pGC), (XPoint *) pPoints, nPoints, mode);
+      }
+    }
+    else
+    {
+      XDrawLines(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                 (XPoint *) pPoints, nPoints, mode);
+    }
+
+    fbPolyLine(nxagentVirtualDrawable(pDrawable), pGC, mode, nPoints, pPoints);
+
+    return;
+  }
+  else
+  {
+    XDrawLines(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+               (XPoint *) pPoints, nPoints, mode);
+
+    fbPolyLine(pDrawable, pGC, mode, nPoints, pPoints);
+  }
+}
+
+void nxagentPolySegment(DrawablePtr pDrawable, GCPtr pGC,
+                            int nSegments, xSegment *pSegments)
+{
+  #ifdef TEST
+
+  if (nSegments == 1)
+  {
+    fprintf(stderr, "nxagentPolySegment: Drawable at [%p] GC at [%p] Segment [%d,%d,%d,%d].\n",
+                (void *) pDrawable, (void *) pGC,
+                    pSegments -> x1, pSegments -> y1, pSegments -> x2, pSegments -> y2);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentPolySegment: Drawable at [%p] GC at [%p] Segments [%d].\n",
+                (void *) pDrawable, (void *) pGC, nSegments);
+  }
+
+  #endif
+
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      fbPolySegment(nxagentVirtualDrawable(pDrawable), pGC, nSegments, pSegments);
+    }
+    else
+    {
+      fbPolySegment(pDrawable, pGC, nSegments, pSegments);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly segment on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly segment enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawSegments(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                          nxagentGC(pGC), (XSegment *) pSegments, nSegments);
+      }
+    }
+    else
+    {
+      XDrawSegments(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                    (XSegment *) pSegments, nSegments);
+    }
+
+    fbPolySegment(nxagentVirtualDrawable(pDrawable), pGC, nSegments, pSegments);
+
+    return;
+  }
+  else
+  {
+    XDrawSegments(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                 (XSegment *) pSegments, nSegments);
+
+    fbPolySegment(pDrawable, pGC, nSegments, pSegments);
+  }
+}
+
+void nxagentPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
+                              int nRectangles, xRectangle *pRectangles)
+{
+  #ifdef TEST
+
+  if (nRectangles == 1)
+  {
+    fprintf(stderr, "nxagentPolyRectangle: Drawable at [%p] GC at [%p] Rectangle [%d,%d][%d,%d].\n",
+                (void *) pDrawable, (void *) pGC,
+                    pRectangles -> x, pRectangles -> y, pRectangles -> width, pRectangles -> height);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentPolyRectangle: Drawable at [%p] GC at [%p] Rectangles [%d].\n",
+                (void *) pDrawable, (void *) pGC, nRectangles);
+  }
+
+  #endif
+
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      miPolyRectangle(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+    }
+    else
+    {
+      miPolyRectangle(pDrawable, pGC, nRectangles, pRectangles);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly rectangle on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly rectangle enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawRectangles(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                            nxagentGC(pGC), (XRectangle *) pRectangles, nRectangles);
+      }
+    }
+    else
+    {
+      XDrawRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                      (XRectangle *) pRectangles, nRectangles);
+    }
+
+    SET_GC_TRAP();
+
+    miPolyRectangle(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+
+    RESET_GC_TRAP();
+
+    return;
+  }
+  else
+  {
+    XDrawRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                    (XRectangle *) pRectangles, nRectangles);
+
+    SET_GC_TRAP();
+
+    miPolyRectangle(pDrawable, pGC, nRectangles, pRectangles);
+
+    RESET_GC_TRAP();
+  }
+}
+
+void nxagentPolyArc(DrawablePtr pDrawable, GCPtr pGC,
+                        int nArcs, xArc *pArcs)
+{
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      fbPolyArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+    }
+    else
+    {
+      fbPolyArc(pDrawable, pGC, nArcs, pArcs);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly arc on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly arc enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawArcs(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                      nxagentGC(pGC), (XArc *) pArcs, nArcs);
+      }
+    }
+    else
+    {
+       XDrawArcs(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                     (XArc *) pArcs, nArcs);
+    }
+
+    fbPolyArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+
+    return;
+  }
+  else
+  {
+    XDrawArcs(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                  (XArc *) pArcs, nArcs);
+
+    fbPolyArc(pDrawable, pGC, nArcs, pArcs);
+  }
+}
+
+void nxagentFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+                            int mode, int nPoints, xPoint *pPoints)
+{
+  xPoint *newPoints = NULL;
+
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      miFillPolygon(nxagentVirtualDrawable(pDrawable), pGC, shape, mode, nPoints, pPoints);
+    }
+    else
+    {
+      miFillPolygon(pDrawable, pGC, shape, mode, nPoints, pPoints);
+    }
+
+    return;
+  }
+
+  /*
+   * The coordinate-mode must be CoordModePrevious
+   * to make better use of differential encoding of
+   * X_FillPoly request by the side of proxy.
+   */
+
+  if (mode == CoordModeOrigin)
+  {
+    int i;
+
+    mode = CoordModePrevious;
+
+    newPoints = xalloc(nPoints * sizeof(xPoint));
+
+    /*
+     * The first point is always relative
+     * to the drawable's origin.
+     */
+
+    newPoints[0].x = pPoints[0].x;
+    newPoints[0].y = pPoints[0].y;
+
+    /*
+     * If coordinate-mode is CoordModePrevious,
+     * the points following the first are rela-
+     * tive to the previous point.
+     */
+
+    for (i = 1; i < nPoints; i++)
+    {
+      newPoints[i].x = pPoints[i].x - pPoints[i-1].x;
+      newPoints[i].y = pPoints[i].y - pPoints[i-1].y;
+    }
+
+    pPoints = newPoints;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to fill polygon on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: fill polygon enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XFillPolygon(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                         nxagentGC(pGC), (XPoint *) pPoints, nPoints, shape, mode);
+      }
+    }
+    else
+    {
+      XFillPolygon(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                       (XPoint *) pPoints, nPoints, shape, mode);
+    }
+
+    SET_GC_TRAP();
+
+    miFillPolygon(nxagentVirtualDrawable(pDrawable), pGC, shape, mode, nPoints, pPoints);
+
+    RESET_GC_TRAP();
+  }
+  else
+  {
+    XFillPolygon(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                     (XPoint *) pPoints, nPoints, shape, mode);
+
+    SET_GC_TRAP();
+
+    miFillPolygon(pDrawable, pGC, shape, mode, nPoints, pPoints);
+
+    RESET_GC_TRAP();
+  }
+
+  if (newPoints != NULL)
+  {
+    xfree(newPoints);
+  }
+}
+
+void nxagentPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+                             int nRectangles, xRectangle *pRectangles)
+{
+  RegionPtr rectRegion;
+
+  int inheritCorruptedRegion;
+
+  #ifdef TEST
+
+  if (nRectangles == 1)
+  {
+    fprintf(stderr, "nxagentPolyFillRect: Drawable at [%p] GC at [%p] FillStyle [%d] Rectangle [%d,%d][%d,%d].\n",
+                (void *) pDrawable, (void *) pGC, pGC -> fillStyle, 
+                    pRectangles -> x, pRectangles -> y, pRectangles -> width, pRectangles -> height);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentPolyFillRect: Drawable at [%p] GC at [%p] FillStyle [%d] Rectangles [%d].\n",
+                (void *) pDrawable, (void *) pGC, pGC -> fillStyle, nRectangles);
+  }
+
+  #endif
+
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      fbPolyFillRect(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+    }
+    else
+    {
+      fbPolyFillRect(pDrawable, pGC, nRectangles, pRectangles);
+    }
+
+    return;
+  }
+
+  /*
+   * The PolyFillRect acts in two ways: if the GC
+   * has a corrupted tile, the operation propagates
+   * the corrupted region on the destination. In
+   * other cases, because the PolyFillRect will
+   * cover the destination, any corrupted region
+   * intersecting the target will be cleared.
+   */
+
+  inheritCorruptedRegion = 0;
+
+  if (pGC -> fillStyle == FillTiled &&
+          pGC -> tileIsPixel == 0 && pGC -> tile.pixmap != NULL)
+  {
+    nxagentIncreasePixmapUsageCounter(pGC -> tile.pixmap);
+
+    if (nxagentDrawableStatus((DrawablePtr) pGC -> tile.pixmap) == NotSynchronized)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentPolyFillRect: GC at [%p] uses corrupted tile pixmap at [%p]. Going to "
+                  "corrupt the destination [%s][%p].\n", (void *) pGC, (void *) pGC -> tile.pixmap,
+                      (pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"), (void *) pDrawable);
+
+      #endif
+
+      inheritCorruptedRegion = 1;
+    }
+  }
+
+  if (inheritCorruptedRegion == 1 || nxagentDrawableStatus(pDrawable) == NotSynchronized)
+  {
+    rectRegion = RECTS_TO_REGION(pDrawable -> pScreen, nRectangles, pRectangles, CT_REGION);
+
+    if (pGC -> clientClip != NULL)
+    {
+      RegionRec tmpRegion;
+
+      REGION_INIT(pDrawable -> pScreen, &tmpRegion, NullBox, 1);
+
+      REGION_COPY(pDrawable -> pScreen, &tmpRegion, ((RegionPtr) pGC -> clientClip));
+
+      if (pGC -> clipOrg.x != 0 || pGC -> clipOrg.y != 0)
+      {
+        REGION_TRANSLATE(pDrawable -> pScreen, &tmpRegion, pGC -> clipOrg.x, pGC -> clipOrg.y);
+      }
+
+      REGION_INTERSECT(pDrawable -> pScreen, rectRegion, rectRegion, &tmpRegion);
+
+      REGION_UNINIT(pDrawable -> pScreen, &tmpRegion);
+    }
+
+    if (inheritCorruptedRegion == 1)
+    {
+      /*
+       * The fill style should affect the cor-
+       * rupted region propagation: if the tile
+       * is not completely corrupted the region
+       * should be 'tiled' over the destination.
+       */
+
+      nxagentMarkCorruptedRegion(pDrawable, rectRegion);
+    }
+    else
+    {
+      if (pGC -> fillStyle != FillStippled && pGC -> fillStyle != FillOpaqueStippled)
+      {
+        nxagentUnmarkCorruptedRegion(pDrawable, rectRegion);
+      }
+      else
+      {
+        /*
+         * The stipple mask computation could cause
+         * an high fragmentation of the destination
+         * region. An analysis should be done to exa-
+         * mine the better solution (e.g.rdesktop
+         * uses stipples to draw texts).
+         */
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentPolyFillRect: Synchronizing the region [%d,%d,%d,%d] before using "
+                    "the stipple at [%p].\n", rectRegion -> extents.x1, rectRegion -> extents.y1,
+                        rectRegion -> extents.x2, rectRegion -> extents.y2, (void *) pGC -> stipple);
+        #endif
+
+        nxagentSynchronizeRegion(pDrawable, rectRegion, NEVER_BREAK, NULL);
+      }
+    }
+
+    REGION_DESTROY(pDrawable -> pScreen, rectRegion);
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly fill rect on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly fill rect enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XFillRectangles(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                            nxagentGC(pGC), (XRectangle *) pRectangles, nRectangles);
+      }
+    }
+    else
+    {
+      XFillRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                          (XRectangle *) pRectangles, nRectangles);
+    }
+
+    fbPolyFillRect(nxagentVirtualDrawable(pDrawable), pGC, nRectangles, pRectangles);
+
+    return;
+  }
+  else
+  {
+    XFillRectangles(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                        (XRectangle *) pRectangles, nRectangles);
+
+    fbPolyFillRect(pDrawable, pGC, nRectangles, pRectangles);
+  }
+}
+
+void nxagentPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
+                            int nArcs, xArc *pArcs)
+{
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      miPolyFillArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+    }
+    else
+    {
+      miPolyFillArc(pDrawable, pGC, nArcs, pArcs);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly fillarc on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly fill arc enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                       (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XFillArcs(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                      nxagentGC(pGC), (XArc *) pArcs, nArcs);
+      }
+    }
+    else
+    {
+      XFillArcs(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                (XArc *) pArcs, nArcs);
+    }
+
+    SET_GC_TRAP();
+
+    miPolyFillArc(nxagentVirtualDrawable(pDrawable), pGC, nArcs, pArcs);
+
+    RESET_GC_TRAP();
+
+    return;
+  }
+  else
+  {
+    XFillArcs(nxagentDisplay, nxagentDrawable(pDrawable),
+                  nxagentGC(pGC), (XArc *) pArcs, nArcs);
+
+    SET_GC_TRAP();
+
+    miPolyFillArc(pDrawable, pGC, nArcs, pArcs);
+
+    RESET_GC_TRAP();
+  }
+}
+
+int nxagentPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+                         int y, int count, char *string)
+{
+  int width;
+
+  /*
+   * While the session is suspended
+   * the font structure is NULL.
+   */
+
+  if (nxagentFontStruct(pGC -> font) == NULL)
+  {
+    return x;
+  }
+
+  width = XTextWidth(nxagentFontStruct(pGC->font), string, count);
+
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      miPolyText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+    }
+    else
+    {
+      miPolyText8(pDrawable, pGC, x, y, count, string);
+    }
+
+    return width + x;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly text8 on FB pixmap [%p] with string [%s].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), (char *) string);
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly text8 enters with virtual pixmap [%p] parent is [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+         XDrawString(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                         nxagentGC(pGC), x, y, string, count);
+      }
+    }
+    else
+    {
+      XDrawString(nxagentDisplay, nxagentDrawable(pDrawable),
+                      nxagentGC(pGC), x, y, string, count);
+    }
+
+    miPolyText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+    return width + x;
+  }
+  else
+  {
+    XDrawString(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
+                    x, y, string, count);
+
+    miPolyText8(pDrawable, pGC, x, y, count, string);
+  }
+
+  return width + x;
+}
+
+int nxagentPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+                          int y, int count, unsigned short *string)
+{
+  int width;
+
+  /*
+   * While the session is suspended
+   * the font structure is NULL.
+   */
+
+  if (nxagentFontStruct(pGC -> font) == NULL)
+  {
+    return x;
+  }
+
+  width = XTextWidth16(nxagentFontStruct(pGC->font), (XChar2b *)string, count);
+
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      miPolyText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+    }
+    else
+    {
+      miPolyText16(pDrawable, pGC, x, y, count, string);
+    }
+
+    return width + x;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to poly text16 on FB pixmap %p] with string [%s]\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), (char *) string);
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly text16 enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawString16(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                          nxagentGC(pGC), x, y, (XChar2b *)string, count);
+      }
+    }
+    else
+    {
+      XDrawString16(nxagentDisplay, nxagentDrawable(pDrawable),
+                        nxagentGC(pGC), x, y, (XChar2b *)string, count);
+    }
+
+    miPolyText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+    return width + x;
+  }
+  else
+  {
+    XDrawString16(nxagentDisplay, nxagentDrawable(pDrawable),
+                      nxagentGC(pGC), x, y, (XChar2b *)string, count);
+
+    miPolyText16(pDrawable, pGC, x, y, count, string);
+  }
+
+  return width + x;
+}
+
+void nxagentImageText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+                           int y, int count, char *string)
+{
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      miImageText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+    }
+    else
+    {
+      miImageText8(pDrawable, pGC, x, y, count, string);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to image text8 on FB pixmap [%p] with string [%s].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), string);
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly image text8 enters with virtual pixmap [%p] parent is [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawImageString(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                             nxagentGC(pGC), x, y, string, count);
+      }
+    }
+    else
+    {
+      XDrawImageString(nxagentDisplay, nxagentDrawable(pDrawable),
+                           nxagentGC(pGC), x, y, string, count);
+    }
+
+    miImageText8(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+    return;
+  }
+  else
+  {
+    XDrawImageString(nxagentDisplay, nxagentDrawable(pDrawable),
+                         nxagentGC(pGC), x, y, string, count);
+
+    miImageText8(pDrawable, pGC, x, y, count, string);
+  }
+}
+
+void nxagentImageText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+                            int y, int count, unsigned short *string)
+{
+  if (nxagentGCTrap == 1)
+  {
+    if ((pDrawable)->type == DRAWABLE_PIXMAP)
+    {
+      miImageText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+    }
+    else
+    {
+      miImageText16(pDrawable, pGC, x, y, count, string);
+    }
+
+    return;
+  }
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to image text16 on FB pixmap [%p] with string [%s].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable), (char *) string);
+    #endif
+
+    if (nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+    {
+      #ifdef TEST
+      fprintf(stderr, "GCOps: poly image text16 enters with virtual pixmap = [%p] parent is = [%p]\n",
+                  (void *) nxagentVirtualDrawable(pDrawable),
+                      (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+      #endif
+
+      if (nxagentRealPixmap((PixmapPtr) pDrawable))
+      {
+        XDrawImageString16(nxagentDisplay, nxagentDrawable((DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable)),
+                               nxagentGC(pGC), x, y, (XChar2b *)string, count);
+      }
+    }
+    else
+    {
+      XDrawImageString16(nxagentDisplay, nxagentDrawable(pDrawable),
+                             nxagentGC(pGC), x, y, (XChar2b *)string, count);
+    }
+
+    miImageText16(nxagentVirtualDrawable(pDrawable), pGC, x, y, count, string);
+
+    return;
+  }
+  else
+  {
+    XDrawImageString16(nxagentDisplay, nxagentDrawable(pDrawable),
+                           nxagentGC(pGC), x, y, (XChar2b *)string, count);
+
+    miImageText16(pDrawable, pGC, x, y, count, string);
+  }
+}
+
+void nxagentImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                              unsigned int nGlyphs, CharInfoPtr *pCharInfo,
+                                  pointer pGlyphBase)
+{
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to imageGlyphBlt on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+     #endif
+
+    fbImageGlyphBlt(nxagentVirtualDrawable(pDrawable), pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+  }
+  else
+  {
+    fbImageGlyphBlt(pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+  }
+}
+
+void nxagentPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                             unsigned int nGlyphs, CharInfoPtr *pCharInfo,
+                                 pointer pGlyphBase)
+{
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to PolyGlyphBlt on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    fbPolyGlyphBlt(nxagentVirtualDrawable(pDrawable), pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+  }
+  else
+  {
+    fbPolyGlyphBlt(pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase);
+  }
+}
+
+void nxagentPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable,
+                           int width, int height, int x, int y)
+{
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "GCOps: GC [%p] going to PushPixels on FB pixmap [%p].\n",
+                (void *) pGC, (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    fbPushPixels(pGC, nxagentVirtualPixmap(pBitmap),
+                     (DrawablePtr) nxagentVirtualDrawable(pDrawable),
+                         width, height, x, y);
+  }
+  else
+  {
+    fbPushPixels(pGC, nxagentVirtualPixmap(pBitmap),
+                     (DrawablePtr) pDrawable, width, height, x, y);
+  }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
new file mode 100644
index 000000000..14d30e392
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
@@ -0,0 +1,105 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __GCOps_H__
+#define __GCOps_H__
+
+/*
+ * Graphic operations.
+ */
+
+void nxagentFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans,
+                          xPoint *pPoints, int *pWidths, int fSorted);
+
+void nxagentSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc,
+                         xPoint *pPoints, int *pWidths, int nSpans, int fSorted);
+
+void nxagentGetSpans(DrawablePtr pDrawable, int maxWidth, xPoint *pPoints,
+                         int *pWidths, int nSpans, char *pBuffer);
+
+RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+                              GCPtr pGC, int srcx, int srcy, int width,
+                                  int height, int dstx, int dsty);
+
+RegionPtr nxagentCopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+                               GCPtr pGC, int srcx, int srcy, int width, int height,
+                                   int dstx, int dsty, unsigned long plane);
+
+void nxagentQueryBestSize(int class, unsigned short *pwidth,
+                              unsigned short *pheight, ScreenPtr pScreen);
+
+void nxagentPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                          int nPoints, xPoint *pPoints);
+
+void nxagentPolyLines(DrawablePtr pDrawable, GCPtr pGC, int mode,
+                          int nPoints, xPoint *pPoints);
+
+void nxagentPolySegment(DrawablePtr pDrawable, GCPtr pGC,
+                            int nSegments, xSegment *pSegments);
+
+void nxagentPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
+                              int nRectangles, xRectangle *pRectangles);
+
+void nxagentPolyArc(DrawablePtr pDrawable, GCPtr pGC,
+                        int nArcs, xArc *pArcs);
+
+void nxagentFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape,
+                            int mode, int nPoints, xPoint *pPoints);
+
+void nxagentPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
+                             int nRectangles, xRectangle *pRectangles);
+
+void nxagentPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
+                            int nArcs, xArc *pArcs);
+
+int nxagentPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+                         int y, int count, char *string);
+
+int nxagentPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+                          int y, int count, unsigned short *string);
+
+void nxagentImageText8(DrawablePtr pDrawable, GCPtr pGC, int x,
+                           int y, int count, char *string);
+
+void nxagentImageText16(DrawablePtr pDrawable, GCPtr pGC, int x,
+                            int y, int count, unsigned short *string);
+
+void nxagentImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                              unsigned int nGlyphs, CharInfoPtr *pCharInfo, pointer pGlyphBase);
+
+void nxagentPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                             unsigned int nGlyphs, CharInfoPtr *pCharInfo, pointer pGlyphBase);
+
+void nxagentPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable,
+                           int width, int height, int x, int y);
+
+#endif /* __GCOps_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCs.h b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
new file mode 100644
index 000000000..207d563ed
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
@@ -0,0 +1,111 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __GC_H__
+#define __GC_H__
+
+extern RESTYPE RT_NX_GC;
+
+/* This file uses the GC definition form Xlib.h as XlibGC. */
+
+typedef struct {
+  XlibGC gc;
+
+  int nClipRects;
+
+  XGCValues lastServerValues;
+
+  XID mid;
+
+  PixmapPtr pPixmap;
+
+} nxagentPrivGC;
+
+extern int nxagentGCPrivateIndex;
+
+typedef struct _nxagentGraphicContextsRec
+{
+  int   depth;
+  GCPtr pGC;
+  int   dirty;
+
+} nxagentGraphicContextsRec;
+
+typedef nxagentGraphicContextsRec *nxagentGraphicContextsPtr;
+extern nxagentGraphicContextsPtr nxagentGraphicContexts;
+extern int nxagentGraphicContextsSize;
+
+#define nxagentGCPriv(pGC) \
+  ((nxagentPrivGC *)((pGC) -> devPrivates[nxagentGCPrivateIndex].ptr))
+
+#define nxagentGC(pGC) (nxagentGCPriv(pGC) -> gc)
+
+#define nxagentCopyGCPriv(valueMask, valueField, src, mask, dst) \
+\
+  if (mask & valueMask) \
+  { \
+    nxagentGCPriv(dst) -> lastServerValues.valueField = \
+           nxagentGCPriv(src) -> lastServerValues.valueField; \
+  }
+
+#define nxagentTestGC(newValue, pvalue) \
+\
+  ((nxagentGCPriv(pGC) -> lastServerValues.pvalue == newValue) ? 0 : 1); \
+\
+  nxagentGCPriv(pGC) -> lastServerValues.pvalue = newValue
+
+Bool nxagentCreateGC(GCPtr pGC);
+void nxagentValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable);
+void nxagentChangeGC(GCPtr pGC, unsigned long mask);
+void nxagentCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+void nxagentDestroyGC(GCPtr pGC);
+void nxagentChangeClip(GCPtr pGC, int type, pointer pValue, int nRects);
+void nxagentDestroyClip(GCPtr pGC);
+void nxagentDestroyClipHelper(GCPtr pGC);
+void nxagentCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+
+void nxagentDisconnectGC(pointer p0, XID x1, pointer p2);
+Bool nxagentDisconnectAllGCs(void);
+
+Bool nxagentReconnectAllGCs(void *p0);
+
+int nxagentDestroyNewGCResourceType(pointer p, XID id);
+
+void nxagentFreeGCList(void);
+void nxagentInitGCSafeVector(void);
+
+GCPtr nxagentGetScratchGC(unsigned depth, ScreenPtr pScreen);
+void nxagentFreeScratchGC(GCPtr pGC);
+
+GCPtr nxagentGetGraphicContext(DrawablePtr pDrawable);
+void nxagentAllocateGraphicContexts(void);
+
+#endif /* __GC_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
new file mode 100644
index 000000000..dc9770c75
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -0,0 +1,1272 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "dixstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "osdep.h"
+
+#include "Agent.h"
+#include "Handlers.h"
+#include "Display.h"
+#include "Events.h"
+#include "Client.h"
+#include "Reconnect.h"
+#include "Dialog.h"
+#include "Drawable.h"
+#include "Splash.h"
+#include "Screen.h"
+#include "Millis.h"
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+/*
+ * Log begin and end of the important
+ * handlers.
+ */
+
+#undef  BLOCKS
+
+/*
+ * If not defined, flush immediately
+ * upon entering the block handler.
+ */
+
+#define FLUSH_AFTER_MULTIPLE_READS
+
+/*
+ * Introduce a small delay after each
+ * loop if the session is down. The
+ * value is in milliseconds.
+ */
+
+#define LOOP_DELAY_IF_DOWN       50
+
+/*
+ * The soft limit should roughly match
+ * the size of the Xlib I/O buffer.
+ */
+
+#define BYTES_BEFORE_SOFT_TOKEN  2048
+#define BYTES_BEFORE_HARD_TOKEN  65536
+
+/*
+ * Maximum number of synchronization
+ * requests before waiting for the
+ * remote.
+ */
+
+#define TOKENS_PENDING_LIMIT     8
+
+/*
+ * Limits are very unobtrusive. We don't
+ * want to interfere with the normal
+ * dispatching.
+ */
+
+#define BYTES_BEFORE_YIELD       1048576
+#define TIME_BEFORE_YIELD        500
+
+/*
+ * Dinamically reduce the display buffer
+ * size after a congestion.
+ */
+
+#undef DYNAMIC_DISPLAY_BUFFER
+
+/*
+ * Minimum display buffer size.
+ */
+
+#define MINIMUM_DISPLAY_BUFFER   512
+
+/*
+ * Used in the handling of the X desktop
+ * manager protocol.
+ */
+
+int nxagentXdmcpUp = 0;
+int nxagentXdmcpAlertUp = 0;
+
+/*
+ * Also used in the block, wakeup and
+ * sync handlers.
+ */
+
+int nxagentBuffer;
+int nxagentBlocking;
+int nxagentCongestion;
+
+double nxagentBytesIn;
+double nxagentBytesOut;
+
+/*
+ * Total number of descriptors ready
+ * as reported by the wakeup handler.
+ */
+
+int nxagentReady;
+
+/*
+ * Timestamp of the last write to the
+ * remote display.
+ */
+
+int nxagentFlush;
+
+/*
+ * Arbitrate the bandwidth among our
+ * clients.
+ */
+
+struct _TokensRec   nxagentTokens   = { 0, 0, 0 };
+struct _DispatchRec nxagentDispatch = { UNDEFINED, 0, 0, 0 };
+
+/*
+ * Called just before blocking, waiting
+ * for our clients or the X server.
+ */
+
+void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
+{
+  /*
+   * Zero timeout.
+   */
+
+  static struct timeval zero;
+
+  /*
+   * Current timestamp.
+   */
+
+  static int now;
+
+  /*
+   * Pending bytes to write to the
+   * network.
+   */
+
+  static int flushable;
+
+  /*
+   * Set if we need to synchronize
+   * any drawable.
+   */
+
+  static int synchronize;
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[Begin block]\n");
+  #endif
+
+  now = GetTimeInMillis();
+
+  if (nxagentNeedConnectionChange() == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentBlockHandler: Calling nxagentHandleConnectionChanges "
+                "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup);
+    #endif
+
+    nxagentHandleConnectionChanges();
+  }
+
+  if (nxagentOption(Rootless) &&
+          nxagentLastWindowDestroyed && nxagentRootlessDialogPid == 0 &&
+              now > nxagentLastWindowDestroyedTime + 30 * 1000)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentBlockHandler: No application running. Closing the session.\n");
+    #endif
+
+    nxagentTerminateSession();
+  }
+
+  #ifdef TEST
+
+  if (nxagentLastWindowDestroyed == 1)
+  {
+    fprintf(stderr, "nxagentBlockHandler: Elapsed time [%lu].\n",
+                now - nxagentLastWindowDestroyedTime);
+  }
+
+  #endif
+
+  /*
+   * Slow down the agent if the session is
+   * not connected to a valid display.
+   */
+
+  if (NXDisplayError(nxagentDisplay) == 1 && nxagentShadowCounter == 0)
+  {
+    usleep(LOOP_DELAY_IF_DOWN * 1000);
+
+    now = GetTimeInMillis();
+  }
+
+  /*
+   * Update the shadow display. This is
+   * only for test purposes.
+   */
+
+  #ifdef DUMP
+
+  nxagentPixmapOnShadowDisplay(NULL);
+
+  nxagentFbOnShadowDisplay();
+
+  #endif
+
+  /*
+   * We need this here because some window
+   * configuration changes can be generated
+   * by the X server outside the control of
+   * the DIX.
+   */
+
+  nxagentFlushConfigureWindow();
+
+  /*
+   * Check whether there is any drawable to
+   * synchronize.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentBlockHandler: Checking synchronization at %s with "
+              "[%d][%d][%d].\n", GetTimeInMillisAsString(), nxagentCorruptedWindows,
+                  nxagentCorruptedBackgrounds, nxagentCorruptedPixmaps);
+  #endif
+
+  synchronize = (nxagentCorruptedWindows > 0 ||
+                     nxagentCorruptedBackgrounds > 0 ||
+                         nxagentCorruptedPixmaps > 0);
+
+  /*
+   * The synchronization function requires a mask as
+   * parameter:
+   *
+   * EVENT_BREAK       Breaks if an user input, like
+   *                   a key press or a mouse move,
+   *                   is detected.
+   *
+   * CONGESTION_BREAK  Breaks if the congestion beco-
+   *                   mes greater than 4.
+   *
+   * BLOCKING_BREAK    Breaks if the display descript-
+   *                   or becomes blocked for write
+   *                   during the loop.
+   *
+   * ALWAYS_BREAK      Any of the previous conditions
+   *                   is met.
+   *
+   * NEVER_BREAK       The loop continues until all
+   *                   the drawables are synchronized.
+   */
+
+  if (synchronize == 1)
+  {
+    /*
+     * We should not enter the synchronization
+     * loop if there is any user input pending,
+     * i.e. if we are in the middle of a scroll
+     * operation.
+     */
+
+    if (nxagentForceSynchronization == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentBlockHandler: Going to force a synchronization at %s.\n",
+                GetTimeInMillisAsString());
+      #endif
+
+      nxagentSynchronizationLoop(NEVER_BREAK);
+
+      nxagentForceSynchronization = 0;
+    }
+    else if (nxagentUserInput(NULL) == 0 &&
+                 nxagentBlocking == 0 &&
+                     nxagentCongestion <= 4)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentBlockHandler: Going to synchronize at %s.\n",
+                GetTimeInMillisAsString());
+      #endif
+
+      nxagentSynchronizationLoop(ALWAYS_BREAK);
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentBlockHandler: Not synchronizing with [%d][%d].\n",
+                  nxagentBlocking, nxagentCongestion);
+    }
+    #endif
+
+    /*
+     * Check if we have more corrupted resources
+     * and whether the conditions are satisfied
+     * to continue with the synchronization.
+     */
+
+    synchronize = (nxagentCongestion <= 4 &&
+                       (nxagentCorruptedWindows > 0 ||
+                           nxagentCorruptedBackgrounds > 0 ||
+                               nxagentCorruptedPixmaps > 0));
+
+    if (synchronize == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentBlockHandler: Setting a zero timeout with [%d][%d][%d] and "
+                  "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds,
+                      nxagentCorruptedPixmaps, nxagentCongestion);
+      #endif
+
+      zero.tv_sec  = 0;
+      zero.tv_usec = 0;
+
+      *timeout = &zero;
+    }
+    #ifdef TEST
+    else
+    {
+      if (nxagentCorruptedWindows == 0 &&
+              nxagentCorruptedBackgrounds == 0 &&
+                  nxagentCorruptedPixmaps == 0)
+      {
+        fprintf(stderr, "nxagentBlockHandler: Nothing more to synchronize at %s.\n",
+                    GetTimeInMillisAsString());
+      }
+      else
+      {
+        fprintf(stderr, "nxagentBlockHandler: Delaying synchronization with [%d][%d][%d] and "
+                  "congestion [%d].\n", nxagentCorruptedWindows, nxagentCorruptedBackgrounds,
+                      nxagentCorruptedPixmaps, nxagentCongestion);
+      }
+    }
+    #endif
+  }
+
+  /*
+   * If the remote X server is blocking, reduce the
+   * amount of data sent in a single display update
+   * by reducing the size of the display buffer.
+   */
+
+  #ifdef DYNAMIC_DISPLAY_BUFFER
+
+  if (nxagentBlocking == 1 &&
+          nxagentBuffer > MINIMUM_DISPLAY_BUFFER)
+  {
+    nxagentBuffer >>= 1;
+
+    if (nxagentBuffer < MINIMUM_DISPLAY_BUFFER)
+    {
+      nxagentBuffer = MINIMUM_DISPLAY_BUFFER;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentDispatchHandler: Reducing the display buffer to [%d] bytes.\n",
+                nxagentBuffer);
+    #endif
+
+    NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer);
+  }
+  else if (nxagentBuffer < nxagentOption(DisplayBuffer) &&
+               nxagentCongestion == 0)
+  {
+    nxagentBuffer = nxagentOption(DisplayBuffer);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentDispatchHandler: Increasing the display buffer to [%d] bytes.\n",
+                nxagentBuffer);
+    #endif
+
+    NXSetDisplayBuffer(nxagentDisplay, nxagentBuffer);
+  }
+
+  #endif /* #ifdef DYNAMIC_DISPLAY_BUFFER */
+  
+  /*
+   * Dispatch to the clients the events that
+   * may have become available.
+   */
+
+  if (nxagentPendingEvents(nxagentDisplay) > 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentBlockHandler: Reading the events available.\n");
+    #endif
+
+    nxagentDispatchEvents(NULL);
+  }
+
+  /*
+   * Check if there is any data remaining,
+   * either in the display buffer or in
+   * the NX transport.
+   */
+
+  flushable = NXDisplayFlushable(nxagentDisplay);
+
+  if (flushable > 0)
+  {
+    #ifdef FLUSH_AFTER_MULTIPLE_READS
+
+    /*
+     * Flush all the outstanding data if
+     * the wakeup handler didn't detect
+     * any activity.
+     */
+
+    if (nxagentReady == 0 || now - nxagentFlush >=
+            nxagentOption(DisplayCoalescence))
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentBlockHandler: Flushing the display with [%d] bytes to flush.\n",
+                  flushable);
+      #endif
+
+      NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+      /*
+       * New events may have become available
+       * after the flush.
+       */
+
+      if (nxagentPendingEvents(nxagentDisplay) > 0)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentBlockHandler: Reading the events available.\n");
+        #endif
+
+        nxagentDispatchEvents(NULL);
+      }
+    }
+    else
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentBlockHandler: Delaying flush with [%d][%d] and [%d] bytes.\n",
+                  synchronize, nxagentReady, flushable);
+      #endif
+
+      zero.tv_sec  = 0;
+      zero.tv_usec = 0;
+
+      *timeout = &zero;
+    }
+
+    #else /* #ifdef FLUSH_AFTER_MULTIPLE_READS */
+
+    /*
+     * We are entering the select. Tell the NX
+     * transport to write any produced data to
+     * the remote end.
+     */
+
+    NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+    if (nxagentPendingEvents(nxagentDisplay) > 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentBlockHandler: Reading the events available.\n");
+      #endif
+
+      nxagentDispatchEvents(NULL);
+    }
+
+    #endif /* #ifdef FLUSH_AFTER_MULTIPLE_READS */
+  }
+  else
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentBlockHandler: Nothing to flush with [%d][%d].\n",
+                synchronize, nxagentReady);
+    #endif
+
+    if (nxagentQueuedEvents(nxagentDisplay) > 0)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentBlockHandler: WARNING! Forcing a null timeout with events queued.\n");
+      #endif
+
+      zero.tv_sec  = 0;
+      zero.tv_usec = 0;
+
+      *timeout = &zero;
+    }
+  }
+
+  /*
+   * 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 number of ticks at the time
+   * the client is scheduled in.
+   */
+
+  #ifdef SMART_SCHEDULE
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentBlockHandler: Stopping the smart schedule timer.\n");
+  #endif
+
+  nxagentStopTimer();
+
+  #endif
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[End block]\n");
+  #endif
+}
+
+void nxagentWakeupHandler(pointer data, int count, pointer mask)
+{
+  #ifdef BLOCKS
+  fprintf(stderr, "[Begin wakeup]\n");
+  #endif
+
+  if (nxagentException.sigHup || nxagentException.ioError)
+  {
+    #ifdef TEST
+    fprintf(stderr,"nxagentWakeupHandler: Got SIGHUP or I/O error.\n");
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentBlockHandler: Calling nxagentHandleConnectionStates "
+                "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup);
+    #endif
+
+    nxagentHandleConnectionStates();
+  }
+
+  #ifdef SMART_SCHEDULE
+
+  if (SmartScheduleDisable == 1)
+  {
+
+  #endif
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentWakeupHandler: Resetting the dispatch state after wakeup.\n");
+    #endif
+
+    nxagentDispatch.start = GetTimeInMillis();
+
+    nxagentDispatch.in  = nxagentBytesIn;
+    nxagentDispatch.out = nxagentBytesOut;
+
+  #ifdef SMART_SCHEDULE
+
+  }
+
+  #endif
+
+  /*
+   * Can become true during the dispatch loop.
+   */
+
+  nxagentBlocking = 0;
+
+  /*
+   * Check if we got new events.
+   */
+
+  if (count > 0 && FD_ISSET(nxagentXConnectionNumber, (fd_set *) mask))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentWakeupHandler: Reading the X events with count [%d].\n",
+                count);
+    #endif
+
+    nxagentDispatchEvents(NULL);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentWakeupHandler: Removing the X descriptor from the count.\n");
+    #endif
+
+    FD_CLR(nxagentXConnectionNumber, (fd_set *) mask);
+
+    count--;
+  }
+  else if (nxagentQueuedEvents(nxagentDisplay) == 1)
+  {
+    /*
+     * We may have left some events in
+     * the queue.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentWakeupHandler: Reading the queued X events with count [%d].\n",
+                count);
+    #endif
+
+    nxagentDispatchEvents(NULL);
+  }
+
+  /*
+   * Save the number of descriptors ready.
+   */
+
+  if (count <= 0)
+  {
+    count = (XFD_ANYSET(&ClientsWithInput) ? 1 : 0);
+  }
+
+  nxagentReady = count;
+
+  #ifdef TEST
+
+  if (nxagentReady == 0)
+  {
+    fprintf(stderr, "nxagentWakeupHandler: No X clients found to be processed.\n");
+  }
+
+  #endif
+
+  /*
+   * If the XDM connection can't be established
+   * we'll need to create a dialog to notify the
+   * user and give him/her a chance to terminate
+   * the session.
+   */
+
+  if (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentWakeupHandler: XdmcpState [%d].\n", XdmcpState);
+    #endif
+
+    if (XdmcpState == XDM_RUN_SESSION)
+    {
+      nxagentXdmcpUp = 1;
+    }
+
+    if (nxagentXdmcpUp == 0)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentWakeupHandler: XdmcpTime [%lu].\n",
+                  GetTimeInMillis() - XdmcpStartTime);
+      #endif
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentWakeupHandler: XdmcpTimeOutRtx [%d].\n",
+                  XdmcpTimeOutRtx);
+      #endif
+
+      if (nxagentXdmcpAlertUp == 0 &&
+              GetTimeInMillis() - XdmcpStartTime >= XDM_TIMEOUT)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentWakeupHandler: WARNING! The XDM session seems to be "
+                    "unable to start after [%ld] ms.\n",(long int)(GetTimeInMillis() - XdmcpStartTime));
+        #endif
+
+        NXTransAlert(FAILED_XDMCP_CONNECTION_ALERT, NX_ALERT_REMOTE);
+
+        nxagentXdmcpAlertUp = 1;
+      }
+    }
+  }
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[End wakeup]\n");
+  #endif
+}
+
+void nxagentShadowBlockHandler(pointer data, struct timeval **timeout, pointer mask)
+{
+  static struct timeval zero;
+
+  int changed;
+  int suspended = 0;
+  int result;
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[Begin block]\n");
+  #endif
+
+  if (nxagentNeedConnectionChange() == 1)
+  {
+    nxagentHandleConnectionChanges();
+  }
+
+  if (nxagentSessionState == SESSION_DOWN)
+  {
+    usleep(50 * 1000);
+  }
+
+  #ifndef __CYGWIN32__
+
+  if (nxagentReadEvents(nxagentDisplay) > 0 ||
+          nxagentReadEvents(nxagentShadowDisplay) > 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowBlockHandler: Reading X events queued.\n");
+    #endif
+
+    nxagentDispatchEvents(NULL);
+  }
+
+  if (nxagentShadowResize == 1)
+  {
+    nxagentShadowResize = 0;
+
+    nxagentShadowAdaptToRatio();
+  }
+
+  #else
+
+  if (nxagentReadEvents(nxagentDisplay) > 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowBlockHandler: Reading X events queued.\n");
+    #endif
+
+    nxagentDispatchEvents(NULL);
+  }
+
+  #endif
+
+  changed = 0;
+
+  nxagentShadowPoll(nxagentShadowPixmapPtr, nxagentShadowGCPtr, nxagentShadowDepth, nxagentShadowWidth,
+                        nxagentShadowHeight, nxagentShadowBuffer, &changed, &suspended);
+
+  result = nxagentShadowSendUpdates(&suspended);
+
+  if (nxagentBlocking == 0)
+  {
+    nxagentSynchronizeDrawable((DrawablePtr) nxagentShadowPixmapPtr, DONT_WAIT,
+                                   ALWAYS_BREAK, nxagentShadowWindowPtr);
+  }
+
+  /*
+   * We are entering the select. Tell the NX
+   * transport to write any produced data to
+   * the remote end.
+   */
+/*
+FIXME: Must queue multiple writes and handle
+       the events by resembling the ordinary
+       block handler.
+*/
+
+  NXFlushDisplay(nxagentDisplay, NXFlushLink);
+
+  if (*timeout == NULL)
+  {
+    *timeout = &zero;
+  }
+
+  #ifdef __CYGWIN32__
+
+  usleep(50 * 1000);
+
+  (*timeout) -> tv_sec  = 0;
+  (*timeout) -> tv_usec = 50 * 1000;
+
+  #else
+
+  if (changed == 0)
+  {
+    (*timeout) -> tv_sec  = 0;
+    (*timeout) -> tv_usec = 50 * 1000;
+  }
+  else
+  {
+    (*timeout) -> tv_sec  = 0;
+    (*timeout) -> tv_usec = 0;
+  }
+
+  #endif
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[End block]\n");
+  #endif
+}
+
+void nxagentShadowWakeupHandler(pointer data, int count, pointer mask)
+{
+  #ifdef BLOCKS
+  fprintf(stderr, "[Begin wakeup]\n");
+  #endif
+
+  if (nxagentException.sigHup || nxagentException.ioError)
+  {
+    #ifdef TEST
+    fprintf(stderr,"nxagentShadowWakeupHandler: Got SIGHUP or I/O error.\n");
+    #endif
+
+    nxagentHandleConnectionStates();
+  }
+
+  #ifdef SMART_SCHEDULE
+
+  if (SmartScheduleDisable == 1)
+  {
+
+  #endif
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentShadowWakeupHandler: Resetting the dispatch state after wakeup.\n");
+    #endif
+
+    nxagentDispatch.start = GetTimeInMillis();
+
+    nxagentDispatch.in  = nxagentBytesIn;
+    nxagentDispatch.out = nxagentBytesOut;
+
+  #ifdef SMART_SCHEDULE
+
+  }
+
+  #endif
+
+  /*
+   * Can become true during the dispatch loop.
+   */
+
+  nxagentBlocking = 0;
+
+  /*
+   * Check if we got new events.
+   */
+
+  if (count > 0 && FD_ISSET(nxagentXConnectionNumber, (fd_set *) mask))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowWakeupHandler: Reading the X events with count [%d].\n",
+                count);
+    #endif
+
+    nxagentDispatchEvents(NULL);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowWakeupHandler: Removing the X descriptor from the count.\n");
+    #endif
+
+    FD_CLR(nxagentXConnectionNumber, (fd_set *) mask);
+
+    count--;
+  }
+  else if (nxagentQueuedEvents(nxagentDisplay) == 1)
+  {
+    /*
+     * We may have left some events in
+     * the queue.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowWakeupHandler: Reading the queued X events with count [%d].\n",
+                count);
+    #endif
+
+    nxagentDispatchEvents(NULL);
+  }
+
+  /*
+   * Save the number of descriptors ready.
+   */
+
+  if (count <= 0)
+  {
+    count = (XFD_ANYSET(&ClientsWithInput) ? 1 : 0);
+  }
+
+  nxagentReady = count;
+
+  #ifdef TEST
+
+  if (nxagentReady == 0)
+  {
+    fprintf(stderr, "nxagentShadowWakeupHandler: No X clients found to be processed.\n");
+  }
+
+  #endif
+
+  #ifdef BLOCKS
+  fprintf(stderr, "[End wakeup]\n");
+  #endif
+}
+
+void nxagentHandleCollectInputFocusEvent(int resource)
+{
+  Window window;
+  int revert_to;
+
+  if (NXGetCollectedInputFocus(nxagentDisplay, resource, &window, &revert_to) == 0)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentHandleCollectInputFocusEvent: PANIC! Failed to get the input focus "
+                "reply for resource [%d].\n", resource);
+    #endif
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentHandleCollectInputFocusEvent: Received a sync reply with [%d] pending.\n",
+              nxagentTokens.pending);
+  #endif
+
+  nxagentTokens.pending--;
+
+  nxagentCongestion = (nxagentTokens.pending >= TOKENS_PENDING_LIMIT / 2);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleCollectInputFocusEvent: Current congestion level is [%d].\n",
+              nxagentCongestion);
+  #endif
+}
+
+Bool nxagentCollectInputFocusPredicate(Display *display, XEvent *X, XPointer ptr)
+{
+  return (X -> xclient.window == 0 &&
+             X -> xclient.message_type == 0 &&
+                 X -> xclient.format == 32 &&
+                     X -> xclient.data.l[0] == NXCollectInputFocusNotify);
+}
+
+void nxagentDispatchHandler(ClientPtr client, int in, int out)
+{
+  /*
+   * This function is called by the dispatcher (with 0
+   * bytes out) after a new request has been processed.
+   * It is also called by the write handler (with 0
+   * bytes in) after more data has been written to the
+   * display. It may be optionally called in the block
+   * and wakeup handlers. In this case both in and out
+   * must be 0.
+   */
+
+  if (out > 0)
+  {
+    /*
+     * Called by the display write callback.
+     */
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDispatchHandler: Called with [%d] bytes written.\n",
+                out);
+    #endif
+
+    nxagentBytesOut += out;
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDispatchHandler: Total bytes are [%.0f] in [%.0f] out.\n",
+                nxagentBytesIn, nxagentBytesOut);
+    #endif
+
+    /*
+     * Don't take care of the synchronization if
+     * the NX transport is running. The NX trans-
+     * port has its own token-based control flow.
+     *
+     * We can't produce more output here because
+     * we are in the middle of the flush. We will
+     * take care of the sync requests when called
+     * by the dispatcher.
+     */
+
+    if (nxagentOption(LinkType) == LINK_TYPE_NONE)
+    {
+      nxagentTokens.soft += out;
+
+      if (out > BYTES_BEFORE_HARD_TOKEN)
+      {
+        nxagentTokens.hard += out;
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentDispatchHandler: Sync bytes accumulated are [%d] and [%d].\n",
+                  nxagentTokens.soft, nxagentTokens.hard);
+      #endif
+    }
+
+    #ifdef SMART_SCHEDULE
+
+    if (SmartScheduleDisable == 1)
+    {
+
+    #endif
+
+      /*
+       * Pay attention to the next client if this
+       * client produced enough output.
+       */
+
+      if  (nxagentBytesOut - nxagentDispatch.out > BYTES_BEFORE_YIELD)
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchHandler: Yielding with [%ld][%.0f][%.0f] for client [%d].\n",
+                    GetTimeInMillis() - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in,
+                        nxagentBytesOut - nxagentDispatch.out, nxagentDispatch.client);
+        #endif
+
+        nxagentDispatch.start = GetTimeInMillis();
+
+        nxagentDispatch.in  = nxagentBytesIn;
+        nxagentDispatch.out = nxagentBytesOut;
+
+        isItTimeToYield = 1;
+      }
+      #ifdef DEBUG
+      else
+      {
+        fprintf(stderr, "nxagentDispatchHandler: Dispatching with [%ld][%.0f][%.0f] for client [%d].\n",
+                    GetTimeInMillis() - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in,
+                        nxagentBytesOut - nxagentDispatch.out, nxagentDispatch.client);
+      }
+      #endif
+
+    #ifdef SMART_SCHEDULE
+
+    }
+
+    #endif
+
+    return;
+  }
+  else if (in > 0)
+  {
+    /*
+     * Called by the dispatcher.
+     */
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDispatchHandler: Called with [%d] bytes processed for client [%d].\n",
+                in, client -> index);
+    #endif
+
+    /*
+     * This is presently unused.
+     *
+     * nxagentClientAddBytes(client, in);
+     *
+     * #ifdef DEBUG
+     * fprintf(stderr, "nxagentDispatchHandler: Bytes processed for client [%d] are [%ld].\n",
+     *             client -> index, nxagentClientBytes(client));
+     * #endif
+     *
+     */
+
+    nxagentBytesIn += in;
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentDispatchHandler: Total bytes are [%.0f] in [%.0f] out.\n",
+                nxagentBytesIn, nxagentBytesOut);
+    #endif
+
+    /*
+     * When using the dumb scheduler, before reading from
+     * another client, the dispatcher tries to drain all
+     * the input from the client being processed. This
+     * means that, if isItTimeToYield is never set and the
+     * client never produces any output, we'll stick into
+     * the inner dispatch loop forever.
+     */
+
+    #ifdef SMART_SCHEDULE
+
+    if (SmartScheduleDisable == 1)
+    {
+
+    #endif
+
+      if  (client -> index != nxagentDispatch.client)
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentDispatchHandler: Resetting the dispatch state with [%d][%d].\n",
+                    nxagentDispatch.client, client -> index);
+        #endif
+
+        nxagentDispatch.client = client -> index;
+        nxagentDispatch.start  = GetTimeInMillis();
+
+        nxagentDispatch.in  = nxagentBytesIn;
+        nxagentDispatch.out = nxagentBytesOut;
+      }
+      else
+      {
+        static unsigned long int now;
+
+        now = GetTimeInMillis();
+
+        if (now - nxagentDispatch.start > TIME_BEFORE_YIELD ||
+                nxagentBytesIn - nxagentDispatch.in > BYTES_BEFORE_YIELD)
+        {
+          #ifdef DEBUG
+          fprintf(stderr, "nxagentDispatchHandler: Yielding with [%ld][%.0f][%.0f] for client [%d].\n",
+                      now - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in, nxagentBytesOut -
+                          nxagentDispatch.out, nxagentDispatch.client);
+          #endif
+
+          nxagentDispatch.start = now;
+
+          nxagentDispatch.in  = nxagentBytesIn;
+          nxagentDispatch.out = nxagentBytesOut;
+
+          isItTimeToYield = 1;
+        }
+        #ifdef DEBUG
+        else
+        {
+          fprintf(stderr, "nxagentDispatchHandler: Dispatching with [%ld][%.0f][%.0f] for client [%d].\n",
+                      now - nxagentDispatch.start, nxagentBytesIn - nxagentDispatch.in, nxagentBytesOut -
+                          nxagentDispatch.out, nxagentDispatch.client);
+        }
+        #endif
+      }
+
+    #ifdef SMART_SCHEDULE
+
+    }
+
+    #endif
+
+  }
+
+  /*
+   * Let's see if it's time to sync.
+   */
+
+  if (nxagentOption(LinkType) == LINK_TYPE_NONE)
+  {
+    if (nxagentTokens.hard > BYTES_BEFORE_HARD_TOKEN)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentDispatchHandler: Requesting a hard sync reply with [%d] bytes.\n",
+                  nxagentTokens.hard);
+      #endif
+
+      XSync(nxagentDisplay, 0);
+
+      if (nxagentPendingEvents(nxagentDisplay) > 0)
+      {
+        nxagentDispatchEvents(NULL);
+      }
+
+      nxagentTokens.soft  = 0;
+      nxagentTokens.hard  = 0;
+    }
+    else if (nxagentTokens.soft > BYTES_BEFORE_SOFT_TOKEN)
+    {
+      /*
+       * Alternatively, the amounts of bytes
+       * accounted for each sync request may
+       * be decreased according to the number
+       * of pending replies already awaited.
+       *
+       * else if (nxagentTokens.soft > (BYTES_BEFORE_SOFT_TOKEN / (nxagentTokens.pending + 1)))
+       */
+
+      int resource;
+
+      /*
+       * Wait eventually for the number of
+       * synchronization requests to return
+       * below the limit.
+       */
+
+      #ifdef TEST
+
+      if (nxagentTokens.pending == TOKENS_PENDING_LIMIT)
+      {
+        fprintf(stderr, "nxagentDispatchHandler: WARNING! Waiting for the synchronization reply.\n");
+      }
+
+      #endif
+
+      while (nxagentTokens.pending == TOKENS_PENDING_LIMIT)
+      {
+        if (nxagentWaitEvents(nxagentDisplay, NULL) == -1)
+        {
+          nxagentTokens.pending = 0;
+
+          nxagentTokens.soft = 0;
+
+          return;
+        }
+
+        nxagentDispatchEvents(NULL);
+
+        nxagentBlocking = 1;
+      }
+
+      /*
+       * Send a new synchronization request.
+       */
+
+      resource = nxagentWaitForResource(NXGetCollectInputFocusResource,
+                                            nxagentCollectInputFocusPredicate);
+
+      if (resource == -1)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentDispatchHandler: PANIC! Cannot allocate any valid resource.\n");
+        #endif
+
+        nxagentTokens.soft = 0;
+
+        return;
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentDispatchHandler: Requesting a sync reply with [%d] bytes "
+                  "and [%d] pending.\n", nxagentTokens.soft, nxagentTokens.pending);
+      #endif
+
+      NXCollectInputFocus(nxagentDisplay, resource);
+
+      NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+      if (nxagentPendingEvents(nxagentDisplay) > 0)
+      {
+        nxagentDispatchEvents(NULL);
+      }
+
+      nxagentTokens.pending++;
+
+      nxagentCongestion = (nxagentTokens.pending >= TOKENS_PENDING_LIMIT / 2);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentDispatchHandler: Current congestion level is [%d].\n",
+                  nxagentCongestion);
+      #endif
+
+      nxagentTokens.soft = 0;
+    }
+  }
+
+  /*
+   * Check if there are events to read.
+   */
+
+  if (nxagentPendingEvents(nxagentDisplay) > 0)
+  {
+    nxagentDispatchEvents(NULL);
+  }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
new file mode 100644
index 000000000..fc72c7060
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
@@ -0,0 +1,121 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Handlers_H__
+#define __Handlers_H__
+
+/*
+ * Current size of the display buffer.
+ */
+
+extern int nxagentBuffer;
+
+/*
+ * Set if we had to block waiting for
+ * the display to become writable.
+ */
+
+extern int nxagentBlocking;
+
+/*
+ * Current congestion level based on
+ * the sync requests awaited or the
+ * proxy tokens.
+ */
+
+extern int nxagentCongestion;
+
+/*
+ * Bytes read from the agent's clients
+ * and written to the display socket.
+ */
+
+extern double nxagentBytesIn;
+extern double nxagentBytesOut;
+
+/*
+ * Total number of descriptors ready
+ * as reported by the wakeup handler.
+ */
+
+extern int nxagentReady;
+
+/*
+ * Timestamp of the last write to the
+ * remote display.
+ */
+
+extern int nxagentFlush;
+
+/*
+ * Let the dispatch loop yield control to
+ * a different client after a fair amount
+ * of time or after enough data has been
+ * processed.
+ */
+
+struct _DispatchRec
+{
+  int client;
+
+  double in;
+  double out;
+
+  unsigned long start;
+};
+
+extern struct _DispatchRec nxagentDispatch;
+
+/*
+ * Ensure that we synchronize with the X
+ * server after a given amount of output
+ * is produced.
+ */
+
+struct _TokensRec
+{
+  int soft;
+  int hard;
+
+  int pending;
+};
+
+extern struct _TokensRec nxagentTokens;
+
+/*
+ * The agent's block and wakeup handlers.
+ */
+
+void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask);
+void nxagentWakeupHandler(pointer data, int count, pointer mask);
+
+/*
+ * Executed after each request processed.
+ */
+
+void nxagentDispatchHandler(ClientPtr client, int in, int out);
+
+void nxagentShadowBlockHandler(pointer data, struct timeval **timeout, pointer mask);
+void nxagentShadowWakeupHandler(pointer data, int count, pointer mask);
+
+extern GCPtr nxagentShadowGCPtr;
+extern unsigned char nxagentShadowDepth;
+extern int nxagentShadowWidth;
+extern int nxagentShadowHeight;
+extern char *nxagentShadowBuffer;
+
+#endif /* __Handlers_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.c b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
new file mode 100644
index 000000000..087d66017
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
@@ -0,0 +1,226 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <signal.h>
+#include <stdio.h>
+
+#ifdef _XSERVER64
+
+#include "scrnintstr.h"
+#include "Agent.h"
+#define GC XlibGC
+#define PIXEL_ALREADY_TYPEDEFED
+
+#endif /* _XSERVER64 */
+
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "resource.h"
+#include "../../include/gc.h"
+#include "../../include/window.h"
+
+#include "xpm.h"
+
+#include "Agent.h"
+#include "Pixmaps.h"
+#include "Display.h"
+#include "Holder.h"
+#include "Icons.h"
+
+#include NXAGENT_PLACEHOLDER_NAME
+
+#define MAXDEPTH 32
+
+#define PLACEHOLDER_WIDTH 14
+#define PLACEHOLDER_HEIGHT 16
+
+#define PLACEHOLDER_BORDER_COLOR_DARK 0x000000
+#define PLACEHOLDER_BORDER_COLOR_LIGHT 0xB2B2B2
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+static Pixmap nxagentPlaceholderPixmaps[MAXDEPTH + 1];
+
+void nxagentMarkPlaceholderNotLoaded(int depth)
+{
+  nxagentPlaceholderPixmaps[depth] = 0;
+}
+
+void nxagentInitPlaceholder(int depth)
+{
+  int status;
+  XpmAttributes attributes;
+
+  attributes.valuemask = XpmDepth | XpmSize;
+  attributes.depth = depth;
+
+  status = XpmCreatePixmapFromData(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                                       placeholderXpm, nxagentPlaceholderPixmaps + depth, NULL, &attributes);
+
+  if (status != Success)
+  {
+    FatalError("Error: Failed to create the placeholder pixmap.\n");
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitPlaceholder: Created pixmap [0x%lx] with geometry [%d,%d] for depth [%d].\n",
+              nxagentPlaceholderPixmaps[depth], attributes.width, attributes.height, depth);
+  #endif
+}
+
+void nxagentApplyPlaceholder(Drawable drawable, int x, int y,
+                                 int w, int h, int depth)
+{
+  /*
+   * Instead of the image, a white rectangle that
+   * covers the pixmap area is drawn, alongside
+   * with a black and grey line that outlines the
+   * boundaries of the affected area.
+   */
+
+  GC gc;
+  XGCValues value;
+  XPoint points[3];
+
+  value.foreground = 0xffffffff;
+  value.background = 0x00000000;
+  value.plane_mask = 0xffffffff;
+  value.fill_style = FillSolid;
+
+  /*
+   * FIXME: Should we use a gc cache to save
+   *        some bandwidth?
+   */
+
+  gc = XCreateGC(nxagentDisplay, drawable, GCBackground |
+           GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+  XFillRectangle(nxagentDisplay, drawable, gc, x, y, w, h);
+
+  if (depth == 1)
+  {
+    return;
+  }
+
+  value.foreground = PLACEHOLDER_BORDER_COLOR_DARK;
+  value.line_style = LineSolid;
+  value.line_width = 1;
+
+  points[0].x = x;
+  points[0].y = y + h - 1;
+  points[1].x = x;
+  points[1].y = y;
+  points[2].x = x + w - 1;
+  points[2].y = y;
+
+  XChangeGC(nxagentDisplay, gc, GCForeground | GCLineWidth | GCLineStyle, &value);
+  XDrawLines(nxagentDisplay, drawable, gc, points, 3, CoordModeOrigin);
+
+  value.foreground = PLACEHOLDER_BORDER_COLOR_LIGHT;
+  value.line_style = LineSolid;
+  value.line_width = 1;
+
+  points[0].x = x;
+  points[0].y = y + h - 1;
+  points[1].x = x + w - 1;
+  points[1].y = y + h - 1;
+  points[2].x = x + w - 1;
+  points[2].y = y;
+
+  XChangeGC(nxagentDisplay, gc, GCForeground | GCLineWidth | GCLineStyle, &value);
+  XDrawLines(nxagentDisplay, drawable, gc, points, 3, CoordModeOrigin);
+
+  /*
+   * We are going to apply place holder only if on region
+   * we have enough space for the placeholder plus three
+   * pixel for spacing and one for region border.
+   */
+
+  if ((w >= PLACEHOLDER_WIDTH + 8) && (h >= PLACEHOLDER_HEIGHT + 8))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentApplyPlaceholder: drawable %lx placeholder %lx from %d %d  pixmap size is %d %d "
+                        "depth %d\n", drawable, nxagentPlaceholderPixmaps[depth], x, y, w, h, depth);
+    #endif
+
+    if (nxagentPlaceholderPixmaps[depth] == 0)
+    {
+      nxagentInitPlaceholder(depth);
+    }
+
+    XCopyArea(nxagentDisplay, nxagentPlaceholderPixmaps[depth],
+                  drawable, gc, 0, 0, PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT, x + 4, y + 4);
+
+  }
+
+  XFreeGC(nxagentDisplay, gc);
+
+  return;
+}
+
+#ifdef DUMP
+
+static char hexdigit(char c)
+{
+  char map[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '?'};
+
+  return map[c];
+}
+
+/*
+FIXME: Please, check the implementation of the same
+       function in nxcomp.
+*/
+char *nxagentChecksum(char *string, int length)
+{
+  static char md5_output[MD5_DIGEST_LENGTH * 2 + 1];
+  static char md5[MD5_DIGEST_LENGTH];
+  char * ret;
+  int i;
+
+  memset(md5, 0, sizeof(md5));
+  memset(md5_output, 0, sizeof(md5_output));
+
+  ret = MD5(string, length, md5);
+
+  for (i = 0; i < MD5_DIGEST_LENGTH; i++)
+  {
+    char c = md5[i];
+
+    md5_output[i * 2 + 0] = hexdigit((c >> 0) & 0xF);
+    md5_output[i * 2 + 1] = hexdigit((c >> 4) & 0xF);
+  }
+
+  return md5_output;
+}
+
+#else
+
+const char *nxagentChecksum(char *data, int size)
+{
+  return "";
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.h b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
new file mode 100644
index 000000000..6dc2b8ed2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
@@ -0,0 +1,27 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Holder_H__
+#define __Holder_H__
+
+void nxagentMarkPlaceholderNotLoaded(int depth);
+void nxagentInitPlaceholder(int depth);
+void nxagentApplyPlaceholder(Drawable drawable, int x, int y, int w, int h, int depth);
+
+const char *nxagentChecksum(char *data, int size);
+
+#endif /* __Holder_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Icons.h b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
new file mode 100644
index 000000000..cb2e08521
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
@@ -0,0 +1,29 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Icons_H__
+#define __Icons_H__
+
+#define Pixel XpmPixel
+#include <X11/xpm.h>
+#undef Pixel
+
+#define NXAGENT_ICON_NAME  "nxagent.xpm"
+
+#define NXAGENT_PLACEHOLDER_NAME  "nxmissing.xpm"
+
+#endif /* __Icons_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
new file mode 100644
index 000000000..5108046b8
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -0,0 +1,1816 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Composite.h"
+#include "Display.h"
+#include "Visual.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+#include "Image.h"
+#include "Events.h"
+#include "Client.h"
+#include "Trap.h"
+#include "Split.h"
+#include "Args.h"
+#include "Screen.h"
+#include "Pixels.h"
+#include "Utils.h"
+
+#include "NXlib.h"
+#include "NXpack.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+/*
+ * Don't pack the images having a width, a
+ * height or a data size smaller or equal
+ * to these thresholds.
+ */
+
+#define IMAGE_PACK_WIDTH     2
+#define IMAGE_PACK_HEIGHT    2
+#define IMAGE_PACK_LENGTH    512
+
+/*
+ * Compress the image with a lossless encoder
+ * if the percentage of discrete pixels in the
+ * image is below this threshold.
+ */
+
+#define IMAGE_UNIQUE_RATIO   10
+
+/*
+ * Introduce a small delay after each image
+ * operation if the session is down. Value
+ * is in microseconds and is multiplied by
+ * the image data size in kilobytes.
+ */
+
+#define IMAGE_DELAY_IF_DOWN  250
+
+/*
+ * Preferred pack and split parameters we
+ * got from the NX transport.
+ */
+
+int nxagentPackLossless   = -1;
+int nxagentPackMethod     = -1;
+int nxagentPackQuality    = -1;
+int nxagentSplitThreshold = -1;
+
+/*
+ * Set if images can use the alpha channel.
+ */
+
+int nxagentAlphaEnabled = 0;
+int nxagentAlphaCompat  = 0;
+
+/*
+ * Used to reformat image when connecting to
+ * displays having different byte order.
+ */
+
+extern void BitOrderInvert(unsigned char *, int);
+extern void TwoByteSwap(unsigned char *, register int);
+extern void FourByteSwap(register unsigned char *, register int);
+
+/*
+ * Store the last visual used to unpack
+ * the images for the given client.
+ */
+
+static VisualID nxagentUnpackVisualId[MAX_CONNECTIONS];
+
+/*
+ * Store the last alpha data set for the
+ * client.
+ */
+
+typedef struct _UnpackAlpha
+{
+  char *data;
+  int size;
+
+} UnpackAlphaRec;
+
+typedef UnpackAlphaRec *UnpackAlphaPtr;
+
+static UnpackAlphaPtr nxagentUnpackAlpha[MAX_CONNECTIONS];
+
+/*
+ * Encode the imade alpha channel by using
+ * a specific encoding, separating it from
+ * the rest of the RGB data.
+ */
+
+static char *nxagentImageAlpha(XImage *ximage);
+static void nxagentSetUnpackAlpha(DrawablePtr pDrawable, XImage *pImage, ClientPtr pClient);
+
+/*
+ * Copy the source data to the destination.
+ */
+
+static char *nxagentImageCopy(XImage *source, XImage *destination);
+
+/*
+ * Return true if the image can be cached.
+ * Don't cache the images packed with the
+ * bitmap method as the encoding is little
+ * more expensive than a copy.
+ */
+
+#define nxagentNeedCache(image, method) \
+\
+  ((method) != PACK_BITMAP_16M_COLORS)
+
+/*
+ * With the bitmap encoding, if the image
+ * is 32 bits-per-pixel the 4th byte is not
+ * transmitted, so we don't need to clean
+ * the image.
+ */
+
+#define nxagentNeedClean(image, method) \
+\
+  ((method) == PACK_RLE_16M_COLORS || \
+       (method) == PACK_RGB_16M_COLORS || \
+           ((method) == PACK_BITMAP_16M_COLORS && \
+               image -> bits_per_pixel != 32))
+
+/*
+ * Collect the image cache statistics.
+ */
+
+typedef struct _ImageStatisticsRec
+{
+  double partialLookups;
+  double partialMatches;
+  double partialEncoded;
+  double partialAdded;
+
+  double totalLookups;
+  double totalMatches;
+  double totalEncoded;
+  double totalAdded;
+
+} ImageStatisticsRec;
+
+ImageStatisticsRec nxagentImageStatistics;
+
+int nxagentImageReformat(char *base, int nbytes, int bpp, int order)
+{
+  /*
+   * This is used whenever we need to swap the image data.
+   * If we got an image from a X server having a different
+   * endianess, we will need to redormat the image to match
+   * our own image-order so that ProcGetImage can return
+   * the expected format to the client.
+   */
+
+  switch (bpp)
+  {
+    case 1:
+    {
+      if (BITMAP_BIT_ORDER != order)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentImageReformat: Bit order invert with size [%d] "
+                    "bits per pixel [%d] byte order [%d].\n", nbytes, bpp, order);
+        #endif
+
+        BitOrderInvert((unsigned char *) base, nbytes);
+      }
+
+      #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+
+      nxagentImageReformat(base, nbytes, BITMAP_SCANLINE_UNIT, order);
+
+      #endif
+
+      break;
+    }
+    case 4:
+    case 8:
+    {
+      break;
+    }
+    case 16:
+    {
+      if (IMAGE_BYTE_ORDER != order)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentImageReformat: Two bytes swap with size [%d] "
+                    "bits per pixel [%d] byte order [%d].\n", nbytes, bpp, order);
+        #endif
+
+        TwoByteSwap((unsigned char *) base, nbytes);
+      }
+
+      break;
+    }
+    case 32:
+    {
+      if (IMAGE_BYTE_ORDER != order)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentImageReformat: Four bytes swap with size [%d] "
+                    "bits per pixel [%d] byte order [%d].\n", nbytes, bpp, order);
+        #endif
+
+        FourByteSwap((unsigned char *) base, nbytes);
+      }
+
+      break;
+    }
+  }
+
+  return 1;
+}
+
+int nxagentImageLength(int width, int height, int format, int leftPad, int depth)
+{
+  int line = 0;
+
+  if (format == XYBitmap)
+  {
+    line = BitmapBytePad(width + leftPad);
+  }
+  else if (format == XYPixmap)
+  {
+    line  = BitmapBytePad(width + leftPad);
+
+    line *= depth;
+  }
+  else if (format == ZPixmap)
+  {
+    line = PixmapBytePad(width, depth);
+  }
+
+  return line * height;
+}
+
+int nxagentImagePad(int width, int format, int leftPad, int depth)
+{
+  int line = 0;
+
+  if (format == XYBitmap)
+  {
+    line = BitmapBytePad(width + leftPad);
+  }
+  else if (format == XYPixmap)
+  {
+    line = BitmapBytePad(width + leftPad);
+  }
+  else if (format == ZPixmap)
+  {
+    line = PixmapBytePad(width, depth);
+  }
+
+  return line;
+}
+
+/*
+ * Only copy the data, not the structure.
+ * The data pointed by the destination is
+ * lost. Used to clone two images that
+ * point to the same data.
+ */
+
+char *nxagentImageCopy(XImage *source, XImage *destination)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentImageClone: Copying [%d] bytes of data from the source.\n",
+              source -> bytes_per_line * source -> height);
+  #endif
+
+  destination -> data = Xmalloc(source -> bytes_per_line * source -> height);
+
+  if (destination -> data == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentImageCopy: PANIC! Cannot allocate memory for the copy.\n");
+    #endif
+  }
+  else
+  {
+    memcpy(destination -> data, source -> data,
+               source -> bytes_per_line * source -> height);
+  }
+
+  return destination -> data;
+}
+
+char *nxagentImageAlpha(XImage *image)
+{
+  char *pData;
+
+  char *pSrcData;
+  char *pDstData;
+
+  int size;
+  int offset;
+
+  /*
+   * Use one byte per pixel.
+   */
+
+  size = (image -> bytes_per_line * image -> height) >> 2;
+
+  pData = Xmalloc(size);
+
+  if (pData == NULL)
+  {
+    return NULL;
+  }
+
+  /*
+   * The image is supposed to be in
+   * server order.
+   */
+
+  offset = (image -> byte_order == MSBFirst) ? 0 : 3;
+
+  pSrcData = image -> data;
+  pDstData = pData;
+
+  while (size-- > 0)
+  {
+    *pDstData++ = *(pSrcData + offset);
+
+    pSrcData += 4;
+  }
+
+  return pData;
+}
+
+/*
+ * Write down the image cache statistics
+ * to the buffer.
+ */
+
+void nxagentImageStatisticsHandler(char **buffer, int type)
+{
+/*
+FIXME: Agent cache statistics have to be implemented.
+*/
+  #ifdef TEST
+  fprintf(stderr, "nxagentImageStatisticsHandler: STATISTICS! Statistics requested to the agent.\n");
+  #endif
+
+  *buffer = NULL;
+}
+
+/*
+ * This should be called only for drawables
+ * having a depth of 32. In the other cases,
+ * it would only generate useless traffic.
+ */
+
+void nxagentSetUnpackAlpha(DrawablePtr pDrawable, XImage *pImage, ClientPtr pClient)
+{
+  int resource = pClient -> index;
+
+  unsigned int size = (pImage -> bytes_per_line * pImage -> height) >> 2;
+
+  char *data = nxagentImageAlpha(pImage);
+
+  if (data == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentSetUnpackAlpha: PANIC! Can't allocate data for the alpha channel.\n");
+    #endif
+
+    return;
+  }
+
+  /*
+   * If we are synchronizing the drawable, discard
+   * any unpack alpha stored for the client. The
+   * alpha data, in fact, may be still traveling
+   * and so we either wait until the end of the
+   * split or send a fresh copy.
+   */
+/*
+FIXME: Here the split trap is always set and so the caching of
+       the alpha channel is useless. I remember we set the trap
+       because of the cursor but why is it always set now?
+*/
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentSetUnpackAlpha: Checking alpha channel for client [%d] with trap [%d].\n",
+              resource, nxagentSplitTrap);
+  #endif
+
+  if (nxagentSplitTrap == 1 || nxagentUnpackAlpha[resource] == NULL ||
+          nxagentUnpackAlpha[resource] -> size != size ||
+              memcmp(nxagentUnpackAlpha[resource] -> data, data, size) != 0)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentSetUnpackAlpha: Sending alpha channel with width [%d] height [%d] "
+                "bytes per line [%d] size [%d].\n", pImage -> width, pImage -> height,
+                    pImage -> bytes_per_line, size);
+    #endif
+
+    /*
+     * Check if we are connected to a newer proxy
+     * version and so can send the alpha data in
+     * compressed form.
+     */
+
+    if (nxagentAlphaCompat == 0)
+    {
+      NXSetUnpackAlpha(nxagentDisplay, resource, PACK_NONE, size, data, size);
+    }
+    else
+    {
+      NXSetUnpackAlphaCompat(nxagentDisplay, resource, size, data);
+    }
+
+    if (nxagentUnpackAlpha[resource] != NULL)
+    {
+      Xfree(nxagentUnpackAlpha[resource] -> data);
+    }
+    else if ((nxagentUnpackAlpha[resource] = Xmalloc(sizeof(UnpackAlphaRec))) == NULL)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentSetUnpackAlpha: PANIC! Can't allocate data for the alpha structure.\n");
+      #endif
+
+      Xfree(data);
+
+      return;
+    }
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentSetUnpackAlpha: Saved alpha channel for client [%d] with size [%d].\n",
+                resource, size);
+    #endif
+
+    nxagentUnpackAlpha[resource] -> size = size;
+    nxagentUnpackAlpha[resource] -> data = data;
+  }
+  else
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentSetUnpackAlpha: Matched alpha channel for client [%d] with size [%d].\n",
+                resource, size);
+    #endif
+
+    Xfree(data);
+  }
+}
+
+/*
+ * The NX agent's implementation of the
+ * X server's image functions.
+ */
+
+void nxagentPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                         int dstX, int dstY, int dstWidth, int dstHeight,
+                             int leftPad, int format, char *data)
+{
+  int length;
+
+  RegionPtr pRegion = NullRegion;
+
+  int resource = 0;
+  int split    = 0;
+  int cache    = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPutImage: Image data at [%p] drawable [%s][%p] geometry [%d,%d,%d,%d].\n",
+              data, (pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window"),
+                  (void *) pDrawable, dstX, dstY, dstWidth, dstHeight);
+  #endif
+
+  /*
+   * If the display is down and there is not an
+   * nxagent attached, sleep for a while but
+   * still give a chance to the client to write
+   * to the framebuffer.
+   */
+
+  length = nxagentImageLength(dstWidth, dstHeight, format, leftPad, depth);
+
+  if (nxagentShadowCounter == 0 &&
+          NXDisplayError(nxagentDisplay) == 1)
+  {
+    int us;
+
+    us = IMAGE_DELAY_IF_DOWN * (length / 1024);
+
+    us = (us < 10000 ? 10000 : (us > 1000000 ? 1000000 : us));
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentPutImage: Sleeping for [%d] milliseconds with length [%d] and link down.\n",
+                us / 1000, length);
+    #endif
+
+    usleep(us);
+  }
+
+  /*
+   * This is of little use because clients usually write
+   * to windows only after an expose event, and, in the
+   * rare case they use a direct put image to the window
+   * (for a media player it should be a necessity), they
+   * are likely to monitor the visibility of the window.
+   */
+
+  if (nxagentOption(IgnoreVisibility) == 0 && pDrawable -> type == DRAWABLE_WINDOW &&
+          (nxagentWindowIsVisible((WindowPtr) pDrawable) == 0 ||
+              (nxagentDefaultWindowIsVisible() == 0 && nxagentCompositeEnable == 0)))
+  {
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on fully obscured "
+                "window at [%p].\n", (void *) pDrawable);
+    #endif
+
+    goto nxagentPutImageEnd;
+  }
+
+  /*
+   * This is more interesting. Check if the operation
+   * will produce a visible result based on the clip
+   * list of the window and the GC.
+   */
+
+  pRegion = nxagentCreateRegion(pDrawable, pGC, dstX, dstY, dstWidth, dstHeight);
+
+  if (REGION_NIL(pRegion) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on fully clipped "
+                "region [%d,%d,%d,%d] for drawable at [%p].\n", pRegion -> extents.x1,
+                    pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+                        (void *) pDrawable);
+    #endif
+
+    goto nxagentPutImageEnd;
+  }
+
+/*
+FIXME: Should use these.
+
+  int framebuffer = 1;
+  int realize     = 1;
+*/
+  if (nxagentGCTrap == 1 && nxagentReconnectTrap == 0 &&
+          nxagentFBTrap == 0 && nxagentShmTrap == 0)
+  {
+    if (pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      fbPutImage(nxagentVirtualDrawable(pDrawable), pGC, depth,
+                     dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+    }
+    else
+    {
+      fbPutImage(pDrawable, pGC, depth,
+                     dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+    }
+
+    goto nxagentPutImageEnd;
+  }
+
+  if (nxagentReconnectTrap == 0 &&
+          nxagentSplitTrap == 0)
+  {
+    if (pDrawable -> type == DRAWABLE_PIXMAP &&
+            nxagentFBTrap == 0 && nxagentShmTrap == 0)
+    {
+      fbPutImage(nxagentVirtualDrawable(pDrawable), pGC, depth,
+                     dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+    }
+    else if (pDrawable -> type == DRAWABLE_WINDOW)
+    {
+      fbPutImage(pDrawable, pGC, depth,
+                     dstX, dstY, dstWidth, dstHeight, leftPad, format, data);
+    }
+  }
+
+  /*
+   * We are going to realize the operation
+   * on the real display. Let's check if
+   * the link is down.
+   */
+
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    goto nxagentPutImageEnd;
+  }
+
+  /*
+   * Mark the region as corrupted and skip the operation
+   * if we went out of bandwidth. The drawable will be
+   * synchronized at later time. Don't do that if the
+   * image is likely to be a shape or a clip mask, if we
+   * are here because we are actually synchronizing the
+   * drawable or if the drawable's corrupted region is
+   * over-age.
+   */
+
+  if (NXAGENT_SHOULD_DEFER_PUTIMAGE(pDrawable))
+  {
+    if (pDrawable -> type == DRAWABLE_PIXMAP &&
+            pDrawable -> depth != 1 &&
+                nxagentOption(DeferLevel) >= 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+                  "for drawable at [%p] with drawable pixmap.\n", pRegion -> extents.x1,
+                      pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+                          (void *) pDrawable);
+      #endif
+  
+      nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+      goto nxagentPutImageEnd;
+    }
+
+    if (pDrawable -> type == DRAWABLE_WINDOW &&
+            nxagentOption(DeferLevel) >= 2)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentPutImage: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+                  "for drawable at [%p] with drawable window.\n", pRegion -> extents.x1,
+                      pRegion -> extents.y1, pRegion -> extents.x2, pRegion -> extents.y2,
+                          (void *) pDrawable);
+      #endif
+  
+      nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+      goto nxagentPutImageEnd;
+    }
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentPutImage: Operation on drawable [%p] not skipped with nxagentSplitTrap [%d].\n",
+                (void *) pDrawable, nxagentSplitTrap);
+  }
+  #endif
+
+  /*
+   * Check whether we need to enclose the
+   * image in a split sequence.
+   */
+/*
+FIXME: Should we disable the split with link LAN?
+
+  split = (nxagentOption(Streaming) == 1 &&
+               nxagentOption(LinkType) != LINK_TYPE_NONE &&
+                   nxagentOption(LinkType) != LINK_TYPE_LAN
+*/
+  split = (nxagentOption(Streaming) == 1 &&
+               nxagentOption(LinkType) != LINK_TYPE_NONE
+/*
+FIXME: Do we stream the images from GLX or Xv? If we do that,
+       we should also write on the frame buffer, including the
+       images put on windows, to be able to reconstruct the
+       region that is out of sync. Surely we should not try to
+       cache the GLX and Xv images in memory or save them in
+       the image cache on disk.
+*/
+/*
+FIXME: Temporarily stream the GLX data.
+
+                           && nxagentGlxTrap == 0
+                               && nxagentXvTrap == 0
+*/
+);
+
+  /*
+   * Never split images whose depth
+   * is less than 15.
+   */
+
+  if (split == 1 && (nxagentSplitTrap == 1 || depth < 15))
+  {
+    #ifdef TEST
+
+    if (nxagentSplitTrap == 1 ||
+            nxagentReconnectTrap == 1)
+    {
+      fprintf(stderr, "nxagentPutImage: Not splitting with reconnection [%d] trap [%d] "
+                  "depth [%d].\n", nxagentSplitTrap, nxagentReconnectTrap, depth);
+    }
+
+    #endif
+
+    split = 0;
+  }
+  #ifdef TEST
+  else if (split == 1)
+  {
+    fprintf(stderr, "nxagentPutImage: Splitting with reconnection [%d] trap [%d] "
+                "depth [%d].\n", nxagentSplitTrap, nxagentReconnectTrap, depth);
+  }
+  #endif
+
+  #ifdef TEST
+
+  if (split == 1)
+  {
+    fprintf(stderr, "nxagentPutImage: Splitting the image with size [%d] "
+                "link [%d] GLX [%d] Xv [%d].\n", length, nxagentOption(LinkType),
+                    nxagentGlxTrap, nxagentXvTrap);
+  }
+  else if (nxagentOption(LinkType) != LINK_TYPE_NONE)
+  {
+    fprintf(stderr, "nxagentPutImage: Not splitting the image with size [%d] "
+                "link [%d] GLX [%d] Xv [%d].\n", length, nxagentOption(LinkType),
+                    nxagentGlxTrap, nxagentXvTrap);
+  }
+
+  #endif
+
+  /*
+   * If the image was originated by a GLX
+   * or Xvideo request, temporarily disable
+   * the use of the cache.
+   */
+
+  if (nxagentOption(LinkType) != LINK_TYPE_NONE &&
+          (nxagentGlxTrap == 1 || nxagentXvTrap == 1))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentPutImage: Disabling the use of the cache with GLX or Xvideo.\n");
+    #endif
+
+    NXSetCacheParameters(nxagentDisplay, 0, 1, 0, 0);
+
+    cache = 0;
+  }
+
+  /*
+   * Enclose the next messages in a split
+   * sequence. The proxy will tell us if
+   * the split took place.
+   */
+
+  if (split == 1)
+  {
+    /*
+     * If the drawable is already being split,
+     * expand the region. Currently drawables
+     * can't have more than a single split
+     * region.
+     */
+
+    if (nxagentSplitResource(pDrawable) != NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentPutImage: WARNING! Expanding the region with drawable at [%p] streaming.\n",
+                  (void *) pDrawable);
+      #endif
+/*
+FIXME: Should probably intersect the region with
+       the region being split to also invalidate
+       the commits.
+*/
+      nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+      goto nxagentPutImageEnd;
+    }
+    else
+    {
+      /*
+       * Assign a new resource to the drawable.
+       * Will also assign the GC to use for the
+       * operation.
+       */
+
+      resource = nxagentCreateSplit(pDrawable, &pGC);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentPutImage: Resource [%d] assigned to drawable at [%p].\n",
+                  resource, (void *) pDrawable);
+      #endif
+    }
+
+    NXStartSplit(nxagentDisplay, resource, NXSplitModeDefault);
+  }
+
+  nxagentRealizeImage(pDrawable, pGC, depth, dstX, dstY,
+                          dstWidth, dstHeight, leftPad, format, data);
+
+  if (split == 1)
+  {
+    NXEndSplit(nxagentDisplay, resource);
+
+    /*
+     * Now we need to check if all the messages went
+     * straight through the output stream or any of
+     * them required a split. If no split will take
+     * place, we will remove the association with the
+     * drawable and release the resource at the time
+     * we will handle the no-split event.
+     */
+
+    split = nxagentWaitSplitEvent(resource);
+
+    if (split == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentPutImage: Marking corrupted region [%d,%d,%d,%d] for drawable at [%p].\n",
+                  pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2,
+                      pRegion -> extents.y2, (void *) pDrawable);
+      #endif
+
+      /*
+       * Marking the corrupted region we will check
+       * if the region intersects the split region,
+       * therefore the split region must be added
+       * later.
+       */
+
+      nxagentMarkCorruptedRegion(pDrawable, pRegion);
+
+      /*
+       * Assign the region to the drawable.
+       */
+
+      nxagentRegionSplit(pDrawable, pRegion);
+
+      pRegion = NullRegion;
+    }
+  }
+
+  /*
+   * The split value could be changed by a
+   * no-split event in the block above, so
+   * here we have to check the value again.
+   */
+
+  if (split == 0)
+  {
+    if (nxagentDrawableStatus(pDrawable) == NotSynchronized)
+    {
+      /*
+       * We just covered the drawable with
+       * a solid image. We can consider the
+       * overlapping region as synchronized.
+       */
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentPutImage: Marking synchronized region [%d,%d,%d,%d] for drawable at [%p].\n",
+                  pRegion -> extents.x1, pRegion -> extents.y1, pRegion -> extents.x2,
+                      pRegion -> extents.y2, (void *) pDrawable);
+      #endif
+
+      nxagentUnmarkCorruptedRegion(pDrawable, pRegion);
+    }
+  }
+
+nxagentPutImageEnd:
+
+  /*
+   * Check if we disabled caching.
+   */
+
+  if (cache == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentPutImage: Reenabling the use of the cache.\n");
+    #endif
+
+    NXSetCacheParameters(nxagentDisplay, 1, 1, 1, 1);
+  }
+
+  if (pRegion != NullRegion)
+  {
+    nxagentFreeRegion(pDrawable, pRegion);
+  }
+}
+
+void nxagentRealizeImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                             int x, int y, int w, int h, int leftPad,
+                                 int format, char *data)
+{
+  int length;
+
+  int bytesPerLine;
+  int numSubImages;
+  int totalHeight;
+
+  const int subSize = (MAX_REQUEST_SIZE << 2) - sizeof(xPutImageReq);
+
+  Visual *pVisual = NULL;
+
+  RegionPtr clipRegion = NullRegion;
+
+  XImage *image = NULL;
+
+
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentRealizeImage: Returning on display error.\n");
+    #endif
+
+    goto nxagentRealizeImageEnd;
+  }
+
+  /*
+   * Get the visual according to the
+   * drawable and depth.
+   */
+
+  pVisual = nxagentImageVisual(pDrawable, depth);
+
+  if (pVisual == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentRealizeImage: WARNING! Visual not found. Using default visual.\n");
+    #endif
+    
+    pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+  } 
+
+  /*
+   * Get bytes per line according to format.
+   */
+
+  bytesPerLine = nxagentImagePad(w, format, leftPad, depth);
+
+  if (nxagentOption(Shadow) == 1 && format == ZPixmap &&
+          (nxagentOption(XRatio) != DONT_SCALE ||
+              nxagentOption(YRatio) != DONT_SCALE) &&
+                  pDrawable == (DrawablePtr) nxagentShadowPixmapPtr)
+  {
+    int scaledx;
+    int scaledy;
+
+    image = XCreateImage(nxagentDisplay, pVisual, depth, ZPixmap,
+                             0, data, w, h, BitmapPad(nxagentDisplay), bytesPerLine);
+
+    if (image != NULL)
+    {
+      image -> byte_order = IMAGE_BYTE_ORDER;
+
+      image -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+      nxagentScaleImage(x, y, nxagentOption(XRatio), nxagentOption(YRatio),
+                            &image, &scaledx, &scaledy);
+
+      x = scaledx;
+      y = scaledy;
+
+      w = image -> width;
+      h = image -> height;
+
+      data = image -> data;
+
+      /*
+       * Width of image has changed.
+       */
+
+      bytesPerLine = nxagentImagePad(w, format, leftPad, depth);
+    }
+    #ifdef WARNING
+    else
+    {
+      fprintf(stderr, "nxagentRealizeImage: Failed to create XImage for scaling.\n");
+    }
+    #endif
+  }
+
+  if (w == 0 || h == 0)
+  {
+    goto nxagentRealizeImageEnd;
+  }
+
+  totalHeight = h;
+
+  length = bytesPerLine * h;
+
+  h = (subSize < length ? subSize : length) / bytesPerLine;
+
+  numSubImages = totalHeight / h + 1;
+
+  while (numSubImages > 0)
+  {
+    if (pDrawable -> type == DRAWABLE_WINDOW)
+    {
+      clipRegion = nxagentCreateRegion(pDrawable, pGC, x, y, w, h);
+    }
+
+    if (clipRegion == NullRegion || REGION_NIL(clipRegion) == 0)
+    {
+      nxagentPutSubImage(pDrawable, pGC, depth, x, y, w, h,
+                             leftPad, format, data, pVisual);
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentRealizeImage: Skipping the put sub image with geometry "
+                  "[%d,%d,%d,%d] on hidden window at [%p].\n", x, y, w, h, (void *) pDrawable);
+    }
+    #endif
+
+    if (clipRegion != NullRegion)
+    {
+      nxagentFreeRegion(pDrawable, clipRegion);
+    }
+
+    y += h;
+
+    data += h * bytesPerLine;
+
+    if (--numSubImages == 1)
+    {
+      h = totalHeight % h;
+
+      if (h == 0)
+      {
+        break;
+      }
+    }
+  }
+
+nxagentRealizeImageEnd:
+
+  if (image != NULL)
+  {
+    XDestroyImage(image);
+  }
+}
+
+void nxagentPutSubImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                            int x, int y, int w, int h, int leftPad, int format,
+                                char *data, Visual *pVisual)
+{
+  NXPackedImage *packedImage    = NULL;
+  XImage        *plainImage     = NULL;
+  unsigned char *packedChecksum = NULL;
+
+  unsigned int packMethod  = nxagentPackMethod;
+  unsigned int packQuality = nxagentPackQuality;
+
+  ClientPtr client;
+
+  int lossless = 0;
+  int clean    = 0;
+  int pack     = 0;
+
+  /*
+   * XCreateImage is the place where the leftPad should be passed.
+   * The image data is received from our client unmodified. In
+   * theory what we would need to do is just creating an appropri-
+   * ate XImage structure based on the incoming data and let Xlib
+   * do the rest. Probably we don't have to pass leftPad again in
+   * the src_x of XPutImage otherwise the src_x would make Xlib
+   * to take into account the xoffset field twice. Unfortunately
+   * passing the leftPad doesn't work.
+   *
+   * plainImage = XCreateImage(nxagentDisplay, pVisual,
+   *                           depth, format, leftPad, data,
+   *                           w, h, BitmapPad(nxagentDisplay),
+   *                           nxagentImagePad(w, format, leftPad, depth));
+   */
+
+  if ((plainImage = XCreateImage(nxagentDisplay, pVisual,
+                                 depth, format, leftPad, data,
+                                 w, h, BitmapPad(nxagentDisplay),
+                                 nxagentImagePad(w, format, leftPad, depth))) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentPutSubImage: WARNING! Failed to create image.\n");
+    #endif
+
+    goto nxagentPutSubImageEnd;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentPutSubImage: Handling image with geometry [%d,%d] depth [%d].\n",
+              w, h, depth);
+
+  fprintf(stderr, "nxagentPutSubImage: Default pack method is [%d] quality is [%d].\n",
+              packMethod, packQuality);
+  #endif
+
+/*
+FIXME: Should use an unpack resource here.
+*/
+  client = requestingClient;
+
+  if (client == NULL)
+  {
+    client = serverClient;
+ 
+    #ifdef TEST
+    fprintf(stderr, "nxagentPutSubImage: WARNING! Using the server client with index [%d].\n",
+                client -> index);
+    #endif
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPutSubImage: Server order is [%d] client order is [%d].\n",
+              nxagentServerOrder(), nxagentClientOrder(client));
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPutSubImage: Display image order is [%d] bitmap order is [%d].\n",
+              ImageByteOrder(nxagentDisplay), BitmapBitOrder(nxagentDisplay));
+  #endif
+
+  /*
+   * We got the image data from the X client or
+   * from the frame-buffer with our own endianess.
+   * Byte swap the image data if the display has
+   * a different endianess than our own.
+   */
+
+  if (nxagentImageNormalize(plainImage) != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentPutSubImage: WARNING! Reformatted the image with remote order [%d/%d].\n",
+                plainImage -> byte_order, plainImage -> bitmap_bit_order);
+    #endif
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPutSubImage: Image has visual with RGB color masks [%0lx][%0lx][%0lx].\n",
+              pVisual -> red_mask, pVisual -> green_mask, pVisual -> blue_mask);
+  #endif
+
+  /*
+   * Check if the user requested to pack the
+   * image but don't pack it if we are not
+   * connected to a proxy or if the depth is
+   * less than 15 bpp.
+   */
+
+  pack = (nxagentOption(LinkType) != LINK_TYPE_NONE &&
+              packMethod != PACK_NONE && depth > 8);
+
+  lossless = (packMethod == nxagentPackLossless);
+
+  if (pack == 1 && lossless == 0)
+  {
+    /*
+     * Force the image to be sent as a plain
+     * bitmap if we don't have any lossless
+     * encoder available.
+     */
+
+    if (w <= IMAGE_PACK_WIDTH || h <= IMAGE_PACK_HEIGHT ||
+            nxagentImageLength(w, h, format, leftPad, depth) <=
+                IMAGE_PACK_LENGTH || nxagentLosslessTrap == 1)
+    {
+      if (nxagentPackLossless == PACK_NONE)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentPutSubImage: Disabling pack with lossless method [%d] "
+                    "trap [%d] size [%d].\n", nxagentPackLossless, nxagentLosslessTrap,
+                        nxagentImageLength(w, h, format, leftPad, depth));
+        #endif
+
+        pack = 0;
+      }
+      else
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentPutSubImage: Lossless encoder with geometry [%d,%d] "
+                    "trap [%d] size [%d].\n", w, h, nxagentLosslessTrap,
+                        nxagentImageLength(w, h, format, leftPad, depth));
+        #endif
+
+        packMethod = nxagentPackLossless;
+
+        lossless = 1;
+      }
+    }
+  }
+
+  /*
+   * Do we still want to pack the image?
+   */
+
+  if (pack == 1)
+  {
+    /*
+     * Set the geometry and alpha channel
+     * to be used for the unpacked image.
+     */
+
+    if (nxagentUnpackVisualId[client -> index] != pVisual -> visualid)
+    {
+      nxagentUnpackVisualId[client -> index] = pVisual -> visualid;
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentPutSubImage: Sending new geometry for client [%d].\n",
+                  client -> index);
+      #endif
+
+      NXSetUnpackGeometry(nxagentDisplay, client -> index, pVisual);
+    }
+
+    /*
+     * Check if the image is supposed to carry
+     * the alpha data in the fourth byte and,
+     * if so, send the alpha channel using the
+     * specific encoding.
+     */
+
+    if (plainImage -> depth == 32)
+    {
+      nxagentSetUnpackAlpha(pDrawable, plainImage, client);
+    }
+
+    /*
+     * If the image doesn't come from the XVideo or the
+     * GLX extension try to locate it in the cache. The
+     * case of the lossless trap is also special, as we
+     * want to eventually encode the image again using
+     * a lossless compression.
+     */
+/*
+FIXME: Should try to locate the image anyway, if the lossless
+       trap is set, and if the image was encoded by a lossy
+       compressor, roll back the changes and encode the image
+       again using the preferred method.
+*/
+    if (nxagentNeedCache(plainImage, packMethod) &&
+            nxagentGlxTrap == 0 && nxagentXvTrap == 0 &&
+                nxagentLosslessTrap == 0 && NXImageCacheSize > 0)
+    {
+      /*
+       * Be sure that the padding bits are
+       * cleaned before calculating the MD5
+       * checksum.
+       */
+/*
+FIXME: There should be a callback registered by the agent that
+       provides a statistics report, in text format, telling
+       for example how many images were searched in the cache,
+       how many were found, how many drawables are to be synch-
+       ronized, etc. This statistics report would be included
+       by the proxy in its stat output.
+*/
+      clean = 1;
+
+      NXCleanImage(plainImage);
+
+      /*
+       * Will return a pointer to the image and checksum
+       * taken from the cache, if found. If the image is
+       * not found, the function returns a null image and
+       * a pointer to the calculated checksum. It is up
+       * to the application to free the memory. We will
+       * use the checksum to add the image in the cache.
+       */
+
+      packedImage = NXCacheFindImage(plainImage, &packMethod, &packedChecksum);
+
+      nxagentImageStatistics.partialLookups++;
+      nxagentImageStatistics.totalLookups++;
+
+      if (packedImage != NULL)
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentPutSubImage: Matched image of geometry [%d,%d] data size [%d] in cache.\n",
+                    w, h, packedImage -> xoffset);
+        #endif
+
+        NXPutPackedImage(nxagentDisplay, client -> index, nxagentDrawable(pDrawable),
+                             nxagentGC(pGC), packedImage, packMethod, depth,
+                                 0, 0, x, y, w, h);
+
+        nxagentImageStatistics.partialMatches++;
+        nxagentImageStatistics.totalMatches++;
+
+        packedChecksum = NULL;
+        packedImage    = NULL;
+
+        goto nxagentPutSubImageEnd;
+      }
+      #ifdef DEBUG
+      else
+      {
+        fprintf(stderr, "nxagentPutSubImage: WARNING! Missed image of geometry [%d,%d] in cache.\n",
+                    w, h);
+      }
+      #endif
+    }
+
+    /*
+     * If a specific encoder was not mandated,
+     * try to guess if a lossless encoder will
+     * compress better.
+     */
+
+    if (lossless == 0 && nxagentOption(Adaptive) == 1)
+    {
+      int ratio = nxagentUniquePixels(plainImage);
+
+      if (ratio <= IMAGE_UNIQUE_RATIO)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentPutSubImage: Lossless encoder with geometry [%d,%d] ratio [%d%%].\n",
+                    w, h, ratio);
+        #endif
+
+        packMethod = nxagentPackLossless;
+
+        lossless = 1;
+      }
+      #ifdef TEST
+      else
+      {
+        fprintf(stderr, "nxagentPutSubImage: Default encoder with geometry [%d,%d] ratio [%d%%].\n",
+                    w, h, ratio);
+      }
+      #endif
+    }
+
+    /*
+     * Encode the image using the selected
+     * pack method.
+     */
+
+    if (packMethod == PACK_RLE_16M_COLORS ||
+            packMethod == PACK_RGB_16M_COLORS ||
+                packMethod == PACK_BITMAP_16M_COLORS)
+    {
+      /*
+       * Cleanup the image if we didn't do that yet.
+       * We assume that the JPEG and PNG compression
+       * methods will actually ignore the padding
+       * bytes. In other words, bitmap images prod-
+       * ucing the same visual output should produce
+       * compressed images that are bitwise the same
+       * regardless the padding bits.
+       */
+
+      if (clean == 0)
+      {
+        if (nxagentNeedClean(plainImage, packMethod) == 1)
+        {
+          clean = 1;
+
+          NXCleanImage(plainImage);
+        }
+      }
+
+      switch (packMethod)
+      {
+        /*
+         * If nothing is done by the bitmap encoder,
+         * it saves an allocation and a memory copy
+         * by setting the data field of the packed
+         * image to the original data. We need to
+         * check this at the time we will free the
+         * packed image.
+         */
+
+        case PACK_BITMAP_16M_COLORS:
+        {
+          packedImage = NXEncodeBitmap(plainImage, packMethod, packQuality);
+
+          break;
+        }
+        case PACK_RGB_16M_COLORS:
+        {
+          packedImage = NXEncodeRgb(plainImage, packMethod, packQuality);
+
+          break;
+        }
+        default:
+        {
+          packedImage = NXEncodeRle(plainImage, packMethod, packQuality);
+
+          break;
+        }
+      }
+    }
+    else if (packMethod >= PACK_JPEG_8_COLORS &&
+                 packMethod <= PACK_JPEG_16M_COLORS)
+    {
+      packedImage = NXEncodeJpeg(plainImage, packMethod, packQuality);
+    }
+    else if (packMethod >= PACK_PNG_8_COLORS &&
+                 packMethod <= PACK_PNG_16M_COLORS)
+    {
+      packedImage = NXEncodePng(plainImage, packMethod, packQuality);
+    }
+    else if (packMethod != PACK_NONE)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentPutSubImage: WARNING! Ignoring deprecated pack method [%d].\n",
+                  packMethod);
+      #endif
+
+      packMethod = PACK_NONE;
+    }
+  }
+
+  /*
+   * If we didn't produce a valid packed
+   * image, send the image as a X bitmap.
+   */
+
+  if (packedImage != NULL)
+  {
+    nxagentImageStatistics.partialEncoded++;
+    nxagentImageStatistics.totalEncoded++;
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentPutSubImage: Using packed image with method [%d] quality [%d] "
+                "geometry [%d,%d] data size [%d].\n", packMethod, packQuality,
+                    w, h, packedImage -> xoffset);
+    #endif
+
+    NXPutPackedImage(nxagentDisplay, client -> index, nxagentDrawable(pDrawable),
+                         nxagentGC(pGC), packedImage, packMethod, depth,
+                             0, 0, x, y, w, h);
+
+    /*
+     * Add the image only if we have a valid
+     * checksum. This is the case only if we
+     * originally tried to find the image in
+     * cache.
+     */
+      
+    if (NXImageCacheSize > 0 && packedChecksum != NULL)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentPutSubImage: Adding image with geometry [%d,%d] data size [%d] "
+                  "to the cache.\n", w, h, packedImage -> xoffset);
+      #endif
+
+      /*
+       * Check if both the plain and the packed
+       * image point to the same data. In this
+       * case we need a copy.
+       */
+
+      if (packedImage -> data == plainImage -> data &&
+              nxagentImageCopy(plainImage, packedImage) == NULL)
+      {
+        goto nxagentPutSubImageEnd;
+      }
+
+      NXCacheAddImage(packedImage, packMethod, packedChecksum);
+
+      nxagentImageStatistics.partialAdded++;
+      nxagentImageStatistics.totalAdded++;
+
+      packedChecksum = NULL;
+      packedImage    = NULL;
+    }
+  }
+  else
+  {
+    /*
+     * Clean the image to help the proxy to match
+     * the checksum in its cache. Do that only if
+     * the differential compression is enabled and
+     * if the image is not supposed to carry the
+     * alpha data in the fourth byte of the pixel.
+     */
+/*
+FIXME: If we failed to encode the image by any of the available
+       methods, for example if we couldn't allocate memory, we
+       may need to ripristinate the alpha channel, that in the
+       meanwhile was sent in the unpack alpha message. This can
+       be done here, if the clean flag is true and we are going
+       to send a plain image.
+*/
+    if (clean == 0)
+    {
+      clean = (nxagentOption(LinkType) != LINK_TYPE_NONE &&
+                   nxagentOption(LinkType) != LINK_TYPE_LAN && depth != 32);
+
+      if (clean == 1)
+      {
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentPutSubImage: Cleaning the image with link type [%d] and depth [%d].\n",
+                    nxagentOption(LinkType), depth);
+        #endif
+
+        NXCleanImage(plainImage);
+      }
+      #ifdef DEBUG
+      else
+      {
+        fprintf(stderr, "nxagentPutSubImage: Not cleaning the image with link type [%d] and depth [%d].\n",
+                    nxagentOption(LinkType), depth);
+      }
+      #endif
+    }
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentPutSubImage: Calling XPutImage with geometry [%d,%d] and data size [%d].\n",
+                w, h, plainImage -> bytes_per_line * plainImage -> height);
+    #endif
+
+    /*
+     * Passing the leftPad value in src_x doesn't work.
+     *
+     * XPutImage(nxagentDisplay, nxagentDrawable(pDrawable),
+     *               nxagentGC(pGC), plainImage, leftPad, 0, x, y, w, h);
+     */
+
+    XPutImage(nxagentDisplay, nxagentDrawable(pDrawable),
+                  nxagentGC(pGC), plainImage, 0, 0, x, y, w, h);
+  }
+
+nxagentPutSubImageEnd:
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPutSubImage: Performed [%.0f] lookups in the cache with [%.0f] matches.\n",
+              nxagentImageStatistics.totalLookups, nxagentImageStatistics.totalMatches);
+
+  fprintf(stderr, "nxagentPutSubImage: Encoded [%.0f] images with [%.0f] added to the cache.\n",
+              nxagentImageStatistics.totalEncoded, nxagentImageStatistics.totalAdded);
+  #endif
+
+  if (packedChecksum != NULL)
+  {
+    Xfree(packedChecksum);
+  }
+
+  if (packedImage != NULL)
+  {
+    if (packedImage -> data != NULL &&
+            packedImage -> data != plainImage -> data)
+    {
+      Xfree(packedImage -> data);
+    }
+
+    Xfree(packedImage);
+  }
+
+  Xfree(plainImage);
+}
+
+void nxagentGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+                         unsigned int format, unsigned long planeMask, char *data)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentGetImage: Called with drawable at [%p] geometry [%d,%d,%d,%d].\n",
+              (void *) pDrawable, x, y, w, h);
+
+  fprintf(stderr, "nxagentGetImage: Format is [%d] plane mask is [%lx].\n",
+              format, planeMask);
+  #endif
+
+  if ((pDrawable)->type == DRAWABLE_PIXMAP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentGetImage: Going to get image from virtual pixmap at [%p].\n",
+                (void *) nxagentVirtualDrawable(pDrawable));
+    #endif
+
+    fbGetImage(nxagentVirtualDrawable(pDrawable), x, y, w, h, format, planeMask, data);
+  }
+  else
+  {
+    fbGetImage(pDrawable, x, y, w, h, format, planeMask, data);
+  }
+}
+
+/*
+ * We have to reset the visual cache before
+ * connecting to another display, so that a
+ * new unpack geometry can be communicated
+ * to the new proxy.
+ */
+
+void nxagentResetVisualCache()
+{
+  int i;
+
+  for (i = 0; i < MAX_CONNECTIONS; i++)
+  {
+    nxagentUnpackVisualId[i] = None;
+  }
+}
+
+void nxagentResetAlphaCache()
+{
+  int i;
+
+  for (i = 0; i < MAX_CONNECTIONS; i++)
+  {
+    if (nxagentUnpackAlpha[i])
+    {
+      Xfree(nxagentUnpackAlpha[i] -> data);
+
+      Xfree(nxagentUnpackAlpha[i]);
+
+      nxagentUnpackAlpha[i] = NULL;
+    }
+  }
+}
+
+int nxagentScaleImage(int x, int y, unsigned xRatio, unsigned yRatio,
+                          XImage **pImage, int *scaledx, int *scaledy)
+{
+  int x1;
+  int x2;
+  int y1;
+  int y2;
+
+  int xx1;
+  int xx2;
+  int yy1;
+  int yy2;
+
+  int newWidth;
+  int newHeight;
+
+  int i;
+  int j;
+  int k;
+  int l;
+
+  unsigned long val;
+
+  XImage *newImage;
+  XImage *image = *pImage;
+
+  #ifdef FAST_GET_PUT_PIXEL
+
+  register char *srcPixel;
+  register char *dstPixel;
+
+  int i;
+
+  #endif
+
+  if (image == NULL)
+  {
+    return 0;
+  }
+
+  x1 = (xRatio * x) >> PRECISION;
+  x2 = (xRatio * (x + image -> width)) >> PRECISION;
+
+  y1 = (yRatio * y) >> PRECISION;
+  y2 = (yRatio * (y + image -> height)) >> PRECISION;
+
+  newWidth = x2 - x1;
+  newHeight = y2 - y1;
+
+  newImage = XCreateImage(nxagentDisplay, NULL, image -> depth, image -> format, 0, NULL,
+                              newWidth, newHeight, BitmapPad(nxagentDisplay),
+                                  PixmapBytePad(newWidth, image -> depth));
+
+  if (newImage == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentScaleImage: PANIC! Failed to create the target image.\n");
+    #endif
+
+    return 0;
+  }
+
+  newImage -> red_mask   = image -> red_mask;
+  newImage -> green_mask = image -> green_mask;
+  newImage -> blue_mask  = image -> blue_mask;
+
+  newImage -> byte_order = IMAGE_BYTE_ORDER;
+  newImage -> bitmap_bit_order = BITMAP_BIT_ORDER;
+
+  newImage -> data = Xmalloc(newImage -> bytes_per_line * newHeight);
+
+  if (newImage -> data == NULL)
+  {
+    Xfree(newImage);
+    
+    #ifdef PANIC
+    fprintf(stderr, "nxagentScaleImage: PANIC! Failed to create the target image data.\n");
+    #endif
+
+    return 0;
+  }
+
+  newImage -> width  = newWidth;
+  newImage -> height = newHeight;
+
+  for (j = y; j < y + image -> height; j++)
+  {
+    yy1 = (yRatio * j) >> PRECISION;
+    yy2 = (yRatio * (j + 1)) >> PRECISION;
+
+    for (i = x; i < x + image -> width; i++)
+    {
+      #ifndef FAST_GET_PUT_PIXEL
+
+      val = XGetPixel(image, i - x, j - y);
+
+      #else
+
+      srcPixel = &image -> data[(j * image -> bytes_per_line) +
+                                  ((i * image -> bits_per_pixel) >> 3)];
+
+      dstPixel = (char *) &val;
+
+      val = 0;
+
+      for (i = (image -> bits_per_pixel + 7) >> 3; --i >= 0; )
+      {
+        *dstPixel++ = *srcPixel++;
+      }
+
+      #endif
+
+      xx1 = (xRatio * i) >> PRECISION;
+      xx2 = (xRatio * (i + 1)) >> PRECISION;
+
+      for (l = yy1; l < yy2; l++)
+      {
+        for (k = xx1; k < xx2; k++)
+        {
+          #ifndef FAST_GET_PUT_PIXEL
+
+          XPutPixel(newImage, k - x1, l - y1, val);
+
+          #else
+
+          dstPixel = &newImage -> data[((l - y1) * newImage -> bytes_per_line) +
+                                           (((k - x1) * newImage -> bits_per_pixel) >> 3)];
+
+          srcPixel = (char *) &val;
+
+          for (i = (newImage -> bits_per_pixel + 7) >> 3; --i >= 0; )
+          {
+            *dstPixel++ = *srcPixel++;
+          }
+
+          #endif
+        }
+      }
+    }
+  }
+
+  if (image -> obdata != NULL)
+  {
+    Xfree((char *) image -> obdata);
+  }
+
+  Xfree((char *) image);
+
+  *pImage = newImage;
+
+  *scaledx = x1;
+  *scaledy = y1;
+
+  return 1;
+}
+
+char *nxagentAllocateImageData(int width, int height, int depth, int *length, int *format)
+{
+  char *data;
+
+  int leftPad;
+
+  leftPad = 0;
+
+  *format = (depth == 1) ? XYPixmap : ZPixmap;
+
+  *length = nxagentImageLength(width, height, *format, leftPad, depth);
+
+  data = NULL;
+
+  if ((data = xalloc(*length)) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentAllocateImageData: WARNING! Failed to allocate [%d] bytes of memory.\n", *length);
+    #endif
+  }
+
+  return data;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.h b/nx-X11/programs/Xserver/hw/nxagent/Image.h
new file mode 100644
index 000000000..fb77f3c80
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.h
@@ -0,0 +1,108 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Image_H__
+#define __Image_H__
+
+/*
+ * Graphic operations.
+ */
+
+void nxagentPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                         int dstX, int dstY, int dstWidth, int dstHeight,
+                             int leftPad, int format, char *data);
+
+void nxagentRealizeImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                             int x, int y, int w, int h, int leftPad,
+                                 int format, char *data);
+
+void nxagentPutSubImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+                            int x, int y, int w, int h, int leftPad, int format,
+                                char *data, Visual *pVisual);
+
+void nxagentGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+                         unsigned int format, unsigned long planeMask, char *data);
+
+/*
+ * Pack and split parameters we get
+ * from the NX transport.
+ */
+
+extern int nxagentPackLossless;
+extern int nxagentPackMethod;
+extern int nxagentPackQuality;
+extern int nxagentSplitThreshold;
+
+/*
+ * Set if images can use the alpha
+ * channel and if the alpha channel
+ * can be sent in compressed form.
+ */
+
+extern int nxagentAlphaEnabled;
+extern int nxagentAlphaCompat;
+
+/*
+ * Reset the visual and alpha cache
+ * before closing the screen or con-
+ * necting to a different display.
+ */
+
+void nxagentResetVisualCache(void);
+void nxagentResetAlphaCache(void);
+
+/*
+ * Always use the default visual for the
+ * image related functions.
+ */
+
+#define nxagentImageVisual(pDrawable, depth) \
+    ((depth) == 32 ? &nxagentAlphaVisual : \
+         nxagentDefaultVisual(((pDrawable) -> pScreen)))
+
+/*
+ * Byte swap the image if the display
+ * uses a different endianess.
+ */
+
+#define nxagentImageNormalize(image) \
+    ((image) -> byte_order != IMAGE_BYTE_ORDER || \
+         (image) -> bitmap_bit_order != BITMAP_BIT_ORDER ? \
+             nxagentImageReformat((image) -> data, (image) -> bytes_per_line * \
+                 (image) -> height * ((image) -> format == XYPixmap ? (image) -> depth : 1), \
+                     ((image) -> format == ZPixmap ? \
+                         BitsPerPixel((image) -> depth) : 1), \
+                             (image) -> byte_order) : 0)
+
+/*
+ * Other image related functions.
+ */
+
+int nxagentImageLength(int width, int height, int format, int leftPad, int depth);
+
+int nxagentImagePad(int width, int format, int leftPad, int depth);
+
+int nxagentImageReformat(char *base, int nbytes, int bpp, int order);
+
+void nxagentImageStatisticsHandler(char **buffer, int type);
+
+int nxagentScaleImage(int x, int y, unsigned xRatio, unsigned yRatio, XImage **pImage, int *scaledx, int *scaledy);
+
+char *nxagentAllocateImageData(int width, int height, int depth, int *length, int *format);
+
+#endif /* __Image_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
new file mode 100644
index 000000000..804f95f78
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -0,0 +1,220 @@
+# 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 =  NXrandr.c \
+        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 =  NXrandr.o \
+        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 \
+          -UPANORAMIX
+
+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/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
new file mode 100644
index 000000000..197bd8c14
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -0,0 +1,491 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 <sys/types.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "fontstruct.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Pointer.h"
+#include "Keyboard.h"
+#include "Handlers.h"
+#include "Init.h"
+#include "Args.h"
+#include "Client.h"
+#include "Options.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+#include "Font.h"
+#include "Millis.h"
+#include "Error.h"
+
+#include "NX.h"
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+#define NXAGENT_VERSION  "3.1.0"
+
+/*
+ * ProcVector array defined in tables.c.
+ */
+
+extern int (*ProcVector[256])(ClientPtr);
+
+/*
+ * From the fb code.
+ */
+
+extern int fbGCPrivateIndex;
+
+/*
+ * Stubs for the DPMS extension.
+ */
+
+#ifdef DPMSExtension
+
+void DPMSSet(int level);
+int DPMSGet(int *level);
+Bool DPMSSupported(void);
+
+#endif
+
+/*
+ * Our error logging function.
+ */
+
+void OsVendorVErrorFFunction(const char *f, va_list args);
+
+/*
+ * True if this is a fatal error.
+ */
+
+extern int OsVendorVErrorFFatal;
+
+/*
+ * Redirect the error output to a
+ * different file
+ */
+
+extern void (*OsVendorStartRedirectErrorFProc)();
+extern void (*OsVendorEndRedirectErrorFProc)();
+
+void OsVendorStartRedirectErrorFFunction();
+void OsVendorEndRedirectErrorFFunction();
+
+/*
+ * Called by InitGlobals() in the
+ * new X server tree.
+ */
+
+#ifdef NXAGENT_UPGRADE
+
+void ddxInitGlobals(void)
+{
+  /*
+   * Install our error logging function.
+   */
+
+  OsVendorVErrorFProc = OsVendorVErrorFFunction;
+
+  OsVendorStartRedirectErrorFProc = OsVendorStartRedirectErrorFFunction;
+  OsVendorEndRedirectErrorFProc   = OsVendorEndRedirectErrorFFunction;
+}
+
+#endif
+
+/*
+ * Set if the remote display supports
+ * backing store.
+ */
+/*
+FIXME: These, if not removed, should at least
+       be moved to Display.h and Display.c.
+*/
+int nxagentBackingStore;
+int nxagentSaveUnder;
+
+/*
+ * This is true at startup and set to the value of
+ * nxagentFullGeneration at the end of InitInput.
+ *
+ *   InitOutput
+ *      nxagentOpenDisplay (if nxagentDoFullGeneration)
+ *         nxagentCloseDisplay (if (nxagentDoFullGeneration && nxagentDisplay))
+ *            nxagentFree*
+ *      nxagentListRemoteFonts
+ *      AddScreen
+ *         nxagentOpenScreen
+ *   InitInput
+ */
+
+int nxagentDoFullGeneration = 1;
+
+/*
+ * Called at X server's initialization.
+ */
+
+void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
+{
+  char *authority;
+  int i;
+
+  #ifdef __sun
+
+  char *environment;
+
+  #endif
+
+  /*
+   * Print our pid and version information.
+   */
+
+  if (serverGeneration <= 1)
+  {
+    fprintf(stderr, "\nNXAGENT - Version " NXAGENT_VERSION "\n\n");
+    fprintf(stderr, "Copyright (C) 2001, 2007 NoMachine.\n");
+    fprintf(stderr, "See http://www.nomachine.com/ for more information.\n\n");
+
+    fprintf(stderr, "Info: Agent running with pid '%d'.\n", getpid());
+
+    fprintf(stderr, "Session: Starting session at '%s'.\n", GetTimeAsString());
+  }
+
+  /*
+   * Unset the LD_LIBRARY_PATH variable in
+   * Popen() before calling execl() in the
+   * child process.
+   */
+
+  NXUnsetLibraryPath(1);
+
+  if (nxagentUserDefinedFontPath == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "InitOutput: Calling nxagentVerifyDefaultFontPath.\n");
+    #endif
+
+    nxagentVerifyDefaultFontPath();
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "InitOutput: User defined font path. Skipping the check on the fonts dir.\n");
+  }
+  #endif
+
+  if ((authority = getenv("NX_XAUTHORITY")))
+  {
+    #ifdef __sun
+
+    environment = malloc(15 + strlen(authority));
+
+    sprintf(environment, "XAUTHORITY=%s", authority);
+
+    if (putenv(environment) < 0)
+
+    #else
+
+    if (setenv("XAUTHORITY", authority, True) < 0)
+
+    #endif
+
+    {
+      fprintf(stderr, "Warning: Couldn't set the XAUTHORITY environment to [%s]\n",
+                  authority);
+    }
+  }
+
+  nxagentInitBSPixmapList();
+
+  /*
+   * Open the display. We are at the early startup and
+   * the information we'll get from the remote X server
+   * will mandate some of the characteristics of the
+   * session, like the screen depth. Note that this re-
+   * liance on the remote display at session startup
+   * should be removed. We should always operate at 32
+   * bpp, internally, and do the required translations
+   * as soon as the graphic operation needs to be real-
+   * ized on the remote display.
+   */
+
+  nxagentOpenDisplay(argc, argv);
+
+/*
+FIXME: These variables, if not removed at all because have probably
+       become useless, should be moved to Display.h and Display.c.
+*/
+  nxagentBackingStore = XDoesBackingStore(DefaultScreenOfDisplay(nxagentDisplay));
+
+  #ifdef TEST
+  fprintf(stderr, "InitOutput: Remote display backing store support [%d].\n",
+              nxagentBackingStore);
+  #endif
+
+  nxagentSaveUnder = XDoesSaveUnders(DefaultScreenOfDisplay(nxagentDisplay));
+
+  #ifdef TEST
+  fprintf(stderr, "InitOutput: Remote display save under support [%d].\n",
+              nxagentSaveUnder);
+  #endif
+
+  /*
+   * Initialize the basic screen info.
+   */
+
+  nxagentSetScreenInfo(screenInfo);
+
+  /*
+   * Initialize pixmap formats for this screen.
+   */
+
+  nxagentSetPixmapFormats(screenInfo);
+
+  /*
+   * Get our own privates' index.
+   */
+
+  nxagentWindowPrivateIndex = AllocateWindowPrivateIndex();
+  nxagentGCPrivateIndex = AllocateGCPrivateIndex();
+  RT_NX_GC = CreateNewResourceType(nxagentDestroyNewGCResourceType);
+  nxagentFontPrivateIndex = AllocateFontPrivateIndex();
+  RT_NX_FONT = CreateNewResourceType(nxagentDestroyNewFontResourceType); 
+  nxagentClientPrivateIndex = AllocateClientPrivateIndex();
+  nxagentPixmapPrivateIndex = AllocatePixmapPrivateIndex();
+  RT_NX_PIXMAP = CreateNewResourceType(nxagentDestroyNewPixmapResourceType); 
+
+  RT_NX_CORR_BACKGROUND = CreateNewResourceType(nxagentDestroyCorruptedBackgroundResource);
+  RT_NX_CORR_WINDOW = CreateNewResourceType(nxagentDestroyCorruptedWindowResource);
+  RT_NX_CORR_PIXMAP = CreateNewResourceType(nxagentDestroyCorruptedPixmapResource);
+
+  fbGCPrivateIndex = AllocateGCPrivateIndex();
+
+  if (nxagentNumScreens == 0)
+  {
+    nxagentNumScreens = 1;
+  }
+
+  for (i = 0; i < nxagentNumScreens; i++)
+  {
+    AddScreen(nxagentOpenScreen, argc, argv);
+  }
+
+  nxagentNumScreens = screenInfo->numScreens;
+
+  /*
+   * Initialize the GCs used by the synchro-
+   * nization put images. We do it here beca-
+   * use we use the nxagentDefaultScreen.
+   */
+
+  nxagentAllocateGraphicContexts();
+
+  nxagentDoFullGeneration = nxagentFullGeneration;
+}
+
+void InitInput(argc, argv)
+     int argc;
+     char *argv[];
+{
+  pointer ptr, kbd;
+
+  ptr = AddInputDevice(nxagentPointerProc, True);
+  kbd = AddInputDevice(nxagentKeyboardProc, True);
+
+  RegisterPointerDevice(ptr);
+  RegisterKeyboardDevice(kbd);
+
+  mieqInit(kbd, ptr);
+
+  /*
+   * Add the display descriptor to the
+   * set of descriptors awaited by the
+   * dispatcher.
+   */
+
+  nxagentAddXConnection();
+
+  if (nxagentOption(Shadow))
+  {
+    RegisterBlockAndWakeupHandlers(nxagentShadowBlockHandler, nxagentShadowWakeupHandler, NULL);
+  }
+  else
+  {
+    RegisterBlockAndWakeupHandlers(nxagentBlockHandler, nxagentWakeupHandler, NULL);
+  }
+
+  /*
+   * We let the proxy flush the link on our behalf
+   * after having opened the display. We are now
+   * entering the dispatcher. From now on we'll
+   * flush the proxy link explicitly.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "InitInput: Setting the NX flush policy to deferred.\n");
+  #endif
+
+  NXSetDisplayPolicy(nxagentDisplay, NXPolicyDeferred);
+}
+
+/*
+ * DDX specific abort routine. This is called
+ * by AbortServer() that, in turn, is called
+ * by FatalError().
+ */
+
+void AbortDDX()
+{
+  nxagentDoFullGeneration = True;
+
+  nxagentCloseDisplay();
+
+  /*
+   * Do the required finalization if we
+   * are not going through the normal
+   * X server shutdown.
+   */
+
+  if ((dispatchException & DE_TERMINATE) == 0)
+  {
+    nxagentAbortDisplay();
+  }
+}
+
+/*
+ * Called by GiveUp().
+ */
+
+void ddxGiveUp()
+{
+  AbortDDX();
+}
+
+#ifdef NXAGENT_UPGRADE
+
+void ddxBeforeReset(void)
+{
+}
+
+#endif
+
+void OsVendorInit()
+{
+  return;
+}
+
+void OsVendorFatalError()
+{
+  /*
+   * Let the session terminate gracely
+   * from an user's standpoint.
+   */
+
+  fprintf(stderr, "Session: Aborting session at '%s'.\n", GetTimeAsString());
+
+  fprintf(stderr, "Session: Session aborted at '%s'.\n", GetTimeAsString());
+}
+
+void OsVendorVErrorFFunction(const char *f, va_list args)
+{
+  if (OsVendorVErrorFFatal == 0)
+  {
+    char buffer[1024];
+
+    vsnprintf(buffer, sizeof(buffer), f, args);
+
+    nxagentStartRedirectToClientsLog();
+
+    fprintf(stderr, buffer);
+
+    nxagentEndRedirectToClientsLog();
+  }
+  else
+  {
+    LogVWrite(-1, f, args);
+  }
+}
+
+void OsVendorStartRedirectErrorFFunction()
+{
+  nxagentStartRedirectToClientsLog();
+}
+
+void OsVendorEndRedirectErrorFFunction()
+{
+  nxagentEndRedirectToClientsLog();
+}
+
+/* this is just to get the server to link on AIX */
+#ifdef AIXV3
+int SelectWaitTime = 10000; /* usec */
+#endif
+
+#ifdef DPMSExtension
+
+void DPMSSet(int level)
+{
+}
+
+int DPMSGet(int *level)
+{
+  return -1;
+}
+
+Bool DPMSSupported(void)
+{
+  return 1;
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
new file mode 100644
index 000000000..63e27bada
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h
@@ -0,0 +1,40 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Init_H__
+#define __Init_H__
+
+extern int nxagentDoFullGeneration;
+
+extern int nxagentBackingStore;
+extern int nxagentSaveUnder;
+
+#endif /* __Init_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
new file mode 100644
index 000000000..dbdfc5b19
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -0,0 +1,1359 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "keysym.h"
+#include "screenint.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Keyboard.h"
+#include "Events.h"
+#include "Options.h"
+
+#include "NXlib.h"
+
+#ifdef XKB
+
+#include <X11/extensions/XKB.h>
+#include <X11/extensions/XKBsrv.h>
+#include <X11/extensions/XKBconfig.h>
+
+#endif /* XKB */
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  WATCH
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+/*
+ * Unfortunately we cannot just include XKBlib.h.
+ * It conflicts with the server side definitions
+ * of the same symbols. This is more a X problem
+ * than our.
+ */
+
+#ifdef XKB
+
+extern Bool XkbQueryExtension(
+#if NeedFunctionPrototypes
+        Display *        /* dpy */,
+        int *            /* opcodeReturn */,
+        int *            /* eventBaseReturn */,
+        int *            /* errorBaseReturn */,
+        int *            /* majorRtrn */,
+        int *            /* minorRtrn */
+#endif
+);
+
+extern        XkbDescPtr XkbGetKeyboard(
+#if NeedFunctionPrototypes
+        Display *        /* dpy */,
+        unsigned int     /* which */,
+        unsigned int     /* deviceSpec */
+#endif
+);
+
+extern        Status        XkbGetControls(
+#if NeedFunctionPrototypes
+        Display *        /* dpy */,
+        unsigned long    /* which */,
+        XkbDescPtr       /* desc */
+#endif
+);
+
+#ifndef XKB_BASE_DIRECTORY
+#define XKB_BASE_DIRECTORY   "/usr/share/X11/xkb"
+#endif
+#ifndef XKB_ALTERNATE_BASE_DIRECTORY
+#define XKB_ALTERNATE_BASE_DIRECTORY   "/usr/X11R6/lib/X11/xkb"
+#endif
+#ifndef XKB_CONFIG_FILE
+#define XKB_CONFIG_FILE      "X0-config.keyboard"
+#endif
+#ifndef XKB_DFLT_RULES_FILE
+#define XKB_DFLT_RULES_FILE  "xfree86"
+#endif
+#ifndef XKB_ALTS_RULES_FILE
+#define XKB_ALTS_RULES_FILE  "xorg"
+#endif
+#ifndef XKB_DFLT_KB_LAYOUT
+#define XKB_DFLT_KB_LAYOUT   "us"
+#endif
+#ifndef XKB_DFLT_KB_MODEL
+#define XKB_DFLT_KB_MODEL    "pc102"
+#endif
+#ifndef XKB_DFLT_KB_VARIANT
+#define XKB_DFLT_KB_VARIANT  NULL
+#endif
+#ifndef XKB_DFLT_KB_OPTIONS
+#define XKB_DFLT_KB_OPTIONS  NULL
+#endif
+
+#define NXAGENT_KEYMAP_DIR_FILE "keymap.dir"
+
+extern int XkbDfltRepeatDelay;
+extern int XkbDfltRepeatInterval;
+
+#endif /* XKB */
+
+/*
+ * Save the values queried from X server.
+ */
+
+XkbAgentInfoRec nxagentXkbInfo = { -1, -1, -1, -1, -1 };
+
+/*
+ * Keyboard status, updated through XKB
+ * events.
+ */
+
+XkbAgentStateRec nxagentXkbState = { 0, 0, 0, 0, 0 };
+
+/*
+ * Info for disabling/enabling Xkb extension.
+ */
+
+XkbWrapperRec nxagentXkbWrapper;
+
+extern char *nxagentKeyboard;
+
+static char *nxagentXkbGetRules(void);
+
+unsigned int nxagentAltMetaMask;
+
+void nxagentCheckAltMetaKeys(CARD8, int);
+
+static int nxagentSaveKeyboardDeviceData(DeviceIntPtr dev, DeviceIntPtr devBackup);
+
+static int nxagentRestoreKeyboardDeviceData(DeviceIntPtr devBackup, DeviceIntPtr dev);
+
+static int nxagentFreeKeyboardDeviceData(DeviceIntPtr dev);
+
+static void nxagentCheckXkbBaseDirectory(void)
+{
+
+  /*
+   * Set XkbBaseDirectory global
+   * variable appropriately.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+              "Before calling _NXGetXkbBasePath.\n");
+
+  fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+              "XkbBaseDirectory varible [%s].\n",
+                  XkbBaseDirectory);
+  #endif
+
+  XkbBaseDirectory = _NXGetXkbBasePath(XkbBaseDirectory);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+              "After calling _NXGetXkbBasePath.\n");
+
+  fprintf(stderr, "nxagentCheckXkbBaseDirectory: "
+              "XkbBaseDirectory varible [%s].\n",
+                  XkbBaseDirectory);
+  #endif
+
+  return;
+}
+
+static char *nxagentXkbGetRules()
+{
+  int ret;
+  int size, sizeDflt, sizeAlt;
+  char *path;
+  struct stat buf;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentXkbGetRules: XkbBaseDirectory [%s].\n",
+              XkbBaseDirectory);
+  #endif
+
+  sizeDflt = strlen(XKB_DFLT_RULES_FILE);
+  sizeAlt = strlen(XKB_ALTS_RULES_FILE);
+  size = strlen(XkbBaseDirectory) + strlen("/rules/");
+  size += (sizeDflt > sizeAlt) ? sizeDflt: sizeAlt;
+
+  if ((path = malloc((size + 1) * sizeof(char))) == NULL)
+  {
+    FatalError("nxagentXkbGetRules: malloc failed.");
+  }
+
+  strcpy(path, XkbBaseDirectory);
+  strcat(path, "/rules/");
+  strcat(path, XKB_DFLT_RULES_FILE);
+  ret = stat(path, &buf);
+
+  if (ret == 0)
+  {
+    free(path);
+    return XKB_DFLT_RULES_FILE;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentXkbGetRules: WARNING! Failed to stat file [%s]: %s.\n", path, strerror(ret));
+  #endif 
+
+  strcpy(path, XkbBaseDirectory);
+  strcat(path, "/rules/");
+  strcat(path, XKB_ALTS_RULES_FILE);
+  ret = stat(path, &buf);
+
+  if (ret == 0)
+  {
+    free(path);
+    return XKB_ALTS_RULES_FILE;
+  }
+
+  #ifdef WARNING
+  fprintf(stderr, "nxagentXkbGetRules: WARNING! Failed to stat file [%s]: %s.\n", path, strerror(ret));
+  #endif
+
+  free(path);
+  return XKB_DFLT_RULES_FILE;
+}
+ 
+void nxagentBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
+{
+  XBell(nxagentDisplay, volume);
+}
+
+void nxagentChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
+{
+  #ifdef XKB
+
+  XkbSrvInfoPtr  xkbi;
+  XkbControlsPtr xkbc;
+
+  if (!noXkbExtension)
+  {
+    xkbi = pDev -> key -> xkbInfo;
+    xkbc = xkbi -> desc -> ctrls;
+
+    /*
+     * We want to prevent agent generating auto-repeated
+     * keystrokes. Let's intercept any attempt by appli-
+     * cations to change the default timeouts on the
+     * nxagent device.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentChangeKeyboardControl: Repeat delay was [%d] interval was [%d].\n",
+                xkbc -> repeat_delay, xkbc -> repeat_interval);
+    #endif
+
+    xkbc -> repeat_delay = ~ 0;
+    xkbc -> repeat_interval = ~ 0;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentChangeKeyboardControl: Repeat delay is now [%d] interval is now [%d].\n",
+                xkbc -> repeat_delay, xkbc -> repeat_interval);
+    #endif
+  }
+
+  #endif
+
+  /*
+   * If enabled, propagate the changes to the
+   * devices attached to the real X server.
+   */
+
+  if (nxagentOption(DeviceControl) == True)
+  {
+    unsigned long value_mask;
+    XKeyboardControl values;
+    int i;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentChangeKeyboardControl: WARNING! Propagating changes to keyboard settings.\n");
+    #endif
+
+    value_mask = KBKeyClickPercent |
+                 KBBellPercent |
+                 KBBellPitch |
+                 KBBellDuration;
+
+    values.key_click_percent = ctrl->click;
+    values.bell_percent = ctrl->bell;
+    values.bell_pitch = ctrl->bell_pitch;
+    values.bell_duration = ctrl->bell_duration;
+
+    /*
+     * Don't propagate the auto repeat mode. It is forced to be
+     * off in the agent server.
+     *
+     * value_mask |= KBAutoRepeatMode;
+     * values.auto_repeat_mode = ctrl->autoRepeat ?
+     *                          AutoRepeatModeOn : AutoRepeatModeOff;
+     */
+
+    XChangeKeyboardControl(nxagentDisplay, value_mask, &values);
+
+    /*
+     * At this point, we need to walk through the vector and
+     * compare it to the current server vector. If there are
+     * differences, report them.
+     */
+
+    value_mask = KBLed | KBLedMode;
+
+    for (i = 1; i <= 32; i++)
+    {
+      values.led = i;
+      values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
+
+      XChangeKeyboardControl(nxagentDisplay, value_mask, &values);
+    }
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentChangeKeyboardControl: WARNING! Not propagating changes to keyboard settings.\n");
+  #endif
+}
+
+int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff)
+{
+  XModifierKeymap *modifier_keymap;
+  KeySym *keymap;
+  int mapWidth;
+  int min_keycode, max_keycode;
+  KeySymsRec keySyms;
+  CARD8 modmap[256];
+  int i, j;
+  XKeyboardState values;
+  char *model = NULL, *layout = NULL;
+  int free_model = 0, free_layout = 0;
+  XkbDescPtr xkb = NULL;
+
+  int ret;
+
+  switch (onoff)
+  {
+    case DEVICE_INIT:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_INIT].\n");
+      #endif
+
+      if (NXDisplayError(nxagentDisplay) == 1)
+      {
+        return Success;
+      }
+
+      #ifdef WATCH
+
+      fprintf(stderr, "nxagentKeyboardProc: Watchpoint 9.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+N/A
+*/
+
+      sleep(30);
+
+      #endif
+
+      /*
+       * Prevent agent from generating auto-repeat keystroke.
+       * Note that this is working only if XKB is enabled.
+       * A better solution should account cases where XKB is
+       * not available. Check also the behaviour of the
+       * DeviceControl nxagent option.
+       */
+
+      XkbDfltRepeatDelay = ~ 0;
+      XkbDfltRepeatInterval = ~ 0;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentKeyboardProc: Set repeat delay to [%u] interval to [%u].\n",
+                  XkbDfltRepeatDelay, XkbDfltRepeatInterval);
+      #endif
+
+      modifier_keymap = XGetModifierMapping(nxagentDisplay);
+
+      if (modifier_keymap == NULL)
+      {
+        return -1;
+      }
+
+      XDisplayKeycodes(nxagentDisplay, &min_keycode, &max_keycode);
+#ifdef _XSERVER64
+      {
+        KeySym64 *keymap64;
+        int i, len;
+        keymap64 = XGetKeyboardMapping(nxagentDisplay,
+                                     min_keycode,
+                                     max_keycode - min_keycode + 1,
+                                     &mapWidth);
+
+        if (keymap == NULL)
+        {
+          XFreeModifiermap(modifier_keymap);
+
+          return -1;
+        }
+
+        len = (max_keycode - min_keycode + 1) * mapWidth;
+        keymap = (KeySym *)xalloc(len * sizeof(KeySym));
+        for(i = 0; i < len; ++i)
+          keymap[i] = keymap64[i];
+        XFree(keymap64);
+      }
+
+#else /* #ifdef _XSERVER64 */
+
+      keymap = XGetKeyboardMapping(nxagentDisplay,
+                                   min_keycode,
+                                   max_keycode - min_keycode + 1,
+                                   &mapWidth);
+
+      if (keymap == NULL)
+      {
+        XFreeModifiermap(modifier_keymap);
+
+        return -1;
+      }
+
+#endif /* #ifdef _XSERVER64 */
+
+      nxagentAltMetaMask = 0;
+
+      for (i = 0; i < 256; i++)
+        modmap[i] = 0;
+      for (j = 0; j < 8; j++)
+        for(i = 0; i < modifier_keymap->max_keypermod; i++) {
+          CARD8 keycode;
+          if ((keycode =
+              modifier_keymap->
+                modifiermap[j * modifier_keymap->max_keypermod + i]))
+            modmap[keycode] |= 1<<j;
+
+          if (keycode > 0)
+          {
+            nxagentCheckAltMetaKeys(keycode, j);
+          }
+        }
+      XFreeModifiermap(modifier_keymap);
+
+      keySyms.minKeyCode = min_keycode;
+      keySyms.maxKeyCode = max_keycode;
+      keySyms.mapWidth = mapWidth;
+      keySyms.map = keymap;
+
+#ifdef XKB
+
+      /*
+       * First of all the validity
+       * of XkbBaseDirectory global
+       * variable is checked.
+       */
+
+      nxagentCheckXkbBaseDirectory();
+
+      if (noXkbExtension) {
+        #ifdef TEST
+        fprintf(stderr, "nxagentKeyboardProc: No XKB extension.\n");
+        #endif
+
+XkbError:
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentKeyboardProc: XKB error.\n");
+        #endif
+
+        XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
+        xkb = NULL;
+        if (free_model) 
+        {
+          free_model = 0;
+          free(model);
+        }
+        if (free_layout)
+        {
+          free_layout = 0;
+          free(layout);
+        }
+#endif
+      XGetKeyboardControl(nxagentDisplay, &values);
+
+      memmove((char *) defaultKeyboardControl.autoRepeats,
+             (char *) values.auto_repeats, sizeof(values.auto_repeats));
+
+      ret = InitKeyboardDeviceStruct((DevicePtr) pDev, &keySyms, modmap,
+                               nxagentBell, nxagentChangeKeyboardControl);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentKeyboardProc: InitKeyboardDeviceStruct returns [%d].\n", ret);
+      #endif
+
+#ifdef XKB
+      } else {
+        FILE *file;
+        XkbConfigRtrnRec config;
+
+        int nxagentXkbConfigFilePathSize;
+
+        char *nxagentXkbConfigFilePath;
+
+        XkbComponentNamesRec names;
+        char *rules, *variants, *options;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentKeyboardProc: Using XKB extension.\n");
+        #endif
+
+        memset(&names, 0, sizeof(XkbComponentNamesRec));
+
+        rules = nxagentXkbGetRules();
+
+        if ((nxagentKeyboard != NULL) && (strcmp(nxagentKeyboard, "query") !=0))
+        {
+          for (i = 0; nxagentKeyboard[i] != '/' && nxagentKeyboard[i] != 0; i++);
+
+          if(nxagentKeyboard[i] == 0 || nxagentKeyboard[i + 1] == 0 || i == 0)
+          {
+            ErrorF("Warning: Wrong keyboard type: %s.\n",nxagentKeyboard);
+
+            goto XkbError;
+          }
+
+          free_model = 1;
+          model = malloc(i + 1);
+
+          strncpy(model, nxagentKeyboard, i);
+
+          model[i] = '\0';
+
+          free_layout = 1;
+          layout = malloc(strlen(&nxagentKeyboard[i + 1]) + 1);
+
+          strcpy(layout, &nxagentKeyboard[i + 1]);
+
+          /*
+           * There is no description for pc105 on Solaris.
+           * Need to revert to the closest approximation.
+           */
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: Using keyboard model [%s] with layout [%s].\n",
+                      model, layout);
+          #endif
+
+          #ifdef __sun
+
+          if (strcmp(model, "pc105") == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "nxagentKeyboardProc: WARNING! Keyboard model 'pc105' unsupported on Solaris.\n");
+
+            fprintf(stderr, "nxagentKeyboardProc: WARNING! Forcing keyboard model to 'pc104'.\n");
+            #endif
+
+            strcpy(model, "pc104");
+          }
+
+          #endif
+        }
+        else
+        {
+          layout = XKB_DFLT_KB_LAYOUT;
+          model = XKB_DFLT_KB_MODEL;
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: Using default keyboard: model [%s] layout [%s].\n",
+                      model, layout);
+          #endif
+        }
+
+        variants = XKB_DFLT_KB_VARIANT;
+        options = XKB_DFLT_KB_OPTIONS;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentKeyboardProc: XkbInitialMap [%s]\n", XkbInitialMap ? XkbInitialMap: "NULL");
+        #endif
+
+        if (XkbInitialMap) {
+          if ((names.keymap = strchr(XkbInitialMap, '/')) != NULL)
+            ++names.keymap;
+          else
+            names.keymap = XkbInitialMap;
+        }
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentKeyboardProc: Init XKB extension.\n");
+        #endif
+
+        if (XkbQueryExtension(nxagentDisplay,
+                              &nxagentXkbInfo.Opcode,
+                              &nxagentXkbInfo.EventBase,
+                              &nxagentXkbInfo.ErrorBase,
+                              &nxagentXkbInfo.MajorVersion,
+                              &nxagentXkbInfo.MinorVersion) == 0)
+        {
+          ErrorF("Unable to initialize XKEYBOARD extension.\n");
+
+          goto XkbError;
+        }
+
+        xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
+
+        if (xkb == NULL || xkb->geom == NULL)
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: No current keyboard.\n");
+          #endif
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: No keyboard, going to set rules and init device.\n");
+          #endif
+
+          XkbSetRulesDflts(rules, model, layout, variants, options);
+          XkbInitKeyboardDeviceStruct((pointer)pDev, &names, &keySyms, modmap,
+                                          nxagentBell, nxagentChangeKeyboardControl);
+
+          if (!nxagentKeyboard ||
+                  (nxagentKeyboard && (strcmp(nxagentKeyboard, "query") == 0)))
+          {
+            goto XkbError;
+          }
+
+          goto XkbEnd;
+        }
+
+        XkbGetControls(nxagentDisplay, XkbAllControlsMask, xkb);
+
+        nxagentXkbConfigFilePathSize = strlen(XkbBaseDirectory) +
+                                           strlen(XKB_CONFIG_FILE) + 1;
+
+        nxagentXkbConfigFilePath = malloc((nxagentXkbConfigFilePathSize + 1) * sizeof(char));
+
+        if ( nxagentXkbConfigFilePath == NULL)
+        {
+          FatalError("nxagentKeyboardProc: malloc failed.");
+        }
+
+        strcpy(nxagentXkbConfigFilePath, XkbBaseDirectory);
+        strcat(nxagentXkbConfigFilePath, "/");
+        strcat(nxagentXkbConfigFilePath, XKB_CONFIG_FILE);
+ 
+        #ifdef TEST
+        fprintf(stderr, "nxagentKeyboardProc: nxagentXkbConfigFilePath [%s].\n",
+                    nxagentXkbConfigFilePath);
+        #endif
+
+        if ((file = fopen(nxagentXkbConfigFilePath, "r")) != NULL) {
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: Going to parse config file.\n");
+          #endif
+
+          if (XkbCFParse(file, XkbCFDflts, xkb, &config) == 0) {
+            ErrorF("Error parsing config file.\n");
+
+            free(nxagentXkbConfigFilePath);
+
+            fclose(file);
+            goto XkbError;
+          }
+          if (config.rules_file)
+            rules = config.rules_file;
+          if (config.model)
+          {
+            if (free_model)
+            {
+              free_model = 0; 
+              free(model);
+            }
+            model = config.model;
+          }
+          if (config.layout)
+          {
+            if (free_layout)
+            {
+              free_layout = 0;
+              free(layout);
+            }
+            layout = config.layout;
+          }
+          if (config.variant)
+            variants = config.variant;
+          if (config.options)
+            options = config.options;
+
+          free(nxagentXkbConfigFilePath);
+
+          fclose(file);
+        }
+        else
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: No config file.\n");
+          #endif
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: No config file, going to set rules and init device.\n");
+          #endif
+
+          XkbSetRulesDflts(rules, model, layout, variants, options);
+          XkbInitKeyboardDeviceStruct((pointer)pDev, &names, &keySyms, modmap,
+                                          nxagentBell, nxagentChangeKeyboardControl);
+
+          if (!nxagentKeyboard ||
+                 (nxagentKeyboard && (strcmp(nxagentKeyboard, "query") == 0)))
+          {
+            goto XkbError;
+          }
+
+          goto XkbEnd;
+        }
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device.\n");
+        #endif
+
+        XkbSetRulesDflts(rules, model, layout, variants, options);
+        XkbInitKeyboardDeviceStruct((pointer)pDev, &names, &keySyms, modmap,
+                                    nxagentBell, nxagentChangeKeyboardControl);
+        XkbDDXChangeControls((pointer)pDev, xkb->ctrls, xkb->ctrls);
+
+XkbEnd:
+        if (free_model) 
+        {
+          free_model = 0;
+          free(model);
+        }
+
+        if (free_layout)
+        {
+          free_layout = 0;
+          free(layout);
+        }
+
+        XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
+
+        xkb = NULL;
+      }
+#endif
+
+      #ifdef WATCH
+
+      fprintf(stderr, "nxagentKeyboardProc: Watchpoint 10.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#1   U  3	2	80320 bits (10 KB) ->	28621 bits (3 KB) ->	26773/1 -> 9540/1	= 2.806:1
+#98     1		256 bits (0 KB) ->	27 bits (0 KB) ->	256/1 -> 27/1	= 9.481:1
+#101    1		32000 bits (4 KB) ->	2940 bits (0 KB) ->	32000/1 -> 2940/1	= 10.884:1
+#119    1		384 bits (0 KB) ->	126 bits (0 KB) ->	384/1 -> 126/1	= 3.048:1
+*/
+
+      sleep(30);
+
+      #endif
+
+#ifdef _XSERVER64
+      xfree(keymap);
+#else
+      XFree(keymap);
+#endif
+      break;
+    case DEVICE_ON:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_ON].\n");
+      #endif
+
+      if (NXDisplayError(nxagentDisplay) == 1)
+      {
+        return Success;
+      }
+
+      #ifdef WATCH
+
+      fprintf(stderr, "nxagentKeyboardProc: Watchpoint 11.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#117    1		320 bits (0 KB) ->	52 bits (0 KB) ->	320/1 -> 52/1	= 6.154:1
+*/
+
+      sleep(30);
+
+      #endif
+
+      nxagentEnableKeyboardEvents();
+
+      break;
+
+    case DEVICE_OFF:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_OFF].\n");
+      #endif
+
+      if (NXDisplayError(nxagentDisplay) == 1)
+      {
+        return Success;
+      }
+
+      nxagentDisableKeyboardEvents();
+
+      break;
+
+    case DEVICE_CLOSE:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentKeyboardProc: Called for [DEVICE_CLOSE].\n");
+      #endif
+
+      break;
+  }
+
+  return Success;
+}
+
+Bool LegalModifier(key, pDev)
+     unsigned int key;
+     DevicePtr pDev;
+{
+  return TRUE;
+}
+
+void nxagentNotifyKeyboardChanges(int oldMinKeycode, int oldMaxKeycode)
+{
+  #ifdef XKB
+
+  if (!noXkbExtension)
+  {
+    DeviceIntPtr dev;
+    XkbDescPtr xkb;
+    xkbNewKeyboardNotify nkn;
+
+    dev = inputInfo.keyboard;
+    xkb = dev -> key -> xkbInfo -> desc;
+
+    nkn.deviceID = nkn.oldDeviceID = dev -> id;
+    nkn.minKeyCode = 8;
+    nkn.maxKeyCode = 255;
+    nkn.oldMinKeyCode = oldMinKeycode;
+    nkn.oldMaxKeyCode = oldMaxKeycode;
+    nkn.requestMajor = XkbReqCode;
+    nkn.requestMinor = X_kbGetKbdByName;
+    nkn.changed = XkbNKN_KeycodesMask;
+
+    XkbSendNewKeyboardNotify(dev, &nkn);
+  }
+  else
+  {
+
+  #endif
+
+    int i;
+    xEvent event;
+
+    event.u.u.type = MappingNotify;
+    event.u.mappingNotify.request = MappingKeyboard;
+    event.u.mappingNotify.firstKeyCode = inputInfo.keyboard -> key -> curKeySyms.minKeyCode;
+    event.u.mappingNotify.count = inputInfo.keyboard -> key -> curKeySyms.maxKeyCode -
+                                      inputInfo.keyboard -> key -> curKeySyms.minKeyCode;
+
+    /*
+     *  0 is the server client
+     */
+
+    for (i = 1; i < currentMaxClients; i++)
+    {
+      if (clients[i] && clients[i] -> clientState == ClientStateRunning)
+      {
+        event.u.u.sequenceNumber = clients[i] -> sequence;
+        WriteEventsToClient(clients[i], 1, &event);
+      }
+    }
+
+  #ifdef XKB
+
+  }
+
+  #endif
+
+}
+
+int nxagentResetKeyboard(void)
+{
+  DeviceIntPtr dev = inputInfo.keyboard;
+  DeviceIntPtr devBackup;
+
+  int result;
+  int oldMinKeycode = 8;
+  int oldMaxKeycode = 255;
+
+  int savedBellPercent;
+  int savedBellPitch;
+  int savedBellDuration;
+
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    return 0;
+  }
+
+  /*
+   * Save bell settings.
+   */
+
+  savedBellPercent = inputInfo.keyboard -> kbdfeed -> ctrl.bell;
+  savedBellPitch = inputInfo.keyboard -> kbdfeed -> ctrl.bell_pitch;
+  savedBellDuration = inputInfo.keyboard -> kbdfeed -> ctrl.bell_duration;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentResetKeyboard: bellPercent [%d]  bellPitch [%d]  bellDuration [%d].\n",
+              savedBellPercent, savedBellPitch, savedBellDuration);
+  #endif
+
+  devBackup = xalloc(sizeof(DeviceIntRec));
+
+  if (devBackup == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentSaveKeyboardDeviceData: PANIC! Can't allocate backup structure.\n");
+    #endif
+  }
+  else
+  {
+    memset(devBackup, 0, sizeof(DeviceIntRec));
+  }
+
+  nxagentSaveKeyboardDeviceData(dev, devBackup);
+
+  if (dev->key)
+  {
+    #ifdef XKB
+    if (noXkbExtension == 0 && dev->key->xkbInfo)
+    {
+      oldMinKeycode = dev->key->xkbInfo -> desc -> min_key_code;
+      oldMaxKeycode = dev->key->xkbInfo -> desc -> max_key_code;
+    }
+    #endif
+
+    dev->key=NULL;
+  }
+
+  dev->focus=NULL;
+
+  dev->kbdfeed=NULL;
+
+  #ifdef XKB
+  nxagentTuneXkbWrapper();
+  #endif
+
+  result = (*inputInfo.keyboard -> deviceProc)(inputInfo.keyboard, DEVICE_INIT);
+
+  if (result == Success && inputInfo.keyboard -> key != NULL)
+  {
+
+    /*
+     * Restore bell settings.
+     */
+
+    inputInfo.keyboard -> kbdfeed -> ctrl.bell = savedBellPercent;
+    inputInfo.keyboard -> kbdfeed -> ctrl.bell_pitch = savedBellPitch;
+    inputInfo.keyboard -> kbdfeed -> ctrl.bell_duration = savedBellDuration;
+
+    nxagentNotifyKeyboardChanges(oldMinKeycode, oldMaxKeycode);
+
+    nxagentFreeKeyboardDeviceData(devBackup);
+
+    free(devBackup);
+
+    return 1;
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentResetKeyboard: Can't initialize the keyboard device.\n");
+    #endif
+
+    nxagentRestoreKeyboardDeviceData(devBackup, dev);
+
+    return 0;
+  }
+}
+
+void  nxagentCheckAltMetaKeys(CARD8 keycode, int j)
+{
+  if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_L))
+  {
+    nxagentAltMetaMask |= 1 << j;
+  }
+
+  if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Meta_R))
+  {
+    nxagentAltMetaMask |= 1 << j;
+  }
+
+  if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_L))
+  {
+    nxagentAltMetaMask |= 1 << j;
+  }
+
+  if (keycode == XKeysymToKeycode(nxagentDisplay, XK_Alt_R))
+  {
+    nxagentAltMetaMask |= 1 << j;
+  }
+}
+
+static int nxagentSaveKeyboardDeviceData(DeviceIntPtr dev, DeviceIntPtr devBackup)
+{
+  if (devBackup == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentSaveKeyboardDeviceData: PANIC! Pointer to backup structure is null.\n");
+    #endif
+
+    return -1;
+  }
+
+  devBackup -> key = dev -> key;
+
+  devBackup -> focus = dev -> focus;
+
+  devBackup -> kbdfeed = dev -> kbdfeed;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentSaveKeyboardDeviceData: Saved device data.\n");
+  #endif
+
+  return 1;
+}
+
+static int nxagentRestoreKeyboardDeviceData(DeviceIntPtr devBackup, DeviceIntPtr dev)
+{
+  if (devBackup == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentRestoreKeyboardDeviceData: PANIC! Pointer to backup structure is null.\n");
+    #endif
+
+    return -1;
+  }
+
+  dev -> key = devBackup -> key;
+
+  dev -> focus = devBackup -> focus;
+
+  dev -> kbdfeed = devBackup -> kbdfeed;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentRestoreKeyboardDeviceData: Restored device data.\n");
+  #endif
+
+  return 1;
+}
+
+
+static int nxagentFreeKeyboardDeviceData(DeviceIntPtr dev)
+{
+  KbdFeedbackPtr k, knext;
+
+  if (dev == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentFreeKeyboardDeviceData: PANIC! Pointer to device structure is null.\n");
+    #endif
+
+    return -1;
+  }
+
+  if (dev->key)
+  {
+      #ifdef XKB
+      if (noXkbExtension == 0 && dev->key->xkbInfo)
+      {
+          XkbFreeInfo(dev->key->xkbInfo);
+          dev->key->xkbInfo = NULL;
+      }
+      #endif
+
+      xfree(dev->key->curKeySyms.map);
+      xfree(dev->key->modifierKeyMap);
+      xfree(dev->key);
+
+      dev->key=NULL;
+  }
+
+  if (dev->focus)
+  {
+      xfree(dev->focus->trace);
+      xfree(dev->focus);
+      dev->focus=NULL;
+  }
+
+  for (k = dev->kbdfeed; k; k = knext)
+  {
+      knext = k->next;
+      #ifdef XKB
+      if (k->xkb_sli)
+          XkbFreeSrvLedInfo(k->xkb_sli);
+      #endif
+      xfree(k);
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentFreeKeyboardDeviceData: Freed device data.\n");
+  #endif
+
+  return 1;
+}
+
+#if XKB
+
+int ProcXkbInhibited(register ClientPtr client)
+{
+  unsigned char majorop;
+  unsigned char minorop;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXkbInhibited: Called.\n");
+  #endif
+
+  majorop = ((xReq *)client->requestBuffer)->reqType;
+
+  #ifdef PANIC
+  if (majorop != (unsigned char)nxagentXkbWrapper.base)
+  {
+    fprintf(stderr, "ProcXkbInhibited: MAJOROP is [%d] but should be [%d].\n",
+            majorop, nxagentXkbWrapper.base);
+  }
+  #endif
+
+  minorop = *((unsigned char *) client->requestBuffer + 1);
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXkbInhibited: MAJOROP is [%d] MINOROP is [%d].\n",
+              majorop, minorop);
+  #endif
+
+  switch (minorop)
+  {
+    case X_kbLatchLockState:
+    case X_kbSetControls:
+    case X_kbSetCompatMap:
+    case X_kbSetIndicatorMap:
+    case X_kbSetNamedIndicator:
+    case X_kbSetNames:
+    case X_kbSetGeometry:
+    case X_kbSetDebuggingFlags:
+    case X_kbSetMap:
+    {
+      return client->noClientException;
+    }
+    case X_kbGetKbdByName:
+    {
+      return BadAccess;
+    }
+    default:
+    {
+      return (client->swapped ? nxagentXkbWrapper.SProcXkbDispatchBackup(client) :
+                  nxagentXkbWrapper.ProcXkbDispatchBackup(client));
+    }
+  }
+}
+
+void nxagentInitXkbWrapper(void)
+{
+  ExtensionEntry * extension;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitXkbWrapper: Called.\n");
+  #endif
+
+  if (nxagentOption(InhibitXkb) == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentInitXkbWrapper: Nothing to do.\n");
+    #endif
+
+    return;
+  }
+
+  memset(&nxagentXkbWrapper, 0, sizeof(XkbWrapperRec));
+
+  extension = CheckExtension("XKEYBOARD");
+
+  if (extension != NULL)
+  {
+    nxagentXkbWrapper.base = extension -> base;
+    nxagentXkbWrapper.eventBase = extension -> eventBase;
+    nxagentXkbWrapper.errorBase = extension -> errorBase;
+    nxagentXkbWrapper.ProcXkbDispatchBackup  = NULL;
+    nxagentXkbWrapper.SProcXkbDispatchBackup = NULL;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentInitXkbWrapper: base [%d] eventBase [%d] errorBase [%d].\n",
+                extension -> base, extension -> eventBase, extension -> errorBase);
+    #endif
+  }
+  else
+  {
+    nxagentXkbWrapper.base = -1;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentInitXkbWrapper: XKEYBOARD extension not found.\n");
+    #endif
+  }
+}
+
+void nxagentDisableXkbExtension(void)
+{  
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisableXkbExtension: Called.\n");
+  #endif
+
+  if (nxagentXkbWrapper.base > 0)
+  {
+    if (nxagentXkbWrapper.ProcXkbDispatchBackup == NULL)
+    {
+      nxagentXkbWrapper.ProcXkbDispatchBackup  = ProcVector[nxagentXkbWrapper.base];
+
+      ProcVector[nxagentXkbWrapper.base] = ProcXkbInhibited;
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentDisableXkbExtension: Nothing to be done for ProcXkbDispatch.\n");
+    }
+    #endif
+
+    if (nxagentXkbWrapper.SProcXkbDispatchBackup == NULL)
+    {
+      nxagentXkbWrapper.SProcXkbDispatchBackup = SwappedProcVector[nxagentXkbWrapper.base];
+
+      SwappedProcVector[nxagentXkbWrapper.base] = ProcXkbInhibited;
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentDisableXkbExtension: Nothing to be done for SProcXkbDispatch.\n");
+    }
+    #endif
+  }
+}
+
+void nxagentEnableXkbExtension(void)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentEnableXkbExtension: Called.\n");
+  #endif
+
+  if (nxagentXkbWrapper.base > 0)
+  {
+    if (nxagentXkbWrapper.ProcXkbDispatchBackup != NULL)
+    {
+      ProcVector[nxagentXkbWrapper.base] = nxagentXkbWrapper.ProcXkbDispatchBackup;
+
+      nxagentXkbWrapper.ProcXkbDispatchBackup = NULL;
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentEnableXkbExtension: Nothing to be done for ProcXkbDispatch.\n");
+    }
+    #endif
+
+    if (nxagentXkbWrapper.SProcXkbDispatchBackup != NULL)
+    {
+      SwappedProcVector[nxagentXkbWrapper.base] = nxagentXkbWrapper.SProcXkbDispatchBackup;
+
+      nxagentXkbWrapper.SProcXkbDispatchBackup = NULL;
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentEnableXkbExtension: Nothing to be done for SProcXkbDispatch.\n");
+    }
+    #endif
+  }
+}
+
+void nxagentTuneXkbWrapper(void)
+{
+  if (nxagentOption(InhibitXkb) == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTuneXkbWrapper: Nothing to do.\n");
+    #endif
+
+    return;
+  }
+
+  if (nxagentKeyboard != NULL && 
+          strcmp(nxagentKeyboard, "query") == 0)
+  {
+    nxagentDisableXkbExtension();
+  }
+  else
+  {
+    nxagentEnableXkbExtension();
+  }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
new file mode 100644
index 000000000..f292402d2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -0,0 +1,114 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Keyboard_H__
+#define __Keyboard_H__
+
+#define NXAGENT_KEYBOARD_EVENT_MASK \
+  (KeyPressMask | KeyReleaseMask | FocusChangeMask | KeymapStateMask)
+
+#define NXAGENT_KEYBOARD_EXTENSION_EVENT_MASK \
+  (XkbStateNotifyMask)
+
+/*
+ * Queried at XKB initialization.
+ */
+
+typedef struct _XkbAgentInfo
+{
+  int Opcode;
+  int EventBase;
+  int ErrorBase;
+  int MajorVersion;
+  int MinorVersion;
+
+} XkbAgentInfoRec;
+
+extern XkbAgentInfoRec nxagentXkbInfo;
+
+typedef struct _XkbAgentState
+{
+  int Locked;
+  int Caps;
+  int Num;
+  int Focus;
+  int Initialized;
+
+} XkbAgentStateRec;
+
+extern XkbAgentStateRec nxagentXkbState;
+
+/*
+ * Info for enabling/disabling Xkb.
+ */
+
+typedef struct _XkbWrapper
+{
+  int base;
+  int eventBase;
+  int errorBase;
+  int (* ProcXkbDispatchBackup)(ClientPtr);
+  int (* SProcXkbDispatchBackup)(ClientPtr);
+
+} XkbWrapperRec;
+
+extern XkbWrapperRec nxagentXkbWrapper;
+
+extern char *nxagentKeyboard;
+
+/*
+ * Keyboard device procedure
+ * and utility functions.
+ */
+
+void nxagentBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls);
+
+int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff);
+
+void nxagentChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl);
+
+void nxagentNotifyKeyboardChanges(int oldMinKeycode, int oldMaxKeycode);
+
+int nxagentResetKeyboard(void);
+
+#ifdef XKB
+
+void nxagentInitXkbWrapper(void);
+
+void nxagentDisableXkbExtension(void);
+
+void nxagentEnableXkbExtension(void);
+
+void nxagentTuneXkbWrapper(void);
+
+#endif
+
+#endif /* __Keyboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
new file mode 100644
index 000000000..ea06913f8
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -0,0 +1,216 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "X.h"
+#include "keysym.h"
+
+#include "screenint.h"
+#include "scrnintstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Events.h"
+#include "Options.h"
+#include "Keystroke.h"
+#include "Drawable.h"
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentIpaq;
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
+{
+  KeySym sym;
+  int index = 0;
+
+  *result = doNothing;
+
+  /*
+   * I don't know how much hard work is doing this operation.
+   * Do we need a cache ?
+   */
+
+  sym = XKeycodeToKeysym(nxagentDisplay, X -> keycode, index);
+
+  if (sym == XK_VoidSymbol || sym == NoSymbol)
+  {
+    return 0;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCheckSpecialKeystroke: got code %x - state %x - sym %lx\n",
+              X -> keycode, X -> state, sym);
+  #endif
+
+  /*
+   * Check special keys.
+   */
+
+  /*
+   * FIXME: We should use the keysym instead that the keycode
+   *        here.
+   */
+
+  if (X -> keycode == 130 && nxagentIpaq)
+  {
+    *result = doStartKbd;
+
+    return 1;
+  }
+
+  if ((X -> state & nxagentAltMetaMask) &&
+          ((X -> state & (ControlMask | ShiftMask)) == ControlMask))
+  {
+    switch (sym)
+    {
+      case XK_t:
+      case XK_T:
+      {
+        *result = doCloseSession;
+
+        break;
+      }
+      case XK_f:
+      case XK_F:
+      {
+        if (nxagentOption(Rootless) == False)
+        {
+          *result = doSwitchFullscreen;
+        }
+
+        break;
+      }
+      case XK_m:
+      case XK_M:
+      {
+        if (nxagentOption(Rootless) == False)
+        {
+          *result = doMinimize;
+        }
+
+        break;
+      }
+      case XK_Left:
+      case XK_KP_Left:
+      {
+        if (nxagentOption(Rootless) == False &&
+                nxagentOption(DesktopResize) == False)
+        {
+          *result = doViewportLeft;
+        }
+
+        break;
+      }
+      case XK_Up:
+      case XK_KP_Up:
+      {
+        if (nxagentOption(Rootless) == False &&
+                nxagentOption(DesktopResize) == False)
+        {
+          *result = doViewportUp;
+        }
+
+        break;
+      }
+      case XK_Right:
+      case XK_KP_Right:
+      {
+        if (nxagentOption(Rootless) == False &&
+                nxagentOption(DesktopResize) == False)
+        {
+          *result = doViewportRight;
+        }
+
+        break;
+      }
+      case XK_Down:
+      case XK_KP_Down:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportDown;
+        }
+
+        break;
+      }
+      case XK_R:
+      case XK_r:
+      {
+        if (nxagentOption(Rootless) == 0)
+        {
+          *result = doSwitchResizeMode;
+        }
+
+        break;
+      }
+      case XK_E:
+      case XK_e:
+      {
+        *result = doSwitchDeferMode;
+
+        break;
+      }
+      case XK_BackSpace:
+      case XK_Terminate_Server:
+      {
+        /*
+         * Discard Ctrl-Alt-BackSpace key.
+         */
+
+        return 1;
+
+        break;
+      }
+
+      case XK_J:
+      case XK_j:
+      {
+        nxagentForceSynchronization = 1;
+
+        return 1;
+      }
+
+      #ifdef DUMP
+
+      case XK_A:
+      case XK_a:
+      {
+        /*
+         * Used to test the lazy encoding.
+         */
+
+        nxagentRegionsOnScreen();
+
+        return 1;
+      }
+
+      #endif
+    }
+  }
+
+  return (*result == doNothing) ? 0 : 1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
new file mode 100644
index 000000000..49a35db1d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -0,0 +1,27 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Keystroke_H__
+#define __Keystroke_H__
+
+#include "Events.h"
+
+extern int nxagentCheckSpecialKeystroke(XKeyEvent*, enum HandleEventResult*);
+
+unsigned int nxagentAltMetaMask;
+
+#endif /* __Keystroke_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/LICENSE b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
new file mode 100644
index 000000000..f3e15ee70
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
@@ -0,0 +1,26 @@
+Copyright (C) 2001, 2007 NoMachine - http://www.nomachine.com/.
+
+NXAGENT and NX extensions to X are copyright of NoMachine.
+
+Redistribution and use of this software is allowed according to the
+following terms:
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License Version 2, and
+not any other version, as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA-
+BILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, you can request a copy to NoMachine
+or write to the Free Software Foundation, Inc., 59 Temple Place,
+Suite 330, Boston, MA  02111-1307 USA
+
+Parts of this software are derived from XFree86 and X.org projects.
+Other copyrights and the MIT/X11 license applies to different sources.
+Please check the applicable copyrights in each file or subdirectory.
+
+All rights reserved.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
new file mode 100644
index 000000000..e80f62230
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * Simple table used to translate a request
+ * opcode to the name of the X request.
+ */
+
+static char *nxagentRequestLiteral[] = 
+{
+  "None",
+  "CreateWindow",
+  "ChangeWindowAttributes",
+  "GetWindowAttributes",
+  "DestroyWindow",
+  "DestroySubwindows",
+  "ChangeSaveSet",
+  "ReparentWindow",
+  "MapWindow",
+  "MapSubwindows",
+  "UnmapWindow",
+  "UnmapSubwindows",
+  "ConfigureWindow",
+  "CirculateWindow",
+  "GetGeometry",
+  "QueryTree",
+  "InternAtom",
+  "GetAtomName",
+  "ChangeProperty",
+  "DeleteProperty",
+  "GetProperty",
+  "ListProperties",
+  "SetSelectionOwner",
+  "GetSelectionOwner",
+  "ConvertSelection",
+  "SendEvent",
+  "GrabPointer",
+  "UngrabPointer",
+  "GrabButton",
+  "UngrabButton",
+  "ChangeActivePointerGrab",
+  "GrabKeyboard",
+  "UngrabKeyboard",
+  "GrabKey",
+  "UngrabKey",
+  "AllowEvents",
+  "GrabServer",
+  "UngrabServer",
+  "QueryPointer",
+  "GetMotionEvents",
+  "TranslateCoords",
+  "WarpPointer",
+  "SetInputFocus",
+  "GetInputFocus",
+  "QueryKeymap",
+  "OpenFont",
+  "CloseFont",
+  "QueryFont",
+  "QueryTextExtents",
+  "ListFonts",
+  "ListFontsWithInfo",
+  "SetFontPath",
+  "GetFontPath",
+  "CreatePixmap",
+  "FreePixmap",
+  "CreateGC",
+  "ChangeGC",
+  "CopyGC",
+  "SetDashes",
+  "SetClipRectangles",
+  "FreeGC",
+  "ClearArea",
+  "CopyArea",
+  "CopyPlane",
+  "PolyPoint",
+  "PolyLine",
+  "PolySegment",
+  "PolyRectangle",
+  "PolyArc",
+  "FillPoly",
+  "PolyFillRectangle",
+  "PolyFillArc",
+  "PutImage",
+  "GetImage",
+  "PolyText8",
+  "PolyText16",
+  "ImageText8",
+  "ImageText16",
+  "CreateColormap",
+  "FreeColormap",
+  "CopyColormapAndFree",
+  "InstallColormap",
+  "UninstallColormap",
+  "ListInstalledColormaps",
+  "AllocColor",
+  "AllocNamedColor",
+  "AllocColorCells",
+  "AllocColorPlanes",
+  "FreeColors",
+  "StoreColors",
+  "StoreNamedColor",
+  "QueryColors",
+  "LookupColor",
+  "CreateCursor",
+  "CreateGlyphCursor",
+  "FreeCursor",
+  "RecolorCursor",
+  "QueryBestSize",
+  "QueryExtension",
+  "ListExtensions",
+  "ChangeKeyboardMapping",
+  "GetKeyboardMapping",
+  "ChangeKeyboardControl",
+  "GetKeyboardControl",
+  "Bell",
+  "ChangePointerControl",
+  "GetPointerControl",
+  "SetScreenSaver",
+  "GetScreenSaver",
+  "ChangeHosts",
+  "ListHosts",
+  "SetAccessControl",
+  "SetCloseDownMode",
+  "KillClient",
+  "RotateProperties",
+  "ForceScreenSaver",
+  "SetPointerMapping",
+  "GetPointerMapping",
+  "SetModifierMapping",
+  "GetModifierMapping",
+  "NoOperation"
+};
+
+static char *nxagentRenderRequestLiteral[] =
+{
+  "RenderQueryVersion",
+  "RenderQueryPictFormats",
+  "RenderQueryPictIndexValues",
+  "RenderQueryDithers",
+  "RenderCreatePicture",
+  "RenderChangePicture",
+  "RenderSetPictureClipRectangles",
+  "RenderFreePicture",
+  "RenderComposite",
+  "RenderScale",
+  "RenderTrapezoids",
+  "RenderTriangles",
+  "RenderTriStrip",
+  "RenderTriFan",
+  "RenderColorTrapezoids",
+  "RenderColorTriangles",
+  "RenderTransform",
+  "RenderCreateGlyphSet",
+  "RenderReferenceGlyphSet",
+  "RenderFreeGlyphSet",
+  "RenderAddGlyphs",
+  "RenderAddGlyphsFromPicture",
+  "RenderFreeGlyphs",
+  "RenderCompositeGlyphs",
+  "RenderCompositeGlyphs",
+  "RenderCompositeGlyphs",
+  "RenderFillRectangles",
+  "RenderCreateCursor",
+  "RenderSetPictureTransform",
+  "RenderQueryFilters",
+  "RenderSetPictureFilter",
+  "RenderCreateAnimCursor",
+  "RenderAddTraps",
+  "RenderCreateSolidFill",
+  "RenderCreateLinearGradient",
+  "RenderCreateRadialGradient",
+  "RenderCreateConicalGradient"
+};
+
+static char *nxagentShmRequestLiteral[] =
+{
+  "ShmQueryVersion",
+  "ShmAttach",
+  "ShmDetach",
+  "ShmPutImage",
+  "ShmGetImage",
+  "ShmCreatePixmap"
+};
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.c b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
new file mode 100644
index 000000000..38435d9a8
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
@@ -0,0 +1,70 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <time.h>
+#include <stdio.h>
+
+#include "Xos.h"
+#include "Millis.h"
+
+#ifdef DDXTIME
+
+CARD32 GetTimeInMillis()
+{
+  struct timeval ts;
+
+  X_GETTIMEOFDAY(&ts);
+
+  return(ts.tv_sec * 1000) + (ts.tv_usec / 1000);
+}
+
+#endif
+
+const char *GetTimeAsString()
+{
+  char *value;
+
+  struct timeval ts;
+
+  X_GETTIMEOFDAY(&ts);
+
+  value = ctime((time_t *) &ts.tv_sec);
+
+  *(value + strlen(value) - 1) = '\0';
+
+  return value;
+}
+
+const char *GetTimeInMillisAsString()
+{
+  char *value;
+
+  char tb[25];
+
+  struct timeval ts;
+
+  X_GETTIMEOFDAY(&ts);
+
+  value = ctime((time_t *) &ts.tv_sec);
+
+  sprintf(tb, "%.8s:%3.3f", value + 11,
+              (float) ts.tv_usec / 1000);
+
+  strncpy(value, tb, 24);
+
+  return value;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.h b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
new file mode 100644
index 000000000..8ee380ae1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
@@ -0,0 +1,30 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Millis_H__
+#define __Millis_H__
+
+#include "Xmd.h"
+
+CARD32 GetTimeInMillis(void);
+
+const char *GetTimeInMillisAsString(void);
+
+const char *GetTimeAsString(void);
+
+#endif /* __Millis_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXcomposite.c b/nx-X11/programs/Xserver/hw/nxagent/NXcomposite.c
new file mode 100644
index 000000000..09bdaeb31
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXcomposite.c
@@ -0,0 +1,359 @@
+#ifndef NXAGENT_UPGRADE
+
+/*
+ * $Id: Xcomposite.c,v 1.2 2005/07/03 07:00:56 daniels Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef NXAGENT_SERVER
+
+#include "NXcompositeint.h"
+
+#else
+
+#include "compositeint.h"
+
+#endif
+
+XCompositeExtInfo XCompositeExtensionInfo;
+
+const char XCompositeExtensionName[] = COMPOSITE_NAME;
+
+/*
+ * XCompositeExtRemoveDisplay - remove the indicated display from the
+ * extension object. (Replaces XextRemoveDisplay.)
+ */
+static int 
+XCompositeExtRemoveDisplay (XCompositeExtInfo *extinfo, Display *dpy)
+{
+    XCompositeExtDisplayInfo *info, *prev;
+
+    /*
+     * locate this display and its back link so that it can be removed
+     */
+    _XLockMutex(_Xglobal_lock);
+    prev = NULL;
+    for (info = extinfo->head; info; info = info->next) {
+	if (info->display == dpy) break;
+	prev = info;
+    }
+    if (!info) {
+	_XUnlockMutex(_Xglobal_lock);
+	return 0;		/* hmm, actually an error */
+    }
+
+    /*
+     * remove the display from the list; handles going to zero
+     */
+    if (prev)
+	prev->next = info->next;
+    else
+	extinfo->head = info->next;
+
+    extinfo->ndisplays--;
+    if (info == extinfo->cur) extinfo->cur = NULL;  /* flush cache */
+    _XUnlockMutex(_Xglobal_lock);
+
+    Xfree ((char *) info);
+    return 1;
+}
+
+static int
+XCompositeCloseDisplay (Display *dpy, XExtCodes *codes)
+{
+    return XCompositeExtRemoveDisplay (&XCompositeExtensionInfo, dpy);
+}
+
+/*
+ * XCompositeExtAddDisplay - add a display to this extension. (Replaces
+ * XextAddDisplay)
+ */
+static XCompositeExtDisplayInfo *
+XCompositeExtAddDisplay (XCompositeExtInfo	*extinfo,
+			 Display		*dpy,
+			 const char		*ext_name)
+{
+    XCompositeExtDisplayInfo    *info;
+
+    #ifndef NXAGENT_SERVER
+
+    int			    ev;
+
+    #endif
+
+    info = (XCompositeExtDisplayInfo *) Xmalloc (sizeof (XCompositeExtDisplayInfo));
+    if (!info) return NULL;
+    info->display = dpy;
+
+    info->codes = XInitExtension (dpy, ext_name);
+
+    /*
+     * if the server has the extension, then we can initialize the 
+     * appropriate function vectors
+     */
+    if (info->codes) {
+	xCompositeQueryVersionReply	rep;
+	xCompositeQueryVersionReq	*req;
+        XESetCloseDisplay (dpy, info->codes->extension, 
+                           XCompositeCloseDisplay);
+	/*
+	 * Get the version info
+	 */
+	LockDisplay (dpy);
+	GetReq (CompositeQueryVersion, req);
+	req->reqType = info->codes->major_opcode;
+	req->compositeReqType = X_CompositeQueryVersion;
+	req->majorVersion = COMPOSITE_MAJOR;
+	req->minorVersion = COMPOSITE_MINOR;
+	if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) 
+	{
+	    UnlockDisplay (dpy);
+	    SyncHandle ();
+	    return 0;
+	}
+	info->major_version = rep.majorVersion;
+	info->minor_version = rep.minorVersion;
+	UnlockDisplay (dpy);
+    } else {
+	/* The server doesn't have this extension.
+	 * Use a private Xlib-internal extension to hang the close_display
+	 * hook on so that the "cache" (extinfo->cur) is properly cleaned.
+	 * (XBUG 7955)
+	 */
+	XExtCodes *codes = XAddExtension(dpy);
+	if (!codes) {
+	    XFree(info);
+	    return NULL;
+	}
+        XESetCloseDisplay (dpy, codes->extension, XCompositeCloseDisplay);
+    }
+
+    /*
+     * now, chain it onto the list
+     */
+    _XLockMutex(_Xglobal_lock);
+    info->next = extinfo->head;
+    extinfo->head = info;
+    extinfo->cur = info;
+    extinfo->ndisplays++;
+    _XUnlockMutex(_Xglobal_lock);
+    return info;
+}
+
+/*
+ * XCompositeExtFindDisplay - look for a display in this extension; keeps a
+ * cache of the most-recently used for efficiency. (Replaces
+ * XextFindDisplay.)
+ */
+static XCompositeExtDisplayInfo *
+XCompositeExtFindDisplay (XCompositeExtInfo *extinfo, 
+		      Display	    *dpy)
+{
+    XCompositeExtDisplayInfo *info;
+
+    /*
+     * see if this was the most recently accessed display
+     */
+    if ((info = extinfo->cur) && info->display == dpy) 
+	return info;
+
+    /*
+     * look for display in list
+     */
+    _XLockMutex(_Xglobal_lock);
+    for (info = extinfo->head; info; info = info->next) {
+	if (info->display == dpy) {
+	    extinfo->cur = info;     /* cache most recently used */
+	    _XUnlockMutex(_Xglobal_lock);
+	    return info;
+	}
+    }
+    _XUnlockMutex(_Xglobal_lock);
+
+    return NULL;
+}
+
+XCompositeExtDisplayInfo *
+XCompositeFindDisplay (Display *dpy)
+{
+    XCompositeExtDisplayInfo *info;
+
+    info = XCompositeExtFindDisplay (&XCompositeExtensionInfo, dpy);
+    if (!info)
+	info = XCompositeExtAddDisplay (&XCompositeExtensionInfo, dpy, 
+				    XCompositeExtensionName);
+    return info;
+}
+    
+
+Bool 
+XCompositeQueryExtension (Display *dpy, int *event_basep, int *error_basep)
+{
+    XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+
+    if (XCompositeHasExtension(info)) 
+    {
+	*event_basep = info->codes->first_event;
+	*error_basep = info->codes->first_error;
+	return True;
+    } 
+    else
+	return False;
+}
+
+Status 
+XCompositeQueryVersion (Display *dpy,
+		    int	    *major_versionp,
+		    int	    *minor_versionp)
+{
+    XCompositeExtDisplayInfo	*info = XCompositeFindDisplay (dpy);
+
+    XCompositeCheckExtension (dpy, info, 0);
+    *major_versionp = info->major_version;
+    *minor_versionp = info->minor_version;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return 1;
+}
+
+int
+XCompositeVersion (void)
+{
+    return XCOMPOSITE_VERSION;
+}
+
+void
+XCompositeRedirectWindow (Display *dpy, Window window, int update)
+{
+    XCompositeExtDisplayInfo	    *info = XCompositeFindDisplay (dpy);
+    xCompositeRedirectWindowReq	    *req;
+
+    XCompositeSimpleCheckExtension (dpy, info);
+    LockDisplay (dpy);
+    GetReq (CompositeRedirectWindow, req);
+    req->reqType = info->codes->major_opcode;
+    req->compositeReqType = X_CompositeRedirectWindow;
+    req->window = window;
+    req->update = update;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+}
+
+void
+XCompositeRedirectSubwindows (Display *dpy, Window window, int update)
+{
+    XCompositeExtDisplayInfo	    *info = XCompositeFindDisplay (dpy);
+    xCompositeRedirectSubwindowsReq *req;
+
+    XCompositeSimpleCheckExtension (dpy, info);
+    LockDisplay (dpy);
+    GetReq (CompositeRedirectSubwindows, req);
+    req->reqType = info->codes->major_opcode;
+    req->compositeReqType = X_CompositeRedirectSubwindows;
+    req->window = window;
+    req->update = update;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+}
+
+void
+XCompositeUnredirectWindow (Display *dpy, Window window, int update)
+{
+    XCompositeExtDisplayInfo	    *info = XCompositeFindDisplay (dpy);
+    xCompositeUnredirectWindowReq   *req;
+
+    XCompositeSimpleCheckExtension (dpy, info);
+    LockDisplay (dpy);
+    GetReq (CompositeUnredirectWindow, req);
+    req->reqType = info->codes->major_opcode;
+    req->compositeReqType = X_CompositeUnredirectWindow;
+    req->window = window;
+    req->update = update;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+}
+
+void
+XCompositeUnredirectSubwindows (Display *dpy, Window window, int update)
+{
+    XCompositeExtDisplayInfo		*info = XCompositeFindDisplay (dpy);
+    xCompositeUnredirectSubwindowsReq	*req;
+
+    XCompositeSimpleCheckExtension (dpy, info);
+    LockDisplay (dpy);
+    GetReq (CompositeUnredirectSubwindows, req);
+    req->reqType = info->codes->major_opcode;
+    req->compositeReqType = X_CompositeUnredirectSubwindows;
+    req->window = window;
+    req->update = update;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+}
+
+XserverRegion
+XCompositeCreateRegionFromBorderClip (Display *dpy, Window window)
+{
+    XCompositeExtDisplayInfo		    *info = XCompositeFindDisplay (dpy);
+    xCompositeCreateRegionFromBorderClipReq *req;
+    XserverRegion			    region;
+
+    XCompositeCheckExtension (dpy, info, 0);
+    LockDisplay (dpy);
+    GetReq (CompositeCreateRegionFromBorderClip, req);
+    req->reqType = info->codes->major_opcode;
+    req->compositeReqType = X_CompositeCreateRegionFromBorderClip;
+    req->window = window;
+    region = req->region = XAllocID (dpy);
+    UnlockDisplay (dpy);
+    SyncHandle ();
+
+    #ifdef NXAGENT_SERVER
+
+    return region;
+
+    #else
+
+    return region;
+
+    #endif
+}
+
+Pixmap
+XCompositeNameWindowPixmap (Display *dpy, Window window)
+{
+    XCompositeExtDisplayInfo	    *info = XCompositeFindDisplay (dpy);
+    xCompositeNameWindowPixmapReq   *req;
+    Pixmap			    pixmap;
+
+    XCompositeCheckExtension (dpy, info, 0);
+    LockDisplay (dpy);
+    GetReq (CompositeNameWindowPixmap, req);
+    req->reqType = info->codes->major_opcode;
+    req->compositeReqType = X_CompositeNameWindowPixmap;
+    req->window = window;
+    pixmap = req->pixmap = XAllocID (dpy);
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return pixmap;
+}
+
+#endif /* #ifndef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXcomposite.h b/nx-X11/programs/Xserver/hw/nxagent/NXcomposite.h
new file mode 100644
index 000000000..952e0d3e3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXcomposite.h
@@ -0,0 +1,86 @@
+#ifndef NXAGENT_UPGRADE
+
+/*
+ * $Id: Xcomposite.h,v 1.3 2005/07/03 07:00:56 daniels Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XCOMPOSITE_H_
+#define _XCOMPOSITE_H_
+
+#ifdef NXAGENT_SERVER
+
+#define XserverRegion XID
+
+#include "NXcompositeext.h"
+
+#else
+
+#include <X11/extensions/composite.h>
+#include <X11/extensions/Xfixes.h>
+
+#endif
+
+#include <X11/Xfuncproto.h>
+
+/*
+ * This revision number also appears in configure.ac, they have
+ * to be manually synchronized
+ */
+#define XCOMPOSITE_MAJOR	COMPOSITE_MAJOR
+#define XCOMPOSITE_MINOR	COMPOSITE_MINOR
+#define XCOMPOSITE_REVISION	0
+#define XCOMPOSITE_VERSION	((XCOMPOSITE_MAJOR * 10000) + (XCOMPOSITE_MINOR * 100) + (XCOMPOSITE_REVISION))
+
+_XFUNCPROTOBEGIN
+
+Bool XCompositeQueryExtension (Display *dpy, int *event_basep, int *error_basep);
+
+Status XCompositeQueryVersion (Display *dpy,
+			       int     *major_versionp,
+			       int     *minor_versionp);
+
+int XCompositeVersion (void);
+
+void
+XCompositeRedirectWindow (Display *dpy, Window window, int update);
+
+void
+XCompositeRedirectSubwindows (Display *dpy, Window window, int update);
+
+void
+XCompositeUnredirectWindow (Display *dpy, Window window, int update);
+
+void
+XCompositeUnredirectSubwindows (Display *dpy, Window window, int update);
+
+XserverRegion
+XCompositeCreateRegionFromBorderClip (Display *dpy, Window window);
+
+Pixmap
+XCompositeNameWindowPixmap (Display *dpy, Window window);
+
+_XFUNCPROTOEND
+
+#endif /* _XCOMPOSITE_H_ */
+
+#endif /* #ifndef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXcompositeext.h b/nx-X11/programs/Xserver/hw/nxagent/NXcompositeext.h
new file mode 100644
index 000000000..a22335153
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXcompositeext.h
@@ -0,0 +1,55 @@
+#ifndef NXAGENT_UPGRADE
+
+/*
+ * $Id: composite.h,v 1.4 2004/07/08 07:20:55 keithp Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _COMPOSITE_H_
+#define _COMPOSITE_H_
+
+#ifndef NXAGENT_SERVER
+
+#include <X11/extensions/xfixeswire.h>
+
+#endif
+
+#define COMPOSITE_NAME				"Composite"
+#define COMPOSITE_MAJOR				0
+#define COMPOSITE_MINOR				2
+
+#define CompositeRedirectAutomatic		0
+#define CompositeRedirectManual			1
+
+#define X_CompositeQueryVersion			0
+#define X_CompositeRedirectWindow		1
+#define X_CompositeRedirectSubwindows		2
+#define X_CompositeUnredirectWindow		3
+#define X_CompositeUnredirectSubwindows		4
+#define X_CompositeCreateRegionFromBorderClip	5
+#define X_CompositeNameWindowPixmap		6
+
+#define CompositeNumberRequests	    (X_CompositeNameWindowPixmap + 1)
+
+#endif /* _COMPOSITE_H_ */
+
+#endif /* #ifndef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXcompositeint.h b/nx-X11/programs/Xserver/hw/nxagent/NXcompositeint.h
new file mode 100644
index 000000000..044335abb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXcompositeint.h
@@ -0,0 +1,76 @@
+#ifndef NXAGENT_UPGRADE 
+
+/*
+ * $Id: xcompositeint.h,v 1.3 2005/07/12 03:10:35 keithp Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XDAMAGEINT_H_
+#define _XDAMAGEINT_H_
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+
+#ifdef NXAGENT_SERVER
+#include "NXcompositeproto.h"
+#include "NXcomposite.h"
+#else
+#include <X11/extensions/compositeproto.h>
+#include <X11/extensions/Xcomposite.h>
+#endif
+
+typedef struct _XCompositeExtDisplayInfo {
+    struct _XCompositeExtDisplayInfo  *next;    /* keep a linked list */
+    Display                 *display;	    /* which display this is */
+    XExtCodes               *codes;	    /* the extension protocol codes */
+    int			    major_version;  /* -1 means we don't know */
+    int			    minor_version;  /* -1 means we don't know */
+} XCompositeExtDisplayInfo;
+
+/* replaces XExtensionInfo */
+typedef struct _XCompositeExtInfo {
+    XCompositeExtDisplayInfo    *head;          /* start of the list */
+    XCompositeExtDisplayInfo    *cur;           /* most recently used */
+    int                     ndisplays;      /* number of displays */
+} XCompositeExtInfo;
+
+extern XCompositeExtInfo XCompositeExtensionInfo;
+extern const char XCompositeExtensionName[];
+
+XCompositeExtDisplayInfo *
+XCompositeFindDisplay (Display *dpy);
+
+#define XCompositeHasExtension(i) ((i) && ((i)->codes))
+
+#define XCompositeCheckExtension(dpy,i,val) \
+  if (!XCompositeHasExtension(i)) { return val; }
+
+#define XCompositeSimpleCheckExtension(dpy,i) \
+  if (!XCompositeHasExtension(i)) { return; }
+
+#endif /* _XDAMAGEINT_H_ */
+
+#endif /* #ifndef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXcompositeproto.h b/nx-X11/programs/Xserver/hw/nxagent/NXcompositeproto.h
new file mode 100644
index 000000000..cd31c7c8c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXcompositeproto.h
@@ -0,0 +1,148 @@
+#ifndef NXAGENT_UPGRADE
+
+/*
+ * $Id: compositeproto.h,v 1.4 2004/07/08 07:20:55 keithp Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _COMPOSITEPROTO_H_
+#define _COMPOSITEPROTO_H_
+
+#include <X11/Xmd.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "NXcomposite.h"
+
+#else
+
+#include <X11/extensions/composite.h>
+
+#endif
+
+#define Window CARD32
+#define Region CARD32
+
+/* 
+ * requests and replies
+ */
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length B16;
+    CARD32  majorVersion B32;
+    CARD32  minorVersion B32;
+} xCompositeQueryVersionReq;
+
+#define sz_xCompositeQueryVersionReq   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;
+} xCompositeQueryVersionReply;
+
+#define sz_xCompositeQueryVersionReply	32
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length B16;
+    Window  window B32;
+    CARD8   update;
+    CARD8   pad1;
+    CARD16  pad2 B16;
+} xCompositeRedirectWindowReq;
+
+#define sz_xCompositeRedirectWindowReq	12
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length B16;
+    Window  window B32;
+    CARD8   update;
+    CARD8   pad1;
+    CARD16  pad2 B16;
+} xCompositeRedirectSubwindowsReq;
+
+#define sz_xCompositeRedirectSubwindowsReq	    12
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length B16;
+    Window  window B32;
+    CARD8   update;
+    CARD8   pad1;
+    CARD16  pad2 B16;
+} xCompositeUnredirectWindowReq;
+
+#define sz_xCompositeUnredirectWindowReq    12
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length B16;
+    Window  window B32;
+    CARD8   update;
+    CARD8   pad1;
+    CARD16  pad2 B16;
+} xCompositeUnredirectSubwindowsReq;
+
+#define sz_xCompositeUnredirectSubwindowsReq   12
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length B16;
+    Region  region B32;
+    Window  window B32;
+} xCompositeCreateRegionFromBorderClipReq;
+
+#define sz_xCompositeCreateRegionFromBorderClipReq  12
+
+/* Version 0.2 additions */
+
+typedef struct {
+    CARD8   reqType;
+    CARD8   compositeReqType;
+    CARD16  length;
+    Window  window B32;
+    Pixmap  pixmap B32;
+} xCompositeNameWindowPixmapReq;
+
+#define sz_xCompositeNameWindowPixmapReq	    12
+
+#undef Window
+#undef Region
+
+#endif /* _COMPOSITEPROTO_H_ */
+
+#endif /* #ifndef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/NXdamage.c
new file mode 100644
index 000000000..8f43680b2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdamage.c
@@ -0,0 +1,5 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXdamage.c"
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
new file mode 100644
index 000000000..90da743a2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -0,0 +1,4716 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXdispatch.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/****************************************************************
+*                                                               *
+*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.29 2003/01/12 02:44:26 dawes Exp $ */
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#ifdef __sun
+#define False 0
+#define True 1
+#endif
+
+#define GC XlibGC
+#include <X11/Xlib.h>
+#undef GC
+
+#include "windowstr.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef XAPPGROUP
+#include "Xagsrv.h"
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include "XKBsrv.h"
+#endif
+
+#include "Atoms.h"
+#include "Splash.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Reconnect.h"
+#include "Millis.h"
+#include "Font.h"
+#include "Shadow.h"
+#include "Handlers.h"
+
+const int nxagentMaxFontNames = 10000;
+
+char dispatchExceptionAtReset = DE_RESET;
+
+/*
+ * This allows the agent to exit if no
+ * client is connected within a timeout.
+*/
+
+int nxagentClients = 0;
+
+void nxagentWaitDisplay(void);
+
+void nxagentListRemoteFonts(const char *, int);
+
+unsigned int nxagentWMtimeout = 0;
+Bool         nxagentWMPassed  = 0;
+
+/*
+ * Timeouts based on screen saver time.
+ */
+
+int nxagentAutoDisconnectTimeout = 0;
+
+#ifdef LBX
+#include "../../lbx/lbxserve.h"
+#endif
+
+#include "Xatom.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  WATCH
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef  BLOCKS
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+                                   (pWin) == nxagentViewportFrameRight || \
+                                       (pWin) == nxagentViewportFrameAbove || \
+                                           (pWin) == nxagentViewportFrameBelow)
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(
+#if NeedFunctionPrototypes
+    void
+#endif
+);
+
+static void DeleteClientFromAnySelections(
+#if NeedFunctionPrototypes
+    ClientPtr /*client*/
+#endif
+);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int	nClients;	/* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+char dispatchException = 0;
+char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue;   /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+    (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(c0, c1)
+    HWEventQueuePtr c0, c1;
+{
+    checkForInput[0] = c0;
+    checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+    TimeStamp systime;
+
+    /* To avoid time running backwards, we must call GetTimeInMillis before
+     * calling ProcessInputEvents.
+     */
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] != *checkForInput[1])
+	ProcessInputEvents();
+    if (CompareTimeStamps(systime, currentTime) == LATER)
+	currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+    TimeStamp systime;
+
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] == *checkForInput[1])
+	currentTime = systime;
+}
+
+void
+InitSelections()
+{
+    if (CurrentSelections)
+	xfree(CurrentSelections);
+    CurrentSelections = (Selection *)NULL;
+    NumCurrentSelections = 0;
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+      Selection *newsels;
+      newsels = (Selection *)xalloc(2 * sizeof(Selection));
+      if (!newsels)
+        return;
+      NumCurrentSelections += 2;
+      CurrentSelections = newsels;
+
+      CurrentSelections[0].selection = XA_PRIMARY;
+      CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[0].window = WindowTable[0]->drawable.id;
+      CurrentSelections[0].pWin = NULL;
+      CurrentSelections[0].client = NullClient;
+
+      CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
+      CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[1].window = WindowTable[0]->drawable.id;
+      CurrentSelections[1].pWin = NULL;
+      CurrentSelections[1].client = NullClient;
+    }
+#endif
+
+}
+
+void 
+FlushClientCaches(id)
+    XID id;
+{
+    int i;
+    register ClientPtr client;
+
+    client = clients[CLIENT_ID(id)];
+    if (client == NullClient)
+        return ;
+    for (i=0; i<currentMaxClients; i++)
+    {
+	client = clients[i];
+        if (client != NullClient)
+	{
+            if (client->lastDrawableID == id)
+	    {
+		client->lastDrawableID = WindowTable[0]->drawable.id;
+		client->lastDrawable = (DrawablePtr)WindowTable[0];
+	    }
+            else if (client->lastGCID == id)
+	    {
+                client->lastGCID = INVALID;
+		client->lastGC = (GCPtr)NULL;
+	    }
+	}
+    }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
+#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
+
+/*
+ * Disable the SmartScheduler as it doesn't
+ * seem to work for us.
+ */
+
+Bool	    SmartScheduleDisable = True;
+
+long	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long	    SmartScheduleTime;
+ClientPtr   SmartLastClient;
+int	    SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int         SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long	    SmartLastPrint;
+#endif
+
+void        Dispatch(void);
+void        InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+    ClientPtr	pClient;
+    int		i;
+    int		client;
+    int		bestPrio, best = 0;
+    int		bestRobin, robin;
+    long	now = SmartScheduleTime;
+    long	idle;
+
+    bestPrio = -0x7fffffff;
+    bestRobin = 0;
+    idle = 2 * SmartScheduleSlice;
+    for (i = 0; i < nready; i++)
+    {
+	client = clientReady[i];
+	pClient = clients[client];
+	/* Praise clients which are idle */
+	if ((now - pClient->smart_check_tick) >= idle)
+	{
+	    if (pClient->smart_priority < 0)
+		pClient->smart_priority++;
+	}
+	pClient->smart_check_tick = now;
+	
+	/* check priority to select best client */
+	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+	if (pClient->smart_priority > bestPrio ||
+	    (pClient->smart_priority == bestPrio && robin > bestRobin))
+	{
+	    bestPrio = pClient->smart_priority;
+	    bestRobin = robin;
+	    best = client;
+	}
+#ifdef SMART_DEBUG
+	if ((now - SmartLastPrint) >= 5000)
+	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+    }
+#ifdef SMART_DEBUG
+    if ((now - SmartLastPrint) >= 5000)
+    {
+	fprintf (stderr, " use %2d\n", best);
+	SmartLastPrint = now;
+    }
+#endif
+    pClient = clients[best];
+    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+    /*
+     * Set current client pointer
+     */
+    if (SmartLastClient != pClient)
+    {
+	pClient->smart_start_tick = now;
+	SmartLastClient = pClient;
+    }
+    /*
+     * Adjust slice
+     */
+    if (nready == 1)
+    {
+	/*
+	 * If it's been a long time since another client
+	 * has run, bump the slice up to get maximal
+	 * performance from a single client
+	 */
+	if ((now - pClient->smart_start_tick) > 1000 &&
+	    SmartScheduleSlice < SmartScheduleMaxSlice)
+	{
+	    SmartScheduleSlice += SmartScheduleInterval;
+	}
+    }
+    else
+    {
+	SmartScheduleSlice = SmartScheduleInterval;
+    }
+    return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+    register int        *clientReady;     /* array of request ready clients */
+    register int	result;
+    register ClientPtr	client;
+    register int	nready;
+    register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+    int			start_tick;
+#endif
+
+    unsigned long currentDispatch = 0;
+
+    nextFreeClientID = 1;
+    InitSelections();
+    nClients = 0;
+
+    /*
+     * The agent initialization was successfully
+     * completed. We can now handle our clients.
+     */
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+
+      nxagentSessionState = SESSION_UP;
+    }
+
+#ifdef NXAGENT_ONSTART
+
+    /*
+     * Set NX_WM property (used by NX client to identify
+     * the agent's window) three seconds since the first
+     * client connects.
+     */
+
+    nxagentWMtimeout = GetTimeInMillis() + 3000;
+
+#endif
+
+    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+    if (!clientReady)
+	return;
+
+  #ifdef WATCH
+
+  fprintf(stderr, "Dispatch: Watchpoint 12.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#3      1		352 bits (0 KB) ->	236 bits (0 KB) ->	352/1 -> 236/1	= 1.492:1
+#14     1		256 bits (0 KB) ->	101 bits (0 KB) ->	256/1 -> 101/1	= 2.535:1
+#16     1		256 bits (0 KB) ->	26 bits (0 KB) ->	256/1 -> 26/1	= 9.846:1
+#20     2	2	12256 bits (1 KB) ->	56 bits (0 KB) ->	6128/1 -> 28/1	= 218.857:1
+#43     1		256 bits (0 KB) ->	45 bits (0 KB) ->	256/1 -> 45/1	= 5.689:1
+#47     2	2	42304 bits (5 KB) ->	49 bits (0 KB) ->	21152/1 -> 24/1	= 863.347:1
+#98     1		256 bits (0 KB) ->	34 bits (0 KB) ->	256/1 -> 34/1	= 7.529:1
+*/
+
+  sleep(30);
+
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
+              dispatchException);
+
+  fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
+              dispatchExceptionAtReset);
+  #endif
+
+  if (!(dispatchException & DE_TERMINATE))
+    dispatchException = 0;
+
+    while (!dispatchException)
+    {
+        if (*icheck[0] != *icheck[1])
+	{
+	    ProcessInputEvents();
+	    FlushIfCriticalOutputPending();
+	}
+
+        /*
+         * Ensure we remove the splash after the timeout.
+         * Initializing clientReady[0] to -1 will tell
+         * WaitForSomething() to yield control after the
+         * timeout set in clientReady[1].
+         */
+
+        clientReady[0] = 0;
+
+        if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
+        {
+          #ifdef TEST
+          fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
+                      NXAGENT_WAKEUP);
+          #endif
+
+          clientReady[0] = -1;
+          clientReady[1] = NXAGENT_WAKEUP;
+        }
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[End dispatch]\n");
+        #endif
+
+	nready = WaitForSomething(clientReady);
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[Begin dispatch]\n");
+        #endif
+
+        #ifdef TEST
+        fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
+                    nready);
+        #endif
+        
+        #ifdef NXAGENT_ONSTART
+
+        currentDispatch = GetTimeInMillis();
+
+        /*
+         * If the timeout is expired set the
+         * selection informing the NX client
+         * that the agent is ready.
+         */
+
+         if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
+         {
+           nxagentRemoveSplashWindow(NULL);
+         }
+
+         nxagentClients = nClients;
+
+         #endif
+
+#ifdef SMART_SCHEDULE
+	if (nready && !SmartScheduleDisable)
+	{
+	    clientReady[0] = SmartScheduleClient (clientReady, nready);
+	    nready = 1;
+	}
+#endif
+       /***************** 
+	*  Handle events in round robin fashion, doing input between 
+	*  each round 
+	*****************/
+
+	while (!dispatchException && (--nready >= 0))
+	{
+	    client = clients[clientReady[nready]];
+	    if (! client)
+	    {
+		/* KillClient can cause this to happen */
+		continue;
+	    }
+	    /* GrabServer activation can cause this to be true */
+	    if (grabState == GrabKickout)
+	    {
+		grabState = GrabActive;
+		break;
+	    }
+	    isItTimeToYield = FALSE;
+ 
+            requestingClient = client;
+#ifdef SMART_SCHEDULE
+	    start_tick = SmartScheduleTime;
+#endif
+	    while (!isItTimeToYield)
+	    {
+	        if (*icheck[0] != *icheck[1])
+		{
+		    ProcessInputEvents();
+		    FlushIfCriticalOutputPending();
+		}
+#ifdef SMART_SCHEDULE
+		if (!SmartScheduleDisable && 
+		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+		{
+		    /* Penalize clients which consume ticks */
+		    if (client->smart_priority > SMART_MIN_PRIORITY)
+			client->smart_priority--;
+		    break;
+		}
+#endif
+		/* now, finally, deal with client requests */
+
+                #ifdef TEST
+                fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
+                            client->index);
+                #endif
+
+	        result = ReadRequestFromClient(client);
+	        if (result <= 0) 
+	        {
+		    if (result < 0)
+			CloseDownClient(client);
+		    break;
+	        }
+#ifdef NXAGENT_SERVER
+
+                #ifdef TEST
+
+                else
+                {
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
+                                      client->req_len << 2, client->index);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
+                                  nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
+                                      client->index);
+                    }
+                }
+
+                #endif
+#endif
+
+		client->sequence++;
+#ifdef DEBUG
+		if (client->requestLogIndex == MAX_REQUEST_LOG)
+		    client->requestLogIndex = 0;
+		client->requestLog[client->requestLogIndex] = MAJOROP;
+		client->requestLogIndex++;
+#endif
+		if (result > (MAX_BIG_REQUEST_SIZE << 2))
+		    result = BadLength;
+		else
+#ifdef NXAGENT_SERVER
+                {
+                    result = (* client->requestVector[MAJOROP])(client);
+
+                    #ifdef TEST
+
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d] result [%d].\n", MAJOROP,
+                                      *((char *) client->requestBuffer + 1), client->req_len << 2,
+                                          client->index, result);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
+                                  "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
+                                      client->req_len << 2, client->index, result);
+                    }
+
+                    #endif
+
+                    /*
+                     * Can set isItTimeToYield to force
+                     * the dispatcher to pay attention
+                     * to another client.
+                     */
+
+                    nxagentDispatchHandler(client, client->req_len << 2, 0);
+                }
+#else
+		    result = (* client->requestVector[MAJOROP])(client);
+#endif
+
+		if (result != Success) 
+		{
+		    if (client->noClientException != Success)
+                        CloseDownClient(client);
+                    else
+		        SendErrorToClient(client, MAJOROP,
+					  MinorOpcodeOfRequest(client),
+					  client->errorValue, result);
+		    break;
+	        }
+	    }
+	    FlushAllOutput();
+#ifdef SMART_SCHEDULE
+	    client = clients[clientReady[nready]];
+	    if (client)
+		client->smart_stop_tick = SmartScheduleTime;
+#endif
+	    requestingClient = NULL;
+	}
+	dispatchException &= ~DE_PRIORITYCHANGE;
+    }
+
+    if ((dispatchException & DE_RESET) && 
+            (serverGeneration > nxagentMaxAllowedResets))
+    {
+        dispatchException &= ~DE_RESET;
+        dispatchException |= DE_TERMINATE;
+
+        fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+    }
+
+    nxagentResetAtomMap();
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      /*
+       * The session is terminating. Force an I/O
+       * error on the display and wait until the
+       * NX transport is gone.
+       */
+
+      fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
+
+      nxagentWaitDisplay();
+
+      fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
+    }
+
+    if (nxagentOption(Shadow))
+    {
+      NXShadowDestroy();
+    }
+
+    KillAllClients();
+    DEALLOCATE_LOCAL(clientReady);
+    dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+/*ARGSUSED*/
+int
+ProcBadRequest(client)
+    ClientPtr client;
+{
+    return (BadRequest);
+}
+
+int
+ProcCreateWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pParent, pWin;
+    REQUEST(xCreateWindowReq);
+    int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+    
+    LEGAL_NEW_RESOURCE(stuff->wid, client);
+    if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+						    SecurityWriteAccess)))
+        return BadWindow;
+    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+    if (Ones(stuff->mask) != len)
+        return BadLength;
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+			      stuff->y, stuff->width, stuff->height, 
+			      stuff->borderWidth, stuff->class,
+			      stuff->mask, (XID *) &stuff[1], 
+			      (int)stuff->depth, 
+			      client, stuff->visual, &result);
+    if (pWin)
+    {
+	Mask mask = pWin->eventMask;
+
+	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+	    return BadAlloc;
+	pWin->eventMask = mask;
+    }
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcChangeWindowAttributes(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeWindowAttributesReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+    if (len != Ones(stuff->valueMask))
+        return BadLength;
+    result =  ChangeWindowAttributes(pWin, 
+				  stuff->valueMask, 
+				  (XID *) &stuff[1], 
+				  client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcGetWindowAttributes(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+    xGetWindowAttributesReply wa;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    GetWindowAttributes(pWin, client, &wa);
+    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+    return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->parent)
+	FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    DestroySubwindows(pWin, client);
+    return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeSaveSetReq);
+    register int result;
+		  
+    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+        return BadMatch;
+    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+    {
+        result = AlterSaveSetForClient(client, pWin, stuff->mode);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->mode;
+	return( BadValue );
+    }
+}
+
+int
+ProcReparentWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin, pParent;
+    REQUEST(xReparentWindowReq);
+    register int result;
+
+    REQUEST_SIZE_MATCH(xReparentWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    if (!nxagentWMPassed)
+    {
+      nxagentRemoveSplashWindow(pWin);
+    }
+
+    pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+					      SecurityWriteAccess);
+    if (!pParent)
+        return(BadWindow);
+    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+    {
+        if ((pWin->backgroundState == ParentRelative) &&
+            (pParent->drawable.depth != pWin->drawable.depth))
+            return BadMatch;
+	if ((pWin->drawable.class != InputOnly) &&
+	    (pParent->drawable.class == InputOnly))
+	    return BadMatch;
+        result =  ReparentWindow(pWin, pParent, 
+			 (short)stuff->x, (short)stuff->y, client);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else 
+        return (BadMatch);
+}
+
+int
+ProcMapWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapWindow(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapSubwindows(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapWindow(pWin, FALSE);
+           /* update cache to say it is mapped */
+
+    return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapSubwindows(pWin);
+    return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xConfigureWindowReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+    if (Ones((Mask)stuff->mask) != len)
+        return BadLength;
+    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
+			      client);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcCirculateWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xCirculateWindowReq);
+
+    REQUEST_SIZE_MATCH(xCirculateWindowReq);
+    if ((stuff->direction != RaiseLowest) &&
+	(stuff->direction != LowerHighest))
+    {
+	client->errorValue = stuff->direction;
+        return BadValue;
+    }
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    CirculateWindow(pWin, (int)stuff->direction, client);
+    return(client->noClientException);
+}
+
+int
+GetGeometry(client, rep)
+    register ClientPtr client;
+    xGetGeometryReply *rep;
+{
+    register DrawablePtr pDraw;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+    rep->type = X_Reply;
+    rep->length = 0;
+    rep->sequenceNumber = client->sequence;
+    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+    rep->depth = pDraw->depth;
+    rep->width = pDraw->width;
+    rep->height = pDraw->height;
+
+    /* XXX - Because the pixmap-implementation of the multibuffer extension 
+     *       may have the buffer-id's drawable resource value be a pointer
+     *       to the buffer's window instead of the buffer itself
+     *       (this happens if the buffer is the displayed buffer),
+     *       we also have to check that the id matches before we can
+     *       truly say that it is a DRAWABLE_WINDOW.
+     */
+
+    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+    {
+        register WindowPtr pWin = (WindowPtr)pDraw;
+	rep->x = pWin->origin.x - wBorderWidth (pWin);
+	rep->y = pWin->origin.y - wBorderWidth (pWin);
+	rep->borderWidth = pWin->borderWidth;
+    }
+    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+    {
+	rep->x = rep->y = rep->borderWidth = 0;
+    }
+
+    return Success;
+}
+
+
+int
+ProcGetGeometry(client)
+    register ClientPtr client;
+{
+    xGetGeometryReply rep;
+    int status;
+
+    if ((status = GetGeometry(client, &rep)) != Success)
+	return status;
+
+    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+    return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(client)
+    register ClientPtr client;
+{
+    xQueryTreeReply reply;
+    int numChildren = 0;
+    register WindowPtr pChild, pWin, pHead;
+    Window  *childIDs = (Window *)NULL;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    reply.type = X_Reply;
+    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+    reply.sequenceNumber = client->sequence;
+    if (pWin->parent)
+	reply.parent = pWin->parent->drawable.id;
+    else
+        reply.parent = (Window)None;
+    pHead = RealChildHead(pWin);
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+      if (!IsViewportFrame(pChild))
+      {
+	numChildren++;
+      }
+    }
+    if (numChildren)
+    {
+	int curChild = 0;
+
+	childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+	if (!childIDs)
+	    return BadAlloc;
+	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+        {
+          if (!IsViewportFrame(pChild))
+          {
+	    childIDs[curChild++] = pChild->drawable.id;
+          }
+        }
+    }
+    
+    reply.nChildren = numChildren;
+    reply.length = (numChildren * sizeof(Window)) >> 2;
+    
+    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+    if (numChildren)
+    {
+    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+	DEALLOCATE_LOCAL(childIDs);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcInternAtom(client)
+    register ClientPtr client;
+{
+    Atom atom;
+    char *tchar;
+    REQUEST(xInternAtomReq);
+
+    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+    {
+	client->errorValue = stuff->onlyIfExists;
+        return(BadValue);
+    }
+    tchar = (char *) &stuff[1];
+    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+    if (atom != BAD_RESOURCE)
+    {
+	xInternAtomReply reply;
+	reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+	reply.atom = atom;
+	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+	return(client->noClientException);
+    }
+    else
+	return (BadAlloc);
+}
+
+int
+ProcGetAtomName(client)
+    register ClientPtr client;
+{
+    char *str;
+    xGetAtomNameReply reply;
+    int len;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if ( (str = NameForAtom(stuff->id)) )
+    {
+	len = strlen(str);
+	reply.type = X_Reply;
+	reply.length = (len + 3) >> 2;
+	reply.sequenceNumber = client->sequence;
+	reply.nameLength = len;
+	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+	(void)WriteToClient(client, len, str);
+	return(client->noClientException);
+    }
+    else 
+    { 
+	client->errorValue = stuff->id;
+	return (BadAtom);
+    }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(client)
+    register ClientPtr client;
+{
+    WindowPtr pWin;
+    TimeStamp time;
+    REQUEST(xSetSelectionOwnerReq);
+
+    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+    UpdateCurrentTime();
+    time = ClientTimeToServerTime(stuff->time);
+
+    /* If the client's time stamp is in the future relative to the server's
+	time stamp, do not set the selection, just return success. */
+    if (CompareTimeStamps(time, currentTime) == LATER)
+    	return Success;
+    if (stuff->window != None)
+    {
+        pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					       SecurityReadAccess);
+        if (!pWin)
+            return(BadWindow);
+    }
+    else
+        pWin = (WindowPtr)None;
+    if (ValidAtom(stuff->selection))
+    {
+	int i = 0;
+
+	/*
+	 * First, see if the selection is already set... 
+	 */
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) 
+            i++;
+        if (i < NumCurrentSelections)
+        {        
+	    xEvent event;
+
+	    /* If the timestamp in client's request is in the past relative
+		to the time stamp indicating the last time the owner of the
+		selection was set, do not set the selection, just return 
+		success. */
+            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+		== EARLIER)
+		return Success;
+	    if (CurrentSelections[i].client &&
+		(!pWin || (CurrentSelections[i].client != client)))
+	    {
+		event.u.u.type = SelectionClear;
+		event.u.selectionClear.time = time.milliseconds;
+		event.u.selectionClear.window = CurrentSelections[i].window;
+		event.u.selectionClear.atom = CurrentSelections[i].selection;
+		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+				NoEventMask, NoEventMask /* CantBeFiltered */,
+				NullGrab);
+	    }
+	}
+	else
+	{
+	    /*
+	     * It doesn't exist, so add it...
+	     */
+	    Selection *newsels;
+
+	    if (i == 0)
+		newsels = (Selection *)xalloc(sizeof(Selection));
+	    else
+		newsels = (Selection *)xrealloc(CurrentSelections,
+			    (NumCurrentSelections + 1) * sizeof(Selection));
+	    if (!newsels)
+		return BadAlloc;
+	    NumCurrentSelections++;
+	    CurrentSelections = newsels;
+	    CurrentSelections[i].selection = stuff->selection;
+	}
+        CurrentSelections[i].lastTimeChanged = time;
+	CurrentSelections[i].window = stuff->window;
+	CurrentSelections[i].pWin = pWin;
+	CurrentSelections[i].client = (pWin ? client : NullClient);
+
+#ifdef NXAGENT_CLIPBOARD
+      if ((CurrentSelections[i].pWin != NULL) &&
+              (nxagentOption(Clipboard) != ClipboardNone) &&
+                  ((CurrentSelections[i].selection == XA_PRIMARY) ||
+                       (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
+      {
+        nxagentSetSelectionOwner(&CurrentSelections[i]);
+      }
+#endif
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->selection;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGetSelectionOwner(client)
+    register ClientPtr client;
+{
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (ValidAtom(stuff->id))
+    {
+	int i;
+        xGetSelectionOwnerReply reply;
+
+	i = 0;
+        while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->id) i++;
+        reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+        if (i < NumCurrentSelections)
+            reply.owner = CurrentSelections[i].window;
+        else
+            reply.owner = None;
+        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+        return(client->noClientException);
+    }
+    else            
+    {
+	client->errorValue = stuff->id;
+        return (BadAtom); 
+    }
+}
+
+int
+ProcConvertSelection(client)
+    register ClientPtr client;
+{
+    Bool paramsOkay;
+    xEvent event;
+    WindowPtr pWin;
+    REQUEST(xConvertSelectionReq);
+
+    REQUEST_SIZE_MATCH(xConvertSelectionReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+#ifdef NXAGENT_CLIPBOARD
+    if (((stuff->selection == XA_PRIMARY) ||
+           (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
+               nxagentOption(Clipboard) != ClipboardNone)
+    {
+      int i = 0;
+
+      while ((i < NumCurrentSelections) &&
+                CurrentSelections[i].selection != stuff->selection) i++;
+
+      if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
+      {
+        if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
+                                       stuff->property, stuff->target, stuff->time))
+        {
+          return (client->noClientException);
+        }
+      }
+    }
+#endif
+
+    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+    if (stuff->property != None)
+	paramsOkay &= ValidAtom(stuff->property);
+    if (paramsOkay)
+    {
+	int i;
+
+	i = 0;
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) i++;
+	if ((i < NumCurrentSelections) && 
+	    (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+#ifdef XCSECURITY
+	    && (!client->CheckAccess ||
+		(* client->CheckAccess)(client, CurrentSelections[i].window,
+					RT_WINDOW, SecurityReadAccess,
+					CurrentSelections[i].pWin))
+#endif
+	    )
+	{        
+	    event.u.u.type = SelectionRequest;
+	    event.u.selectionRequest.time = stuff->time;
+	    event.u.selectionRequest.owner = 
+			CurrentSelections[i].window;
+	    event.u.selectionRequest.requestor = stuff->requestor;
+	    event.u.selectionRequest.selection = stuff->selection;
+	    event.u.selectionRequest.target = stuff->target;
+	    event.u.selectionRequest.property = stuff->property;
+	    if (TryClientEvents(
+		CurrentSelections[i].client, &event, 1, NoEventMask,
+		NoEventMask /* CantBeFiltered */, NullGrab))
+		return (client->noClientException);
+	}
+	event.u.u.type = SelectionNotify;
+	event.u.selectionNotify.time = stuff->time;
+	event.u.selectionNotify.requestor = stuff->requestor;
+	event.u.selectionNotify.selection = stuff->selection;
+	event.u.selectionNotify.target = stuff->target;
+	event.u.selectionNotify.property = None;
+	(void) TryClientEvents(client, &event, 1, NoEventMask,
+			       NoEventMask /* CantBeFiltered */, NullGrab);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->property;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGrabServer(client)
+    register ClientPtr client;
+{
+    REQUEST_SIZE_MATCH(xReq);
+    if (grabState != GrabNone && client != grabClient)
+    {
+	ResetCurrentRequest(client);
+	client->sequence--;
+	BITSET(grabWaiters, client->index);
+	IgnoreClient(client);
+	return(client->noClientException);
+    }
+    OnlyListenToOneClient(client);
+    grabState = GrabKickout;
+    grabClient = client;
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_GRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+
+    return(client->noClientException);
+}
+
+static void
+#if NeedFunctionPrototypes
+UngrabServer(ClientPtr client)
+#else
+UngrabServer(client)
+    ClientPtr client;
+#endif
+{
+    int i;
+
+    grabState = GrabNone;
+    ListenToAllClients();
+    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+	;
+    if (i >= 0)
+    {
+	i <<= 5;
+	while (!GETBIT(grabWaiters, i))
+	    i++;
+	BITCLEAR(grabWaiters, i);
+	AttendClient(clients[i]);
+    }
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_UNGRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+}
+
+int
+ProcUngrabServer(client)
+    register ClientPtr client;
+{
+    REQUEST_SIZE_MATCH(xReq);
+    UngrabServer(client);
+    return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(client)
+    register ClientPtr client;
+{
+    REQUEST(xTranslateCoordsReq);
+
+    register WindowPtr pWin, pDst;
+    xTranslateCoordsReply rep;
+
+    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+					   SecurityReadAccess);
+    if (!pDst)
+        return(BadWindow);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+    {
+	rep.sameScreen = xFalse;
+        rep.child = None;
+	rep.dstX = rep.dstY = 0;
+    }
+    else
+    {
+	INT16 x, y;
+	rep.sameScreen = xTrue;
+	rep.child = None;
+	/* computing absolute coordinates -- adjust to destination later */
+	x = pWin->drawable.x + stuff->srcX;
+	y = pWin->drawable.y + stuff->srcY;
+	pWin = pDst->firstChild;
+	while (pWin)
+	{
+#ifdef SHAPE
+	    BoxRec  box;
+#endif
+	    if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		 wBorderWidth (pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		 wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen, 
+					&pWin->borderSize, x, y, &box))
+#endif
+		)
+            {
+		rep.child = pWin->drawable.id;
+		pWin = (WindowPtr) NULL;
+	    }
+	    else
+		pWin = pWin->nextSib;
+	}
+	/* adjust to destination coordinates */
+	rep.dstX = x - pDst->drawable.x;
+	rep.dstY = y - pDst->drawable.y;
+    }
+    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+    return(client->noClientException);
+}
+
+int
+ProcOpenFont(client)
+    register ClientPtr client;
+{
+    int	err;
+    char fontReq[256];
+    REQUEST(xOpenFontReq);
+
+    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+    client->errorValue = stuff->fid;
+    LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+    memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    fontReq[stuff->nbytes]=0;
+    if (strchr(fontReq,'*') || strchr(fontReq,'?'))
+    {
+       extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
+#ifdef NXAGENT_FONTMATCH_DEBUG
+       fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
+#endif
+       nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
+       err = nxOpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    }
+    else
+    err = OpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcCloseFont(client)
+    register ClientPtr client;
+{
+    FontPtr pFont;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityDestroyAccess);
+    if (pFont != (FontPtr)NULL)
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client closes a font the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this font looping through the
+         * resources.
+         */
+
+        if (pFont -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
+                        (void *) pFont);
+            #endif
+
+            nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
+                        "resource switching skipped.\n", (void *) pFont);
+          }
+          #endif
+        }
+
+        #endif
+
+        FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+        return (BadFont);
+    }
+}
+
+int
+ProcQueryFont(client)
+    register ClientPtr client;
+{
+    xQueryFontReply	*reply;
+    FontPtr pFont;
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    client->errorValue = stuff->id;		/* EITHER font or gc */
+
+    pFont = NULL;
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+	  /* can't use VERIFY_GC because it might return BadGC */
+	pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+					    SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->id;
+            return(BadFont);     /* procotol spec says only error is BadFont */
+	}
+	pFont = pGC->font;
+    }
+
+/* test
+{
+  Atom name_atom, value_atom;
+  int nprops;
+  FontPropPtr props;
+  int i;
+  char *name;
+
+  name_atom = MakeAtom("FONT", 4, True);
+  value_atom = 0L;
+
+  nprops = pFont->info.nprops;
+  props = pFont->info.props;
+
+  for (i = 0; i < nprops; i++)
+    if (props[i].name == name_atom) {
+      value_atom = props[i].value;
+      break;
+    }
+
+  if (!value_atom) return (BadFont);
+
+  name = (char *)NameForAtom(value_atom);
+  fprintf(stderr, "QueryFont: font name [%s]\n",name);
+}
+ end test */
+
+    {
+	xCharInfo	*pmax = FONTINKMAX(pFont);
+	xCharInfo	*pmin = FONTINKMIN(pFont);
+	int		nprotoxcistructs;
+	int		rlength;
+
+	nprotoxcistructs = (
+	   pmax->rightSideBearing == pmin->rightSideBearing &&
+	   pmax->leftSideBearing == pmin->leftSideBearing &&
+	   pmax->descent == pmin->descent &&
+	   pmax->ascent == pmin->ascent &&
+	   pmax->characterWidth == pmin->characterWidth) ?
+		0 : N2dChars(pFont);
+
+	rlength = sizeof(xQueryFontReply) +
+	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
+		     nprotoxcistructs * sizeof(xCharInfo);
+        reply = NULL;
+	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+	if(!reply)
+	{
+	    return(BadAlloc);
+	}
+
+	reply->type = X_Reply;
+	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+	reply->sequenceNumber = client->sequence;
+	QueryFont( pFont, reply, nprotoxcistructs);
+
+        WriteReplyToClient(client, rlength, reply);
+	DEALLOCATE_LOCAL(reply);
+	return(client->noClientException);
+    }
+}
+
+int
+ProcQueryTextExtents(client)
+    register ClientPtr client;
+{
+    REQUEST(xQueryTextExtentsReq);
+    xQueryTextExtentsReply reply;
+    FontPtr pFont;
+    GC *pGC;
+    ExtentInfoRec info;
+    unsigned long length;
+
+    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+        
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+					   SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->fid;
+            return(BadFont);
+	}
+	pFont = pGC->font;
+    }
+    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+    length = length << 1;
+    if (stuff->oddLength)
+    {
+	if (length == 0)
+	    return(BadLength);
+        length--;
+    }
+    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+	return(BadAlloc);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.drawDirection = info.drawDirection;
+    reply.fontAscent = info.fontAscent;
+    reply.fontDescent = info.fontDescent;
+    reply.overallAscent = info.overallAscent;
+    reply.overallDescent = info.overallDescent;
+    reply.overallWidth = info.overallWidth;
+    reply.overallLeft = info.overallLeft;
+    reply.overallRight = info.overallRight;
+    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListFonts(client)
+    register ClientPtr client;
+{
+    char tmp[256];
+
+    REQUEST(xListFontsReq);
+
+    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
+	stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(client)
+    register ClientPtr client;
+{
+    char tmp[256];
+    REQUEST(xListFontsWithInfoReq);
+
+    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
+
+    return StartListFontsWithInfo(client, stuff->nbytes,
+				  (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/*ARGSUSED*/
+int
+dixDestroyPixmap(value, pid)
+    pointer value; /* must conform to DeleteType */
+    XID pid;
+{
+    PixmapPtr pPixmap = (PixmapPtr)value;
+    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    REQUEST(xCreatePixmapReq);
+    DepthPtr pDepth;
+    register int i;
+
+    REQUEST_SIZE_MATCH(xCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+		(pDraw->pScreen, stuff->width,
+		 stuff->height, stuff->depth);
+    if (pMap)
+    {
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	    return(client->noClientException);
+    }
+    return (BadAlloc);
+}
+
+int
+ProcFreePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+					     SecurityDestroyAccess);
+    if (pMap) 
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client releases a pixmap the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this pixmap looping through the
+         * resources.
+         */
+
+        if (pMap -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
+                       (void *) pMap);
+            #endif
+
+            nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
+                        "resource switching skipped.\n", (void *) pMap);
+          }
+          #endif
+        }
+
+        #endif
+
+	FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadPixmap);
+    }
+}
+
+int
+ProcCreateGC(client)
+    register ClientPtr client;
+{
+    int error;
+    GC *pGC;
+    register DrawablePtr pDraw;
+    unsigned len;
+    REQUEST(xCreateGCReq);
+
+    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+    client->errorValue = stuff->gc;
+    LEGAL_NEW_RESOURCE(stuff->gc, client);
+    SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+			      SecurityReadAccess);
+    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+    pGC = (GC *)CreateGC(pDraw, stuff->mask, 
+			 (XID *) &stuff[1], &error);
+    if (error != Success)
+        return error;
+    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+	return (BadAlloc);
+    return(client->noClientException);
+}
+
+int
+ProcChangeGC(client)
+    register ClientPtr client;
+{
+    GC *pGC;
+    REQUEST(xChangeGCReq);
+    int result;
+    unsigned len;
+		
+    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+    SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+
+    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcCopyGC(client)
+    register ClientPtr client;
+{
+    register GC *dstGC;
+    register GC *pGC;
+    int result;
+    REQUEST(xCopyGCReq);
+
+    REQUEST_SIZE_MATCH(xCopyGCReq);
+    SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+    SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+        return (BadMatch);    
+    result = CopyGC(pGC, dstGC, stuff->mask);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetDashes(client)
+    register ClientPtr client;
+{
+    register GC *pGC;
+    int result;
+    REQUEST(xSetDashesReq);
+
+    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+    if (stuff->nDashes == 0)
+    {
+	 client->errorValue = 0;
+         return BadValue;
+    }
+
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+		       (unsigned char *)&stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetClipRectangles(client)
+    register ClientPtr client;
+{
+    int	nr;
+    int result;
+    register GC *pGC;
+    REQUEST(xSetClipRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+    {
+	client->errorValue = stuff->ordering;
+        return BadValue;
+    }
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+		 
+    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+    if (nr & 4)
+	return(BadLength);
+    nr >>= 3;
+    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcFreeGC(client)
+    register ClientPtr client;
+{
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+    FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcClearToBackground(client)
+    register ClientPtr client;
+{
+    REQUEST(xClearAreaReq);
+    register WindowPtr pWin;
+
+    REQUEST_SIZE_MATCH(xClearAreaReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->drawable.class == InputOnly)
+    {
+	client->errorValue = stuff->window;
+	return (BadMatch);
+    }		    
+    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+    {
+	client->errorValue = stuff->exposures;
+        return(BadValue);
+    }
+    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+			       stuff->width, stuff->height,
+			       (Bool)stuff->exposures);
+    return(client->noClientException);
+}
+
+int
+ProcCopyArea(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDst;
+    register DrawablePtr pSrc;
+    register GC *pGC;
+    REQUEST(xCopyAreaReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        pSrc = pDst;
+
+    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY);
+    if (pGC->graphicsExposures)
+    {
+	(*pDst->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+	if (pRgn)
+	    REGION_DESTROY(pDst->pScreen, pRgn);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcCopyPlane(client)
+    register ClientPtr client;
+{
+    register DrawablePtr psrcDraw, pdstDraw;
+    register GC *pGC;
+    REQUEST(xCopyPlaneReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if (pdstDraw->pScreen != psrcDraw->pScreen)
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        psrcDraw = pdstDraw;
+
+    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+    {
+       client->errorValue = stuff->bitPlane;
+       return(BadValue);
+    }
+
+    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY, stuff->bitPlane);
+    if (pGC->graphicsExposures)
+    {
+	(*pdstDraw->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+	if (pRgn)
+	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyPoint(client)
+    register ClientPtr client;
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyPointReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
+    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+    if (npoint)
+    {
+        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+			  (xPoint *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyLine(client)
+    register ClientPtr client;
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyLineReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+    if (npoint > 1)
+    {
+	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
+			      (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolySegment(client)
+    register ClientPtr client;
+{
+    int nsegs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolySegmentReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+    if (nsegs & 4)
+	return(BadLength);
+    nsegs >>= 3;
+    if (nsegs)
+    {
+        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (client)
+    register ClientPtr client;
+{
+    int nrects;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+    if (nrects & 4)
+	return(BadLength);
+    nrects >>= 3;
+    if (nrects)
+    {
+        (*pGC->ops->PolyRectangle)(pDraw, pGC, 
+		    nrects, (xRectangle *) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyArc(client)
+    register ClientPtr client;
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcFillPoly(client)
+    register ClientPtr client;
+{
+    int          things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xFillPolyReq);
+
+    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
+	(stuff->shape != Convex))
+    {
+	client->errorValue = stuff->shape;
+        return BadValue;
+    }
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+    if (things)
+    {
+        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+			 stuff->coordMode, things,
+			 (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(client)
+    register ClientPtr client;
+{
+    int             things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+
+    if (things)
+    {
+        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+		      (xRectangle *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(client)
+    register ClientPtr client;
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+    int	    whichbyte = 1;
+
+    if (*((char *) &whichbyte))
+	return LSBFirst;
+    return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+    switch (bpp) {
+    case 1:	/* yuck */
+	if (BITMAP_BIT_ORDER != order)
+	    BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+	break;
+    case 4:
+	break;  /* yuck */
+    case 8:
+	break;
+    case 16:
+	if (IMAGE_BYTE_ORDER != order)
+	    TwoByteSwap ((unsigned char *) base, nbytes);
+	break;
+    case 32:
+	if (IMAGE_BYTE_ORDER != order)
+	    FourByteSwap ((unsigned char *) base, nbytes);
+	break;
+    }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(client)
+    register ClientPtr client;
+{
+    register	GC *pGC;
+    register	DrawablePtr pDraw;
+    long	length; 	/* length of scanline server padded */
+    long 	lengthProto; 	/* length of scanline protocol padded */
+    char	*tmpImage;
+    REQUEST(xPutImageReq);
+
+    REQUEST_AT_LEAST_SIZE(xPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    if (stuff->format == XYBitmap)
+    {
+        if ((stuff->depth != 1) ||
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || 
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length      = BitmapBytePad(stuff->width + stuff->leftPad);
+	length      *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+            return BadMatch;
+        length      = PixmapBytePad(stuff->width, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    tmpImage = (char *)&stuff[1];
+    lengthProto = length;
+	
+    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 
+	(sizeof(xPutImageReq) >> 2)) != client->req_len)
+	return BadLength;
+
+    ReformatImage (tmpImage, lengthProto * stuff->height, 
+		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+		   ClientOrder(client));
+    
+    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+		  stuff->width, stuff->height, 
+		  stuff->leftPad, stuff->format, tmpImage);
+
+     return (client->noClientException);
+}
+
+
+int
+DoGetImage(client, format, drawable, x, y, width, height, planemask, im_return)
+    register ClientPtr	client;
+    Drawable drawable;
+    int format;
+    int x, y, width, height;
+    Mask planemask;
+    xGetImageReply **im_return;
+{
+    register DrawablePtr pDraw;
+    int			nlines, linesPerBuf;
+    register int	linesDone;
+    long		widthBytesLine, length;
+    Mask		plane = 0;
+    char		*pBuf;
+    xGetImageReply	xgi;
+    RegionPtr pVisibleRegion = NULL;
+
+    if ((format != XYPixmap) && (format != ZPixmap))
+    {
+	client->errorValue = format;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+    if(pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + x < 0 ||
+ 	 pDraw->x + x + width > pDraw->pScreen->width ||
+         pDraw->y + y < 0 ||
+         pDraw->y + y + height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         x < - wBorderWidth((WindowPtr)pDraw) ||
+         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         y < -wBorderWidth((WindowPtr)pDraw) ||
+         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual (((WindowPtr) pDraw));
+    }
+    else
+    {
+      if(x < 0 ||
+         x+width > (int)pDraw->width ||
+         y < 0 ||
+         y+height > (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+
+    SET_DBE_SRCBUF(pDraw, drawable);
+
+    xgi.type = X_Reply;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(format == ZPixmap)
+    {
+	widthBytesLine = PixmapBytePad(width, pDraw->depth);
+	length = widthBytesLine * height;
+
+    }
+    else 
+    {
+	widthBytesLine = BitmapBytePad(width);
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = widthBytesLine * height *
+		 Ones(planemask & (plane | (plane - 1)));
+
+    }
+
+    xgi.length = length;
+
+    if (im_return) {
+	pBuf = (char *)xalloc(sz_xGetImageReply + length);
+	if (!pBuf)
+	    return (BadAlloc);
+	if (widthBytesLine == 0)
+	    linesPerBuf = 0;
+	else
+	    linesPerBuf = height;
+	*im_return = (xGetImageReply *)pBuf;
+	*(xGetImageReply *)pBuf = xgi;
+	pBuf += sz_xGetImageReply;
+    } else {
+	xgi.length = (xgi.length + 3) >> 2;
+	if (widthBytesLine == 0 || height == 0)
+	    linesPerBuf = 0;
+	else if (widthBytesLine >= IMAGE_BUFSIZE)
+	    linesPerBuf = 1;
+	else
+	{
+	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+	    if (linesPerBuf > height)
+		linesPerBuf = height;
+	}
+	length = linesPerBuf * widthBytesLine;
+	if (linesPerBuf < height)
+	{
+	    /* we have to make sure intermediate buffers don't need padding */
+	    while ((linesPerBuf > 1) &&
+		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+	    {
+		linesPerBuf--;
+		length -= widthBytesLine;
+	    }
+	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+	    {
+		linesPerBuf++;
+		length += widthBytesLine;
+	    }
+	}
+	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+	    return (BadAlloc);
+	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+    }
+
+#ifdef XCSECURITY
+    if (client->trustLevel != XSecurityClientTrusted &&
+	pDraw->type == DRAWABLE_WINDOW)
+    {
+	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+	if (pVisibleRegion)
+	{
+	    REGION_TRANSLATE(pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+	}
+    }
+#endif
+
+    if (linesPerBuf == 0)
+    {
+	/* nothing to do */
+    }
+    else if (format == ZPixmap)
+    {
+        linesDone = 0;
+        while (height - linesDone > 0)
+        {
+	    nlines = min(linesPerBuf, height - linesDone);
+	    (*pDraw->pScreen->GetImage) (pDraw,
+	                                 x,
+				         y + linesDone,
+				         width, 
+				         nlines,
+				         format,
+				         planemask,
+				         (pointer) pBuf);
+#ifdef XCSECURITY
+	    if (pVisibleRegion)
+		SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+			pDraw, x, y + linesDone, width, 
+			nlines, format, pBuf);
+#endif
+
+	    /* Note that this is NOT a call to WriteSwappedDataToClient,
+               as we do NOT byte swap */
+	    if (!im_return)
+	    {
+		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+			       BitsPerPixel (pDraw->depth),
+			       ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+		(void)WriteToClient(client,
+				    (int)(nlines * widthBytesLine),
+				    pBuf);
+	    }
+	    linesDone += nlines;
+        }
+    }
+    else /* XYPixmap */
+    {
+        for (; plane; plane >>= 1)
+	{
+	    if (planemask & plane)
+	    {
+	        linesDone = 0;
+	        while (height - linesDone > 0)
+	        {
+		    nlines = min(linesPerBuf, height - linesDone);
+	            (*pDraw->pScreen->GetImage) (pDraw,
+	                                         x,
+				                 y + linesDone,
+				                 width, 
+				                 nlines,
+				                 format,
+				                 plane,
+				                 (pointer)pBuf);
+#ifdef XCSECURITY
+		    if (pVisibleRegion)
+			SecurityCensorImage(client, pVisibleRegion,
+				widthBytesLine,
+				pDraw, x, y + linesDone, width, 
+				nlines, format, pBuf);
+#endif
+
+		    /* Note: NOT a call to WriteSwappedDataToClient,
+		       as we do NOT byte swap */
+		    if (im_return) {
+			pBuf += nlines * widthBytesLine;
+		    } else {
+			ReformatImage (pBuf, 
+				       (int)(nlines * widthBytesLine), 
+				       1,
+				       ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+			(void)WriteToClient(client,
+					(int)(nlines * widthBytesLine),
+					pBuf);
+		    }
+		    linesDone += nlines;
+		}
+            }
+	}
+    }
+#ifdef XCSECURITY
+    if (pVisibleRegion)
+	REGION_DESTROY(pScreen, pVisibleRegion);
+#endif
+    if (!im_return)
+	DEALLOCATE_LOCAL(pBuf);
+    return (client->noClientException);
+}
+
+int
+ProcGetImage(client)
+    register ClientPtr	client;
+{
+    REQUEST(xGetImageReq);
+
+    REQUEST_SIZE_MATCH(xGetImageReq);
+
+    return DoGetImage(client, stuff->format, stuff->drawable,
+		      stuff->x, stuff->y,
+		      (int)stuff->width, (int)stuff->height,
+		      stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(client)
+    register ClientPtr client;
+{
+    int	err;
+    REQUEST(xPolyTextReq);
+    DrawablePtr pDraw;
+    GC *pGC;
+
+    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = PolyText(client,
+		   pDraw,
+		   pGC,
+		   (unsigned char *)&stuff[1],
+		   ((unsigned char *) stuff) + (client->req_len << 2),
+		   stuff->x,
+		   stuff->y,
+		   stuff->reqType,
+		   stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText8(client)
+    register ClientPtr client;
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText16(client)
+    register ClientPtr client;
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+
+int
+ProcCreateColormap(client)
+    register ClientPtr client;
+{
+    VisualPtr	pVisual;
+    ColormapPtr	pmap;
+    Colormap	mid;
+    register WindowPtr   pWin;
+    ScreenPtr pScreen;
+    REQUEST(xCreateColormapReq);
+    int i, result;
+
+    REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+    {
+	client->errorValue = stuff->alloc;
+        return(BadValue);
+    }
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pScreen = pWin->drawable.pScreen;
+    for (i = 0, pVisual = pScreen->visuals;
+	 i < pScreen->numVisuals;
+	 i++, pVisual++)
+    {
+	if (pVisual->vid != stuff->visual)
+	    continue;
+	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
+				 (int)stuff->alloc, client->index);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+	    return(result);
+    }
+    client->errorValue = stuff->visual;
+    return(BadValue);
+}
+
+int
+ProcFreeColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pmap;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+						SecurityDestroyAccess);
+    if (pmap) 
+    {
+	/* Freeing a default colormap is a no-op */
+	if (!(pmap->flags & IsDefault))
+	    FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadColor);
+    }
+}
+
+
+int
+ProcCopyColormapAndFree(client)
+    register ClientPtr client;
+{
+    Colormap	mid;
+    ColormapPtr	pSrcMap;
+    REQUEST(xCopyColormapAndFreeReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client,	stuff->srcCmap,
+		RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+    {
+	result = CopyColormapAndFree(mid, pSrcMap, client->index);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->srcCmap;
+	return(BadColor);
+    }
+}
+
+int
+ProcInstallColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					    RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+        (*(pcmp->pScreen->InstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcUninstallColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	if(pcmp->mid != pcmp->pScreen->defColormap)
+            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcListInstalledColormaps(client)
+    register ClientPtr client;
+{
+    xListInstalledColormapsReply *preply; 
+    int nummaps;
+    WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+
+    if (!pWin)
+        return(BadWindow);
+
+    preply = (xListInstalledColormapsReply *) 
+		ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+		     pWin->drawable.pScreen->maxInstalledCmaps *
+		     sizeof(Colormap));
+    if(!preply)
+        return(BadAlloc);
+
+    preply->type = X_Reply;
+    preply->sequenceNumber = client->sequence;
+    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+    preply->nColormaps = nummaps;
+    preply->length = nummaps;
+    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+    DEALLOCATE_LOCAL(preply);
+    return(client->noClientException);
+}
+
+int
+ProcAllocColor(client)
+    register ClientPtr client;
+{
+    ColormapPtr pmap;
+    int	retval;
+    xAllocColorReply acr;
+    REQUEST(xAllocColorReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorReq);
+    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pmap)
+    {
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+	    return Success;
+#endif
+	acr.type = X_Reply;
+	acr.length = 0;
+	acr.sequenceNumber = client->sequence;
+	acr.red = stuff->red;
+	acr.green = stuff->green;
+	acr.blue = stuff->blue;
+	acr.pixel = 0;
+	if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+	                       &acr.pixel, client->index)) )
+	{
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return (retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+	return (client->noClientException);
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocNamedColor           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					    RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int		retval;
+
+	xAllocNamedColorReply ancr;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocNamedColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	ancr.type = X_Reply;
+	ancr.length = 0;
+	ancr.sequenceNumber = client->sequence;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+	{
+	    ancr.screenRed = ancr.exactRed;
+	    ancr.screenGreen = ancr.exactGreen;
+	    ancr.screenBlue = ancr.exactBlue;
+	    ancr.pixel = 0;
+	    if( (retval = AllocColor(pcmp,
+	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+			 &ancr.pixel, client->index)) )
+	    {
+                if (client->noClientException != Success)
+                    return(client->noClientException);
+                else
+    	            return(retval);
+	    }
+#ifdef PANORAMIX
+	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+	    return (client->noClientException);
+	}
+	else
+	    return(BadName);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorCells           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorCellsReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorCellsReply	accr;
+	int			npixels, nmasks, retval;
+	long			length;
+	Pixel			*ppixels, *pmasks;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorCells request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	nmasks = stuff->planes;
+	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	pmasks = ppixels + npixels;
+
+	if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 
+				    (Bool)stuff->contiguous, ppixels, pmasks)) )
+	{
+	    DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    accr.type = X_Reply;
+	    accr.length = length >> 2;
+	    accr.sequenceNumber = client->sequence;
+	    accr.nPixels = npixels;
+	    accr.nMasks = nmasks;
+	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorPlanes(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorPlanesReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorPlanesReply	acpr;
+	int			npixels, retval;
+	long			length;
+	Pixel			*ppixels;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorPlanes request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	acpr.type = X_Reply;
+	acpr.sequenceNumber = client->sequence;
+	acpr.nPixels = npixels;
+	length = (long)npixels * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+	    (Bool)stuff->contiguous, ppixels,
+	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+	{
+            DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+	acpr.length = length >> 2;
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcFreeColors          (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xFreeColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+	if(pcmp->flags & AllAllocated)
+	    return(BadAccess);
+	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+	retval =  FreeColors(pcmp, client->index, count,
+	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreColors               (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+	if (count % sizeof(xColorItem))
+	    return(BadLength);
+	count /= sizeof(xColorItem);
+	retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreNamedColor           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xColorItem	def;
+        int             retval;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+	                 stuff->nbytes, &def.red, &def.green, &def.blue))
+	{
+	    def.flags = stuff->flags;
+	    def.pixel = stuff->pixel;
+	    retval = StoreColors(pcmp, 1, &def);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+		return(retval);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcQueryColors(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xQueryColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	int			count, retval;
+	xrgb 			*prgbs;
+	xQueryColorsReply	qcr;
+
+	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+	prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+	if(!prgbs && count)
+            return(BadAlloc);
+	if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+	{
+   	    if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	    if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	    {
+		client->errorValue = clientErrorValue;
+	        return (retval);
+	    }
+	}
+	qcr.type = X_Reply;
+	qcr.length = (count * sizeof(xrgb)) >> 2;
+	qcr.sequenceNumber = client->sequence;
+	qcr.nColors = count;
+	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+	if (count)
+	{
+	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+	}
+	if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	return(client->noClientException);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+} 
+
+int
+ProcLookupColor(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xLookupColorReq);
+
+    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	xLookupColorReply lcr;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+	{
+	    lcr.type = X_Reply;
+	    lcr.length = 0;
+	    lcr.sequenceNumber = client->sequence;
+	    lcr.screenRed = lcr.exactRed;
+	    lcr.screenGreen = lcr.exactGreen;
+	    lcr.screenBlue = lcr.exactBlue;
+	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+	                                   &lcr.screenGreen,
+					   &lcr.screenBlue,
+					   pcmp->pVisual);
+	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+	    return(client->noClientException);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcCreateCursor( client)
+    register ClientPtr client;
+{
+    CursorPtr	pCursor;
+
+    register PixmapPtr 	src;
+    register PixmapPtr 	msk;
+    unsigned char *	srcbits;
+    unsigned char *	mskbits;
+    unsigned short	width, height;
+    long		n;
+    CursorMetricRec cm;
+
+
+    REQUEST(xCreateCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+					      RT_PIXMAP, SecurityReadAccess);
+    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+					      RT_PIXMAP, SecurityReadAccess);
+    if (   src == (PixmapPtr)NULL)
+    {
+	client->errorValue = stuff->source;
+	return (BadPixmap);
+    }
+    if ( msk == (PixmapPtr)NULL)
+    {
+	if (stuff->mask != None)
+	{
+	    client->errorValue = stuff->mask;
+	    return (BadPixmap);
+	}
+    }
+    else if (  src->drawable.width != msk->drawable.width
+	    || src->drawable.height != msk->drawable.height
+	    || src->drawable.depth != 1
+	    || msk->drawable.depth != 1)
+	return (BadMatch);
+
+    width = src->drawable.width;
+    height = src->drawable.height;
+
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+
+    n = BitmapBytePad(width)*height;
+    srcbits = (unsigned char *)xalloc(n);
+    if (!srcbits)
+	return (BadAlloc);
+    mskbits = (unsigned char *)xalloc(n);
+    if (!mskbits)
+    {
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+
+    /* zeroing the (pad) bits helps some ddx cursor handling */
+    bzero((char *)srcbits, n);
+    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+					 XYPixmap, 1, (pointer)srcbits);
+    if ( msk == (PixmapPtr)NULL)
+    {
+	register unsigned char *bits = mskbits;
+	while (--n >= 0)
+	    *bits++ = ~0;
+    }
+    else
+    {
+	/* zeroing the (pad) bits helps some ddx cursor handling */
+	bzero((char *)mskbits, n);
+	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+					height, XYPixmap, 1, (pointer)mskbits);
+    }
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursor( srcbits, mskbits, &cm,
+	    stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+	    stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+    {
+        #ifdef TEST
+        fprintf(stderr, "ProcCreateCursor: Created cursor at [%p].\n", (void *) pCursor);
+        #endif
+
+	    return (client->noClientException);
+    }
+
+    return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor( client)
+    register ClientPtr client;
+{
+    CursorPtr pCursor;
+    int res;
+
+    REQUEST(xCreateGlyphCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+			   stuff->mask, stuff->maskChar,
+			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+			   stuff->backRed, stuff->backGreen, stuff->backBlue,
+			   &pCursor, client);
+    if (res != Success)
+	return res;
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+
+int
+ProcFreeCursor(client)
+    register ClientPtr client;
+{
+    CursorPtr pCursor;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_CURSOR, SecurityDestroyAccess);
+    if (pCursor) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadCursor);
+    }
+}
+
+int
+ProcQueryBestSize   (client)
+    register ClientPtr client;
+{
+    xQueryBestSizeReply	reply;
+    register DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    REQUEST(xQueryBestSizeReq);
+
+    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+    if ((stuff->class != CursorShape) && 
+	(stuff->class != TileShape) && 
+	(stuff->class != StippleShape))
+    {
+	client->errorValue = stuff->class;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+	return (BadMatch);
+    pScreen = pDraw->pScreen;
+    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+			       &stuff->height, pScreen);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.width = stuff->width;
+    reply.height = stuff->height;
+    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+    return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver            (client)
+    register ClientPtr client;
+{
+    int blankingOption, exposureOption;
+    REQUEST(xSetScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+    blankingOption = stuff->preferBlank;
+    if ((blankingOption != DontPreferBlanking) &&
+        (blankingOption != PreferBlanking) &&
+        (blankingOption != DefaultBlanking))
+    {
+	client->errorValue = blankingOption;
+        return BadValue;
+    }
+    exposureOption = stuff->allowExpose;
+    if ((exposureOption != DontAllowExposures) &&
+        (exposureOption != AllowExposures) &&
+        (exposureOption != DefaultExposures))
+    {
+	client->errorValue = exposureOption;
+        return BadValue;
+    }
+    if (stuff->timeout < -1)
+    {
+	client->errorValue = stuff->timeout;
+        return BadValue;
+    }
+    if (stuff->interval < -1)
+    {
+	client->errorValue = stuff->interval;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to change our values.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
+                stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
+    #endif
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      if (blankingOption == DefaultBlanking)
+      {
+	ScreenSaverBlanking = defaultScreenSaverBlanking;
+      }
+      else
+      {
+	ScreenSaverBlanking = blankingOption; 
+      }
+
+      if (exposureOption == DefaultExposures)
+      {
+	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+      }
+      else
+      {
+        ScreenSaverAllowExposures = exposureOption;
+      }
+
+      if (stuff->timeout >= 0)
+      {
+        ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverTime = defaultScreenSaverTime;
+      }
+
+      if (stuff->interval >= 0)
+      {
+        ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverInterval = defaultScreenSaverInterval;
+      }
+    }
+ 
+    #ifdef TEST
+
+    else 
+    {
+      fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
+                  nxagentOption(Timeout));
+    }
+
+    #endif
+
+    return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(client)
+    register ClientPtr client;
+{
+    xGetScreenSaverReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+    rep.preferBlanking = ScreenSaverBlanking;
+    rep.allowExposures = ScreenSaverAllowExposures;
+    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+    return (client->noClientException);
+}
+
+int
+ProcChangeHosts(client)
+    register ClientPtr client;
+{
+    REQUEST(xChangeHostsReq);
+    int result;
+
+    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+    if(stuff->mode == HostInsert)
+	result = AddHost(client, (int)stuff->hostFamily,
+			 stuff->hostLength, (pointer)&stuff[1]);
+    else if (stuff->mode == HostDelete)
+	result = RemoveHost(client, (int)stuff->hostFamily, 
+			    stuff->hostLength, (pointer)&stuff[1]);  
+    else
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcListHosts(client)
+    register ClientPtr client;
+{
+    xListHostsReply reply;
+    int	len, nHosts, result;
+    pointer	pdata;
+    /* REQUEST(xListHostsReq); */
+
+    REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+    /* untrusted clients can't list hosts */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	SecurityAudit("client %d attempted to list hosts\n", client->index);
+	return BadAccess;
+    }
+#endif
+    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+    if (result != Success)
+	return(result);
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.nHosts = nHosts;
+    reply.length = len >> 2;
+    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+    if (nHosts)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+	WriteSwappedDataToClient(client, len, pdata);
+    }
+    xfree(pdata);
+    return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(client)
+    register ClientPtr client;
+{
+    int result;
+    REQUEST(xSetAccessControlReq);
+
+    REQUEST_SIZE_MATCH(xSetAccessControlReq);
+    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcKillClient(client)
+    register ClientPtr client;
+{
+    REQUEST(xResourceReq);
+    ClientPtr	killclient;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (stuff->id == AllTemporary)
+    {
+	CloseDownRetainedResources();
+        return (client->noClientException);
+    }
+
+    if ((killclient = LookupClient(stuff->id, client)))
+    {
+	CloseDownClient(killclient);
+	/* if an LBX proxy gets killed, isItTimeToYield will be set */
+	if (isItTimeToYield || (client == killclient))
+	{
+	    /* force yield and return Success, so that Dispatch()
+	     * doesn't try to touch client
+	     */
+	    isItTimeToYield = TRUE;
+	    return (Success);
+	}
+	return (client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+	return (BadValue);
+    }
+}
+
+int
+ProcSetFontPath(client)
+    register ClientPtr client;
+{
+    unsigned char *ptr;
+    unsigned long nbytes, total;
+    long nfonts;
+    int n, result;
+    int error;
+    REQUEST(xSetFontPathReq);
+    
+    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+    
+    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+    total = nbytes;
+    ptr = (unsigned char *)&stuff[1];
+    nfonts = stuff->nFonts;
+    while (--nfonts >= 0)
+    {
+	if ((total == 0) || (total < (n = (*ptr + 1))))
+	    return(BadLength);
+	total -= n;
+	ptr += n;
+    }
+    if (total >= 4)
+	return(BadLength);
+    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+			 &error);
+    if (!result)
+    {
+	result = client->noClientException;
+	client->errorValue = error;
+    }
+    return (result);
+}
+
+int
+ProcGetFontPath(client)
+    register ClientPtr client;
+{
+    xGetFontPathReply reply;
+    int stringLens, numpaths;
+    unsigned char *bufferStart;
+    /* REQUEST (xReq); */
+
+    REQUEST_SIZE_MATCH(xReq);
+    bufferStart = GetFontPath(&numpaths, &stringLens);
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = (stringLens + numpaths + 3) >> 2;
+    reply.nPaths = numpaths;
+
+    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+    if (stringLens || numpaths)
+	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+    return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(client)
+    register ClientPtr client;
+{
+    REQUEST(xSetCloseDownModeReq);
+
+    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+    if ((stuff->mode == AllTemporary) ||
+	(stuff->mode == RetainPermanent) ||
+	(stuff->mode == RetainTemporary))
+    {
+	client->closeDownMode = stuff->mode;
+	return (client->noClientException);
+    }
+    else   
+    {
+	client->errorValue = stuff->mode;
+	return (BadValue);
+    }
+}
+
+int ProcForceScreenSaver(client)
+    register ClientPtr client;
+{    
+    REQUEST(xForceScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+    
+    if ((stuff->mode != ScreenSaverReset) && 
+	(stuff->mode != ScreenSaverActive))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to force the screen
+     * saver handler execution. 
+     */
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+    }
+
+    #ifdef TEST
+
+    else
+    {
+      fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
+                  stuff -> mode);
+    }
+
+    #endif
+
+    return client->noClientException;
+}
+
+int ProcNoOperation(client)
+    register ClientPtr client;
+{
+    REQUEST_AT_LEAST_SIZE(xReq);
+    
+    /* noop -- don't do anything */
+    return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+    int i;
+    for (i = 0; i<256; i++)
+    {
+	if(!ProcVector[i])
+	{
+            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+	    ReplySwapVector[i] = ReplyNotSwappd;
+	}
+#ifdef K5AUTH
+	if (!k5_Vector[i])
+	{
+	    k5_Vector[i] = k5_bad;
+	}
+#endif
+    }
+    for(i = LASTEvent; i < 128; i++)
+    {
+	EventSwapVector[i] = NotImplemented;
+    }
+    
+}
+
+/**********************
+ * CloseDownClient
+ *
+ *  Client can either mark his resources destroy or retain.  If retained and
+ *  then killed again, the client is really destroyed.
+ *********************/
+
+void
+CloseDownClient(client)
+    register ClientPtr client;
+{
+    Bool really_close_down = client->clientGone ||
+			     client->closeDownMode == DestroyAll;
+
+    /*
+     * There must be a better way to hook a
+     * call-back function to be called any
+     * time a client is going to be closed.
+     */
+
+    nxagentClearClipboard(client, NULL);
+
+    /*
+     * Need to reset the karma counter and
+     * get rid of the pending sync replies.
+     */
+
+    nxagentWakeupByReset(client);
+
+    /*
+     * Check if the client
+     * is a shadow nxagent.
+     */
+
+    nxagentCheckIfShadowAgent(client);
+
+    if (!client->clientGone)
+    {
+	/* ungrab server if grabbing client dies */
+	if (grabState != GrabNone && grabClient == client)
+	{
+	    UngrabServer(client);
+	}
+	BITCLEAR(grabWaiters, client->index);
+	DeleteClientFromAnySelections(client);
+	ReleaseActiveGrabs(client);
+	DeleteClientFontStuff(client);
+	if (!really_close_down)
+	{
+	    /*  This frees resources that should never be retained
+	     *  no matter what the close down mode is.  Actually we
+	     *  could do this unconditionally, but it's probably
+	     *  better not to traverse all the client's resources
+	     *  twice (once here, once a few lines down in
+	     *  FreeClientResources) in the common case of
+	     *  really_close_down == TRUE.
+	     */
+	    FreeClientNeverRetainResources(client);
+	    client->clientState = ClientStateRetained;
+  	    if (ClientStateCallback)
+            {
+		NewClientInfoRec clientinfo;
+
+		clientinfo.client = client; 
+		clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+		clientinfo.setup = (xConnSetup *) NULL;
+		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+            } 
+	}
+	client->clientGone = TRUE;  /* so events aren't sent to client */
+	if (ClientIsAsleep(client))
+	    ClientSignal (client);
+	ProcessWorkQueueZombies();
+#ifdef LBX
+	ProcessQTagZombies();
+#endif
+	CloseDownConnection(client);
+
+	/* If the client made it to the Running stage, nClients has
+	 * been incremented on its behalf, so we need to decrement it
+	 * now.  If it hasn't gotten to Running, nClients has *not*
+	 * been incremented, so *don't* decrement it.
+	 */
+	if (client->clientState != ClientStateInitial &&
+	    client->clientState != ClientStateAuthenticating )
+	{
+	    --nClients;
+	}
+    }
+
+    if (really_close_down)
+    {
+	if (client->clientState == ClientStateRunning && nClients == 0)
+	    dispatchException |= dispatchExceptionAtReset;
+
+	client->clientState = ClientStateGone;
+	if (ClientStateCallback)
+	{
+	    NewClientInfoRec clientinfo;
+
+	    clientinfo.client = client; 
+	    clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+	    clientinfo.setup = (xConnSetup *) NULL;
+	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+	} 	    
+	FreeClientResources(client);
+	if (client->index < nextFreeClientID)
+	    nextFreeClientID = client->index;
+	clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+	SmartLastClient = NullClient;
+#endif
+	xfree(client);
+
+	while (!clients[currentMaxClients-1])
+	    currentMaxClients--;
+    }
+}
+
+static void
+KillAllClients()
+{
+    int i;
+    for (i=1; i<currentMaxClients; i++)
+        if (clients[i]) {
+            /* Make sure Retained clients are released. */
+            clients[i]->closeDownMode = DestroyAll;
+            CloseDownClient(clients[i]);     
+        }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ *    Find all clients that are gone and have terminated in RetainTemporary 
+ *    and  destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+    register int i;
+    register ClientPtr client;
+
+    for (i=1; i<currentMaxClients; i++)
+    {
+        client = clients[i];
+        if (client && (client->closeDownMode == RetainTemporary)
+	    && (client->clientGone))
+	    CloseDownClient(client);
+    }
+}
+
+void InitClient(client, i, ospriv)
+    ClientPtr client;
+    int i;
+    pointer ospriv;
+{
+    client->index = i;
+    client->sequence = 0; 
+    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+    client->clientGone = FALSE;
+    if (i)
+    {
+	client->closeDownMode = DestroyAll;
+	client->lastDrawable = (DrawablePtr)WindowTable[0];
+	client->lastDrawableID = WindowTable[0]->drawable.id;
+    }
+    else
+    {
+	client->closeDownMode = RetainPermanent;
+	client->lastDrawable = (DrawablePtr)NULL;
+	client->lastDrawableID = INVALID;
+    }
+    client->lastGC = (GCPtr) NULL;
+    client->lastGCID = INVALID;
+    client->numSaved = 0;
+    client->saveSet = (pointer *)NULL;
+    client->noClientException = Success;
+#ifdef LOG_DEBUG
+    client->requestLogIndex = 0;
+#endif
+    client->requestVector = InitialVector;
+    client->osPrivate = ospriv;
+    client->swapped = FALSE;
+    client->big_requests = FALSE;
+    client->priority = 0;
+    client->clientState = ClientStateInitial;
+#ifdef XKB
+    if (!noXkbExtension) {
+	client->xkbClientFlags = 0;
+	client->mapNotifyMask = 0;
+	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+    }
+#endif
+    client->replyBytesRemaining = 0;
+#ifdef LBX
+    client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+    client->trustLevel = XSecurityClientTrusted;
+    client->CheckAccess = NULL;
+    client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+    client->appgroup = NULL;
+#endif
+    client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+    client->smart_priority = 0;
+    client->smart_start_tick = SmartScheduleTime;
+    client->smart_stop_tick = SmartScheduleTime;
+    client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(client)
+    ClientPtr client;
+{
+    register char *ptr;
+    DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    if (totalClientSize == sizeof(ClientRec))
+	ppriv = (DevUnion *)NULL;
+    else if (client->index)
+	ppriv = (DevUnion *)(client + 1);
+    else
+    {
+	ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+	if (!ppriv)
+	    return 0;
+    }
+    client->devPrivates = ppriv;
+    sizes = clientPrivateSizes;
+    ptr = (char *)(ppriv + clientPrivateLen);
+    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+
+    /*
+     * Initialize the private members.
+     */
+
+    nxagentInitClientPrivates(client);
+
+    return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr
+NextAvailableClient(ospriv)
+    pointer ospriv;
+{
+    register int i;
+    register ClientPtr client;
+    xReq data;
+
+    i = nextFreeClientID;
+    if (i == MAXCLIENTS)
+	return (ClientPtr)NULL;
+    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+    if (!client)
+	return (ClientPtr)NULL;
+    InitClient(client, i, ospriv);
+    InitClientPrivates(client);
+    if (!InitClientResources(client))
+    {
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    data.reqType = 1;
+    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+    {
+	FreeClientResources(client);
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    if (i == currentMaxClients)
+	currentMaxClients++;
+    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+	nextFreeClientID++;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+        clientinfo.setup = (xConnSetup *) NULL;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return(client);
+}
+
+int
+ProcInitialConnection(client)
+    register ClientPtr client;
+{
+    REQUEST(xReq);
+    register xConnClientPrefix *prefix;
+    int whichbyte = 1;
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+	return (client->noClientException = -1);
+    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+    {
+	client->swapped = TRUE;
+	SwapConnClientPrefix(prefix);
+    }
+    stuff->reqType = 2;
+    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+    if (client->swapped)
+    {
+	swaps(&stuff->length, whichbyte);
+    }
+    ResetCurrentRequest(client);
+    return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+    nClients++;
+}
+#endif
+
+int
+SendConnSetup(client, reason)
+    register ClientPtr client;
+    char *reason;
+{
+    register xWindowRoot *root;
+    register int i;
+    int numScreens;
+    char* lConnectionInfo;
+    xConnSetupPrefix* lconnSetupPrefix;
+
+    if (reason)
+    {
+	xConnSetupPrefix csp;
+
+	csp.success = xFalse;
+	csp.lengthReason = strlen(reason);
+	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+	csp.majorVersion = X_PROTOCOL;
+	csp.minorVersion = X_PROTOCOL_REVISION;
+	if (client->swapped)
+	    WriteSConnSetupPrefix(client, &csp);
+	else
+	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+        (void)WriteToClient(client, (int)csp.lengthReason, reason);
+	return (client->noClientException = -1);
+    }
+
+    numScreens = screenInfo.numScreens;
+    lConnectionInfo = ConnectionInfo;
+    lconnSetupPrefix = &connSetupPrefix;
+
+    /* We're about to start speaking X protocol back to the client by
+     * sending the connection setup info.  This means the authorization
+     * step is complete, and we can count the client as an
+     * authorized one.
+     */
+    nClients++;
+
+    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+    client->sequence = 0;
+#ifdef XAPPGROUP
+    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+    /* fill in the "currentInputMask" */
+    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+    for (i=0; i<numScreens; i++) 
+    {
+	register unsigned int j;
+	register xDepth *pDepth;
+
+        root->currentInputMask = WindowTable[i]->eventMask |
+			         wOtherEventMasks (WindowTable[i]);
+	pDepth = (xDepth *)(root + 1);
+	for (j = 0; j < root->nDepths; j++)
+	{
+	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+				pDepth->nVisuals * sizeof(xVisualType));
+	}
+	root = (xWindowRoot *)pDepth;
+    }
+
+    if (client->swapped)
+    {
+	WriteSConnSetupPrefix(client, lconnSetupPrefix);
+	WriteSConnectionInfo(client,
+			     (unsigned long)(lconnSetupPrefix->length << 2),
+			     lConnectionInfo);
+    }
+    else
+    {
+	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
+			    (char *) lconnSetupPrefix);
+	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+			    lConnectionInfo);
+    }
+    client->clientState = ClientStateRunning;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = lconnSetupPrefix;  
+        clientinfo.setup = (xConnSetup *)lConnectionInfo;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(client)
+    register ClientPtr client;
+{
+    char *reason, *auth_proto, *auth_string;
+    register xConnClientPrefix *prefix;
+    REQUEST(xReq);
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    auth_proto = (char *)prefix + sz_xConnClientPrefix;
+    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+    if ((prefix->majorVersion != X_PROTOCOL) ||
+	(prefix->minorVersion != X_PROTOCOL_REVISION))
+	reason = "Protocol version mismatch";
+    else
+	reason = ClientAuthorized(client,
+				  (unsigned short)prefix->nbytesAuthProto,
+				  auth_proto,
+				  (unsigned short)prefix->nbytesAuthString,
+				  auth_string);
+    /*
+     * If Kerberos is being used for this client, the clientState
+     * will be set to ClientStateAuthenticating at this point.
+     * More messages need to be exchanged among the X server, Kerberos
+     * server, and client to figure out if everyone is authorized.
+     * So we don't want to send the connection setup info yet, since
+     * the auth step isn't really done.
+     */
+    if (client->clientState == ClientStateCheckingSecurity)
+	client->clientState = ClientStateCheckedSecurity;
+    else if (client->clientState != ClientStateAuthenticating)
+	return(SendConnSetup(client, reason));
+    return(client->noClientException);
+}
+
+void
+SendErrorToClient(client, majorCode, minorCode, resId, errorCode)
+    ClientPtr client;
+    unsigned int majorCode;
+    unsigned int minorCode;
+    XID resId;
+    int errorCode;
+{
+    xError rep;
+
+    rep.type = X_Error;
+    rep.sequenceNumber = client->sequence;
+    rep.errorCode = errorCode;
+    rep.majorCode = majorCode;
+    rep.minorCode = minorCode;
+    rep.resourceID = resId;
+
+    WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(pWin)
+    WindowPtr pWin;
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].pWin == pWin)
+        {
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+static void
+DeleteClientFromAnySelections(client)
+    ClientPtr client;
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].client == client)
+        {
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+void
+MarkClientException(client)
+    ClientPtr client;
+{
+    client->noClientException = -1;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
new file mode 100644
index 000000000..90da743a2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
@@ -0,0 +1,4716 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXdispatch.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/****************************************************************
+*                                                               *
+*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.29 2003/01/12 02:44:26 dawes Exp $ */
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#ifdef __sun
+#define False 0
+#define True 1
+#endif
+
+#define GC XlibGC
+#include <X11/Xlib.h>
+#undef GC
+
+#include "windowstr.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef XAPPGROUP
+#include "Xagsrv.h"
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include "XKBsrv.h"
+#endif
+
+#include "Atoms.h"
+#include "Splash.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Reconnect.h"
+#include "Millis.h"
+#include "Font.h"
+#include "Shadow.h"
+#include "Handlers.h"
+
+const int nxagentMaxFontNames = 10000;
+
+char dispatchExceptionAtReset = DE_RESET;
+
+/*
+ * This allows the agent to exit if no
+ * client is connected within a timeout.
+*/
+
+int nxagentClients = 0;
+
+void nxagentWaitDisplay(void);
+
+void nxagentListRemoteFonts(const char *, int);
+
+unsigned int nxagentWMtimeout = 0;
+Bool         nxagentWMPassed  = 0;
+
+/*
+ * Timeouts based on screen saver time.
+ */
+
+int nxagentAutoDisconnectTimeout = 0;
+
+#ifdef LBX
+#include "../../lbx/lbxserve.h"
+#endif
+
+#include "Xatom.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  WATCH
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef  BLOCKS
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+                                   (pWin) == nxagentViewportFrameRight || \
+                                       (pWin) == nxagentViewportFrameAbove || \
+                                           (pWin) == nxagentViewportFrameBelow)
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(
+#if NeedFunctionPrototypes
+    void
+#endif
+);
+
+static void DeleteClientFromAnySelections(
+#if NeedFunctionPrototypes
+    ClientPtr /*client*/
+#endif
+);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int	nClients;	/* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+char dispatchException = 0;
+char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue;   /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+    (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(c0, c1)
+    HWEventQueuePtr c0, c1;
+{
+    checkForInput[0] = c0;
+    checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+    TimeStamp systime;
+
+    /* To avoid time running backwards, we must call GetTimeInMillis before
+     * calling ProcessInputEvents.
+     */
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] != *checkForInput[1])
+	ProcessInputEvents();
+    if (CompareTimeStamps(systime, currentTime) == LATER)
+	currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+    TimeStamp systime;
+
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] == *checkForInput[1])
+	currentTime = systime;
+}
+
+void
+InitSelections()
+{
+    if (CurrentSelections)
+	xfree(CurrentSelections);
+    CurrentSelections = (Selection *)NULL;
+    NumCurrentSelections = 0;
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+      Selection *newsels;
+      newsels = (Selection *)xalloc(2 * sizeof(Selection));
+      if (!newsels)
+        return;
+      NumCurrentSelections += 2;
+      CurrentSelections = newsels;
+
+      CurrentSelections[0].selection = XA_PRIMARY;
+      CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[0].window = WindowTable[0]->drawable.id;
+      CurrentSelections[0].pWin = NULL;
+      CurrentSelections[0].client = NullClient;
+
+      CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
+      CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[1].window = WindowTable[0]->drawable.id;
+      CurrentSelections[1].pWin = NULL;
+      CurrentSelections[1].client = NullClient;
+    }
+#endif
+
+}
+
+void 
+FlushClientCaches(id)
+    XID id;
+{
+    int i;
+    register ClientPtr client;
+
+    client = clients[CLIENT_ID(id)];
+    if (client == NullClient)
+        return ;
+    for (i=0; i<currentMaxClients; i++)
+    {
+	client = clients[i];
+        if (client != NullClient)
+	{
+            if (client->lastDrawableID == id)
+	    {
+		client->lastDrawableID = WindowTable[0]->drawable.id;
+		client->lastDrawable = (DrawablePtr)WindowTable[0];
+	    }
+            else if (client->lastGCID == id)
+	    {
+                client->lastGCID = INVALID;
+		client->lastGC = (GCPtr)NULL;
+	    }
+	}
+    }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
+#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
+
+/*
+ * Disable the SmartScheduler as it doesn't
+ * seem to work for us.
+ */
+
+Bool	    SmartScheduleDisable = True;
+
+long	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long	    SmartScheduleTime;
+ClientPtr   SmartLastClient;
+int	    SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int         SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long	    SmartLastPrint;
+#endif
+
+void        Dispatch(void);
+void        InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+    ClientPtr	pClient;
+    int		i;
+    int		client;
+    int		bestPrio, best = 0;
+    int		bestRobin, robin;
+    long	now = SmartScheduleTime;
+    long	idle;
+
+    bestPrio = -0x7fffffff;
+    bestRobin = 0;
+    idle = 2 * SmartScheduleSlice;
+    for (i = 0; i < nready; i++)
+    {
+	client = clientReady[i];
+	pClient = clients[client];
+	/* Praise clients which are idle */
+	if ((now - pClient->smart_check_tick) >= idle)
+	{
+	    if (pClient->smart_priority < 0)
+		pClient->smart_priority++;
+	}
+	pClient->smart_check_tick = now;
+	
+	/* check priority to select best client */
+	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+	if (pClient->smart_priority > bestPrio ||
+	    (pClient->smart_priority == bestPrio && robin > bestRobin))
+	{
+	    bestPrio = pClient->smart_priority;
+	    bestRobin = robin;
+	    best = client;
+	}
+#ifdef SMART_DEBUG
+	if ((now - SmartLastPrint) >= 5000)
+	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+    }
+#ifdef SMART_DEBUG
+    if ((now - SmartLastPrint) >= 5000)
+    {
+	fprintf (stderr, " use %2d\n", best);
+	SmartLastPrint = now;
+    }
+#endif
+    pClient = clients[best];
+    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+    /*
+     * Set current client pointer
+     */
+    if (SmartLastClient != pClient)
+    {
+	pClient->smart_start_tick = now;
+	SmartLastClient = pClient;
+    }
+    /*
+     * Adjust slice
+     */
+    if (nready == 1)
+    {
+	/*
+	 * If it's been a long time since another client
+	 * has run, bump the slice up to get maximal
+	 * performance from a single client
+	 */
+	if ((now - pClient->smart_start_tick) > 1000 &&
+	    SmartScheduleSlice < SmartScheduleMaxSlice)
+	{
+	    SmartScheduleSlice += SmartScheduleInterval;
+	}
+    }
+    else
+    {
+	SmartScheduleSlice = SmartScheduleInterval;
+    }
+    return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+    register int        *clientReady;     /* array of request ready clients */
+    register int	result;
+    register ClientPtr	client;
+    register int	nready;
+    register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+    int			start_tick;
+#endif
+
+    unsigned long currentDispatch = 0;
+
+    nextFreeClientID = 1;
+    InitSelections();
+    nClients = 0;
+
+    /*
+     * The agent initialization was successfully
+     * completed. We can now handle our clients.
+     */
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+
+      nxagentSessionState = SESSION_UP;
+    }
+
+#ifdef NXAGENT_ONSTART
+
+    /*
+     * Set NX_WM property (used by NX client to identify
+     * the agent's window) three seconds since the first
+     * client connects.
+     */
+
+    nxagentWMtimeout = GetTimeInMillis() + 3000;
+
+#endif
+
+    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+    if (!clientReady)
+	return;
+
+  #ifdef WATCH
+
+  fprintf(stderr, "Dispatch: Watchpoint 12.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#3      1		352 bits (0 KB) ->	236 bits (0 KB) ->	352/1 -> 236/1	= 1.492:1
+#14     1		256 bits (0 KB) ->	101 bits (0 KB) ->	256/1 -> 101/1	= 2.535:1
+#16     1		256 bits (0 KB) ->	26 bits (0 KB) ->	256/1 -> 26/1	= 9.846:1
+#20     2	2	12256 bits (1 KB) ->	56 bits (0 KB) ->	6128/1 -> 28/1	= 218.857:1
+#43     1		256 bits (0 KB) ->	45 bits (0 KB) ->	256/1 -> 45/1	= 5.689:1
+#47     2	2	42304 bits (5 KB) ->	49 bits (0 KB) ->	21152/1 -> 24/1	= 863.347:1
+#98     1		256 bits (0 KB) ->	34 bits (0 KB) ->	256/1 -> 34/1	= 7.529:1
+*/
+
+  sleep(30);
+
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
+              dispatchException);
+
+  fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
+              dispatchExceptionAtReset);
+  #endif
+
+  if (!(dispatchException & DE_TERMINATE))
+    dispatchException = 0;
+
+    while (!dispatchException)
+    {
+        if (*icheck[0] != *icheck[1])
+	{
+	    ProcessInputEvents();
+	    FlushIfCriticalOutputPending();
+	}
+
+        /*
+         * Ensure we remove the splash after the timeout.
+         * Initializing clientReady[0] to -1 will tell
+         * WaitForSomething() to yield control after the
+         * timeout set in clientReady[1].
+         */
+
+        clientReady[0] = 0;
+
+        if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
+        {
+          #ifdef TEST
+          fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
+                      NXAGENT_WAKEUP);
+          #endif
+
+          clientReady[0] = -1;
+          clientReady[1] = NXAGENT_WAKEUP;
+        }
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[End dispatch]\n");
+        #endif
+
+	nready = WaitForSomething(clientReady);
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[Begin dispatch]\n");
+        #endif
+
+        #ifdef TEST
+        fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
+                    nready);
+        #endif
+        
+        #ifdef NXAGENT_ONSTART
+
+        currentDispatch = GetTimeInMillis();
+
+        /*
+         * If the timeout is expired set the
+         * selection informing the NX client
+         * that the agent is ready.
+         */
+
+         if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
+         {
+           nxagentRemoveSplashWindow(NULL);
+         }
+
+         nxagentClients = nClients;
+
+         #endif
+
+#ifdef SMART_SCHEDULE
+	if (nready && !SmartScheduleDisable)
+	{
+	    clientReady[0] = SmartScheduleClient (clientReady, nready);
+	    nready = 1;
+	}
+#endif
+       /***************** 
+	*  Handle events in round robin fashion, doing input between 
+	*  each round 
+	*****************/
+
+	while (!dispatchException && (--nready >= 0))
+	{
+	    client = clients[clientReady[nready]];
+	    if (! client)
+	    {
+		/* KillClient can cause this to happen */
+		continue;
+	    }
+	    /* GrabServer activation can cause this to be true */
+	    if (grabState == GrabKickout)
+	    {
+		grabState = GrabActive;
+		break;
+	    }
+	    isItTimeToYield = FALSE;
+ 
+            requestingClient = client;
+#ifdef SMART_SCHEDULE
+	    start_tick = SmartScheduleTime;
+#endif
+	    while (!isItTimeToYield)
+	    {
+	        if (*icheck[0] != *icheck[1])
+		{
+		    ProcessInputEvents();
+		    FlushIfCriticalOutputPending();
+		}
+#ifdef SMART_SCHEDULE
+		if (!SmartScheduleDisable && 
+		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+		{
+		    /* Penalize clients which consume ticks */
+		    if (client->smart_priority > SMART_MIN_PRIORITY)
+			client->smart_priority--;
+		    break;
+		}
+#endif
+		/* now, finally, deal with client requests */
+
+                #ifdef TEST
+                fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
+                            client->index);
+                #endif
+
+	        result = ReadRequestFromClient(client);
+	        if (result <= 0) 
+	        {
+		    if (result < 0)
+			CloseDownClient(client);
+		    break;
+	        }
+#ifdef NXAGENT_SERVER
+
+                #ifdef TEST
+
+                else
+                {
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
+                                      client->req_len << 2, client->index);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
+                                  nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
+                                      client->index);
+                    }
+                }
+
+                #endif
+#endif
+
+		client->sequence++;
+#ifdef DEBUG
+		if (client->requestLogIndex == MAX_REQUEST_LOG)
+		    client->requestLogIndex = 0;
+		client->requestLog[client->requestLogIndex] = MAJOROP;
+		client->requestLogIndex++;
+#endif
+		if (result > (MAX_BIG_REQUEST_SIZE << 2))
+		    result = BadLength;
+		else
+#ifdef NXAGENT_SERVER
+                {
+                    result = (* client->requestVector[MAJOROP])(client);
+
+                    #ifdef TEST
+
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d] result [%d].\n", MAJOROP,
+                                      *((char *) client->requestBuffer + 1), client->req_len << 2,
+                                          client->index, result);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
+                                  "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
+                                      client->req_len << 2, client->index, result);
+                    }
+
+                    #endif
+
+                    /*
+                     * Can set isItTimeToYield to force
+                     * the dispatcher to pay attention
+                     * to another client.
+                     */
+
+                    nxagentDispatchHandler(client, client->req_len << 2, 0);
+                }
+#else
+		    result = (* client->requestVector[MAJOROP])(client);
+#endif
+
+		if (result != Success) 
+		{
+		    if (client->noClientException != Success)
+                        CloseDownClient(client);
+                    else
+		        SendErrorToClient(client, MAJOROP,
+					  MinorOpcodeOfRequest(client),
+					  client->errorValue, result);
+		    break;
+	        }
+	    }
+	    FlushAllOutput();
+#ifdef SMART_SCHEDULE
+	    client = clients[clientReady[nready]];
+	    if (client)
+		client->smart_stop_tick = SmartScheduleTime;
+#endif
+	    requestingClient = NULL;
+	}
+	dispatchException &= ~DE_PRIORITYCHANGE;
+    }
+
+    if ((dispatchException & DE_RESET) && 
+            (serverGeneration > nxagentMaxAllowedResets))
+    {
+        dispatchException &= ~DE_RESET;
+        dispatchException |= DE_TERMINATE;
+
+        fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+    }
+
+    nxagentResetAtomMap();
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      /*
+       * The session is terminating. Force an I/O
+       * error on the display and wait until the
+       * NX transport is gone.
+       */
+
+      fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
+
+      nxagentWaitDisplay();
+
+      fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
+    }
+
+    if (nxagentOption(Shadow))
+    {
+      NXShadowDestroy();
+    }
+
+    KillAllClients();
+    DEALLOCATE_LOCAL(clientReady);
+    dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+/*ARGSUSED*/
+int
+ProcBadRequest(client)
+    ClientPtr client;
+{
+    return (BadRequest);
+}
+
+int
+ProcCreateWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pParent, pWin;
+    REQUEST(xCreateWindowReq);
+    int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+    
+    LEGAL_NEW_RESOURCE(stuff->wid, client);
+    if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+						    SecurityWriteAccess)))
+        return BadWindow;
+    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+    if (Ones(stuff->mask) != len)
+        return BadLength;
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+			      stuff->y, stuff->width, stuff->height, 
+			      stuff->borderWidth, stuff->class,
+			      stuff->mask, (XID *) &stuff[1], 
+			      (int)stuff->depth, 
+			      client, stuff->visual, &result);
+    if (pWin)
+    {
+	Mask mask = pWin->eventMask;
+
+	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+	    return BadAlloc;
+	pWin->eventMask = mask;
+    }
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcChangeWindowAttributes(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeWindowAttributesReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+    if (len != Ones(stuff->valueMask))
+        return BadLength;
+    result =  ChangeWindowAttributes(pWin, 
+				  stuff->valueMask, 
+				  (XID *) &stuff[1], 
+				  client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcGetWindowAttributes(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+    xGetWindowAttributesReply wa;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    GetWindowAttributes(pWin, client, &wa);
+    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+    return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->parent)
+	FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    DestroySubwindows(pWin, client);
+    return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeSaveSetReq);
+    register int result;
+		  
+    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+        return BadMatch;
+    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+    {
+        result = AlterSaveSetForClient(client, pWin, stuff->mode);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->mode;
+	return( BadValue );
+    }
+}
+
+int
+ProcReparentWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin, pParent;
+    REQUEST(xReparentWindowReq);
+    register int result;
+
+    REQUEST_SIZE_MATCH(xReparentWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    if (!nxagentWMPassed)
+    {
+      nxagentRemoveSplashWindow(pWin);
+    }
+
+    pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+					      SecurityWriteAccess);
+    if (!pParent)
+        return(BadWindow);
+    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+    {
+        if ((pWin->backgroundState == ParentRelative) &&
+            (pParent->drawable.depth != pWin->drawable.depth))
+            return BadMatch;
+	if ((pWin->drawable.class != InputOnly) &&
+	    (pParent->drawable.class == InputOnly))
+	    return BadMatch;
+        result =  ReparentWindow(pWin, pParent, 
+			 (short)stuff->x, (short)stuff->y, client);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else 
+        return (BadMatch);
+}
+
+int
+ProcMapWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapWindow(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapSubwindows(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapWindow(pWin, FALSE);
+           /* update cache to say it is mapped */
+
+    return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapSubwindows(pWin);
+    return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xConfigureWindowReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+    if (Ones((Mask)stuff->mask) != len)
+        return BadLength;
+    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
+			      client);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcCirculateWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xCirculateWindowReq);
+
+    REQUEST_SIZE_MATCH(xCirculateWindowReq);
+    if ((stuff->direction != RaiseLowest) &&
+	(stuff->direction != LowerHighest))
+    {
+	client->errorValue = stuff->direction;
+        return BadValue;
+    }
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    CirculateWindow(pWin, (int)stuff->direction, client);
+    return(client->noClientException);
+}
+
+int
+GetGeometry(client, rep)
+    register ClientPtr client;
+    xGetGeometryReply *rep;
+{
+    register DrawablePtr pDraw;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+    rep->type = X_Reply;
+    rep->length = 0;
+    rep->sequenceNumber = client->sequence;
+    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+    rep->depth = pDraw->depth;
+    rep->width = pDraw->width;
+    rep->height = pDraw->height;
+
+    /* XXX - Because the pixmap-implementation of the multibuffer extension 
+     *       may have the buffer-id's drawable resource value be a pointer
+     *       to the buffer's window instead of the buffer itself
+     *       (this happens if the buffer is the displayed buffer),
+     *       we also have to check that the id matches before we can
+     *       truly say that it is a DRAWABLE_WINDOW.
+     */
+
+    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+    {
+        register WindowPtr pWin = (WindowPtr)pDraw;
+	rep->x = pWin->origin.x - wBorderWidth (pWin);
+	rep->y = pWin->origin.y - wBorderWidth (pWin);
+	rep->borderWidth = pWin->borderWidth;
+    }
+    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+    {
+	rep->x = rep->y = rep->borderWidth = 0;
+    }
+
+    return Success;
+}
+
+
+int
+ProcGetGeometry(client)
+    register ClientPtr client;
+{
+    xGetGeometryReply rep;
+    int status;
+
+    if ((status = GetGeometry(client, &rep)) != Success)
+	return status;
+
+    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+    return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(client)
+    register ClientPtr client;
+{
+    xQueryTreeReply reply;
+    int numChildren = 0;
+    register WindowPtr pChild, pWin, pHead;
+    Window  *childIDs = (Window *)NULL;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    reply.type = X_Reply;
+    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+    reply.sequenceNumber = client->sequence;
+    if (pWin->parent)
+	reply.parent = pWin->parent->drawable.id;
+    else
+        reply.parent = (Window)None;
+    pHead = RealChildHead(pWin);
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+      if (!IsViewportFrame(pChild))
+      {
+	numChildren++;
+      }
+    }
+    if (numChildren)
+    {
+	int curChild = 0;
+
+	childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+	if (!childIDs)
+	    return BadAlloc;
+	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+        {
+          if (!IsViewportFrame(pChild))
+          {
+	    childIDs[curChild++] = pChild->drawable.id;
+          }
+        }
+    }
+    
+    reply.nChildren = numChildren;
+    reply.length = (numChildren * sizeof(Window)) >> 2;
+    
+    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+    if (numChildren)
+    {
+    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+	DEALLOCATE_LOCAL(childIDs);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcInternAtom(client)
+    register ClientPtr client;
+{
+    Atom atom;
+    char *tchar;
+    REQUEST(xInternAtomReq);
+
+    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+    {
+	client->errorValue = stuff->onlyIfExists;
+        return(BadValue);
+    }
+    tchar = (char *) &stuff[1];
+    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+    if (atom != BAD_RESOURCE)
+    {
+	xInternAtomReply reply;
+	reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+	reply.atom = atom;
+	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+	return(client->noClientException);
+    }
+    else
+	return (BadAlloc);
+}
+
+int
+ProcGetAtomName(client)
+    register ClientPtr client;
+{
+    char *str;
+    xGetAtomNameReply reply;
+    int len;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if ( (str = NameForAtom(stuff->id)) )
+    {
+	len = strlen(str);
+	reply.type = X_Reply;
+	reply.length = (len + 3) >> 2;
+	reply.sequenceNumber = client->sequence;
+	reply.nameLength = len;
+	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+	(void)WriteToClient(client, len, str);
+	return(client->noClientException);
+    }
+    else 
+    { 
+	client->errorValue = stuff->id;
+	return (BadAtom);
+    }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(client)
+    register ClientPtr client;
+{
+    WindowPtr pWin;
+    TimeStamp time;
+    REQUEST(xSetSelectionOwnerReq);
+
+    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+    UpdateCurrentTime();
+    time = ClientTimeToServerTime(stuff->time);
+
+    /* If the client's time stamp is in the future relative to the server's
+	time stamp, do not set the selection, just return success. */
+    if (CompareTimeStamps(time, currentTime) == LATER)
+    	return Success;
+    if (stuff->window != None)
+    {
+        pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					       SecurityReadAccess);
+        if (!pWin)
+            return(BadWindow);
+    }
+    else
+        pWin = (WindowPtr)None;
+    if (ValidAtom(stuff->selection))
+    {
+	int i = 0;
+
+	/*
+	 * First, see if the selection is already set... 
+	 */
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) 
+            i++;
+        if (i < NumCurrentSelections)
+        {        
+	    xEvent event;
+
+	    /* If the timestamp in client's request is in the past relative
+		to the time stamp indicating the last time the owner of the
+		selection was set, do not set the selection, just return 
+		success. */
+            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+		== EARLIER)
+		return Success;
+	    if (CurrentSelections[i].client &&
+		(!pWin || (CurrentSelections[i].client != client)))
+	    {
+		event.u.u.type = SelectionClear;
+		event.u.selectionClear.time = time.milliseconds;
+		event.u.selectionClear.window = CurrentSelections[i].window;
+		event.u.selectionClear.atom = CurrentSelections[i].selection;
+		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+				NoEventMask, NoEventMask /* CantBeFiltered */,
+				NullGrab);
+	    }
+	}
+	else
+	{
+	    /*
+	     * It doesn't exist, so add it...
+	     */
+	    Selection *newsels;
+
+	    if (i == 0)
+		newsels = (Selection *)xalloc(sizeof(Selection));
+	    else
+		newsels = (Selection *)xrealloc(CurrentSelections,
+			    (NumCurrentSelections + 1) * sizeof(Selection));
+	    if (!newsels)
+		return BadAlloc;
+	    NumCurrentSelections++;
+	    CurrentSelections = newsels;
+	    CurrentSelections[i].selection = stuff->selection;
+	}
+        CurrentSelections[i].lastTimeChanged = time;
+	CurrentSelections[i].window = stuff->window;
+	CurrentSelections[i].pWin = pWin;
+	CurrentSelections[i].client = (pWin ? client : NullClient);
+
+#ifdef NXAGENT_CLIPBOARD
+      if ((CurrentSelections[i].pWin != NULL) &&
+              (nxagentOption(Clipboard) != ClipboardNone) &&
+                  ((CurrentSelections[i].selection == XA_PRIMARY) ||
+                       (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
+      {
+        nxagentSetSelectionOwner(&CurrentSelections[i]);
+      }
+#endif
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->selection;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGetSelectionOwner(client)
+    register ClientPtr client;
+{
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (ValidAtom(stuff->id))
+    {
+	int i;
+        xGetSelectionOwnerReply reply;
+
+	i = 0;
+        while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->id) i++;
+        reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+        if (i < NumCurrentSelections)
+            reply.owner = CurrentSelections[i].window;
+        else
+            reply.owner = None;
+        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+        return(client->noClientException);
+    }
+    else            
+    {
+	client->errorValue = stuff->id;
+        return (BadAtom); 
+    }
+}
+
+int
+ProcConvertSelection(client)
+    register ClientPtr client;
+{
+    Bool paramsOkay;
+    xEvent event;
+    WindowPtr pWin;
+    REQUEST(xConvertSelectionReq);
+
+    REQUEST_SIZE_MATCH(xConvertSelectionReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+#ifdef NXAGENT_CLIPBOARD
+    if (((stuff->selection == XA_PRIMARY) ||
+           (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
+               nxagentOption(Clipboard) != ClipboardNone)
+    {
+      int i = 0;
+
+      while ((i < NumCurrentSelections) &&
+                CurrentSelections[i].selection != stuff->selection) i++;
+
+      if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
+      {
+        if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
+                                       stuff->property, stuff->target, stuff->time))
+        {
+          return (client->noClientException);
+        }
+      }
+    }
+#endif
+
+    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+    if (stuff->property != None)
+	paramsOkay &= ValidAtom(stuff->property);
+    if (paramsOkay)
+    {
+	int i;
+
+	i = 0;
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) i++;
+	if ((i < NumCurrentSelections) && 
+	    (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+#ifdef XCSECURITY
+	    && (!client->CheckAccess ||
+		(* client->CheckAccess)(client, CurrentSelections[i].window,
+					RT_WINDOW, SecurityReadAccess,
+					CurrentSelections[i].pWin))
+#endif
+	    )
+	{        
+	    event.u.u.type = SelectionRequest;
+	    event.u.selectionRequest.time = stuff->time;
+	    event.u.selectionRequest.owner = 
+			CurrentSelections[i].window;
+	    event.u.selectionRequest.requestor = stuff->requestor;
+	    event.u.selectionRequest.selection = stuff->selection;
+	    event.u.selectionRequest.target = stuff->target;
+	    event.u.selectionRequest.property = stuff->property;
+	    if (TryClientEvents(
+		CurrentSelections[i].client, &event, 1, NoEventMask,
+		NoEventMask /* CantBeFiltered */, NullGrab))
+		return (client->noClientException);
+	}
+	event.u.u.type = SelectionNotify;
+	event.u.selectionNotify.time = stuff->time;
+	event.u.selectionNotify.requestor = stuff->requestor;
+	event.u.selectionNotify.selection = stuff->selection;
+	event.u.selectionNotify.target = stuff->target;
+	event.u.selectionNotify.property = None;
+	(void) TryClientEvents(client, &event, 1, NoEventMask,
+			       NoEventMask /* CantBeFiltered */, NullGrab);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->property;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGrabServer(client)
+    register ClientPtr client;
+{
+    REQUEST_SIZE_MATCH(xReq);
+    if (grabState != GrabNone && client != grabClient)
+    {
+	ResetCurrentRequest(client);
+	client->sequence--;
+	BITSET(grabWaiters, client->index);
+	IgnoreClient(client);
+	return(client->noClientException);
+    }
+    OnlyListenToOneClient(client);
+    grabState = GrabKickout;
+    grabClient = client;
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_GRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+
+    return(client->noClientException);
+}
+
+static void
+#if NeedFunctionPrototypes
+UngrabServer(ClientPtr client)
+#else
+UngrabServer(client)
+    ClientPtr client;
+#endif
+{
+    int i;
+
+    grabState = GrabNone;
+    ListenToAllClients();
+    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+	;
+    if (i >= 0)
+    {
+	i <<= 5;
+	while (!GETBIT(grabWaiters, i))
+	    i++;
+	BITCLEAR(grabWaiters, i);
+	AttendClient(clients[i]);
+    }
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_UNGRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+}
+
+int
+ProcUngrabServer(client)
+    register ClientPtr client;
+{
+    REQUEST_SIZE_MATCH(xReq);
+    UngrabServer(client);
+    return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(client)
+    register ClientPtr client;
+{
+    REQUEST(xTranslateCoordsReq);
+
+    register WindowPtr pWin, pDst;
+    xTranslateCoordsReply rep;
+
+    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+					   SecurityReadAccess);
+    if (!pDst)
+        return(BadWindow);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+    {
+	rep.sameScreen = xFalse;
+        rep.child = None;
+	rep.dstX = rep.dstY = 0;
+    }
+    else
+    {
+	INT16 x, y;
+	rep.sameScreen = xTrue;
+	rep.child = None;
+	/* computing absolute coordinates -- adjust to destination later */
+	x = pWin->drawable.x + stuff->srcX;
+	y = pWin->drawable.y + stuff->srcY;
+	pWin = pDst->firstChild;
+	while (pWin)
+	{
+#ifdef SHAPE
+	    BoxRec  box;
+#endif
+	    if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		 wBorderWidth (pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		 wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen, 
+					&pWin->borderSize, x, y, &box))
+#endif
+		)
+            {
+		rep.child = pWin->drawable.id;
+		pWin = (WindowPtr) NULL;
+	    }
+	    else
+		pWin = pWin->nextSib;
+	}
+	/* adjust to destination coordinates */
+	rep.dstX = x - pDst->drawable.x;
+	rep.dstY = y - pDst->drawable.y;
+    }
+    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+    return(client->noClientException);
+}
+
+int
+ProcOpenFont(client)
+    register ClientPtr client;
+{
+    int	err;
+    char fontReq[256];
+    REQUEST(xOpenFontReq);
+
+    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+    client->errorValue = stuff->fid;
+    LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+    memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    fontReq[stuff->nbytes]=0;
+    if (strchr(fontReq,'*') || strchr(fontReq,'?'))
+    {
+       extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
+#ifdef NXAGENT_FONTMATCH_DEBUG
+       fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
+#endif
+       nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
+       err = nxOpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    }
+    else
+    err = OpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcCloseFont(client)
+    register ClientPtr client;
+{
+    FontPtr pFont;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityDestroyAccess);
+    if (pFont != (FontPtr)NULL)
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client closes a font the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this font looping through the
+         * resources.
+         */
+
+        if (pFont -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
+                        (void *) pFont);
+            #endif
+
+            nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
+                        "resource switching skipped.\n", (void *) pFont);
+          }
+          #endif
+        }
+
+        #endif
+
+        FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+        return (BadFont);
+    }
+}
+
+int
+ProcQueryFont(client)
+    register ClientPtr client;
+{
+    xQueryFontReply	*reply;
+    FontPtr pFont;
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    client->errorValue = stuff->id;		/* EITHER font or gc */
+
+    pFont = NULL;
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+	  /* can't use VERIFY_GC because it might return BadGC */
+	pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+					    SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->id;
+            return(BadFont);     /* procotol spec says only error is BadFont */
+	}
+	pFont = pGC->font;
+    }
+
+/* test
+{
+  Atom name_atom, value_atom;
+  int nprops;
+  FontPropPtr props;
+  int i;
+  char *name;
+
+  name_atom = MakeAtom("FONT", 4, True);
+  value_atom = 0L;
+
+  nprops = pFont->info.nprops;
+  props = pFont->info.props;
+
+  for (i = 0; i < nprops; i++)
+    if (props[i].name == name_atom) {
+      value_atom = props[i].value;
+      break;
+    }
+
+  if (!value_atom) return (BadFont);
+
+  name = (char *)NameForAtom(value_atom);
+  fprintf(stderr, "QueryFont: font name [%s]\n",name);
+}
+ end test */
+
+    {
+	xCharInfo	*pmax = FONTINKMAX(pFont);
+	xCharInfo	*pmin = FONTINKMIN(pFont);
+	int		nprotoxcistructs;
+	int		rlength;
+
+	nprotoxcistructs = (
+	   pmax->rightSideBearing == pmin->rightSideBearing &&
+	   pmax->leftSideBearing == pmin->leftSideBearing &&
+	   pmax->descent == pmin->descent &&
+	   pmax->ascent == pmin->ascent &&
+	   pmax->characterWidth == pmin->characterWidth) ?
+		0 : N2dChars(pFont);
+
+	rlength = sizeof(xQueryFontReply) +
+	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
+		     nprotoxcistructs * sizeof(xCharInfo);
+        reply = NULL;
+	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+	if(!reply)
+	{
+	    return(BadAlloc);
+	}
+
+	reply->type = X_Reply;
+	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+	reply->sequenceNumber = client->sequence;
+	QueryFont( pFont, reply, nprotoxcistructs);
+
+        WriteReplyToClient(client, rlength, reply);
+	DEALLOCATE_LOCAL(reply);
+	return(client->noClientException);
+    }
+}
+
+int
+ProcQueryTextExtents(client)
+    register ClientPtr client;
+{
+    REQUEST(xQueryTextExtentsReq);
+    xQueryTextExtentsReply reply;
+    FontPtr pFont;
+    GC *pGC;
+    ExtentInfoRec info;
+    unsigned long length;
+
+    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+        
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+					   SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->fid;
+            return(BadFont);
+	}
+	pFont = pGC->font;
+    }
+    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+    length = length << 1;
+    if (stuff->oddLength)
+    {
+	if (length == 0)
+	    return(BadLength);
+        length--;
+    }
+    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+	return(BadAlloc);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.drawDirection = info.drawDirection;
+    reply.fontAscent = info.fontAscent;
+    reply.fontDescent = info.fontDescent;
+    reply.overallAscent = info.overallAscent;
+    reply.overallDescent = info.overallDescent;
+    reply.overallWidth = info.overallWidth;
+    reply.overallLeft = info.overallLeft;
+    reply.overallRight = info.overallRight;
+    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListFonts(client)
+    register ClientPtr client;
+{
+    char tmp[256];
+
+    REQUEST(xListFontsReq);
+
+    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
+	stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(client)
+    register ClientPtr client;
+{
+    char tmp[256];
+    REQUEST(xListFontsWithInfoReq);
+
+    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
+
+    return StartListFontsWithInfo(client, stuff->nbytes,
+				  (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/*ARGSUSED*/
+int
+dixDestroyPixmap(value, pid)
+    pointer value; /* must conform to DeleteType */
+    XID pid;
+{
+    PixmapPtr pPixmap = (PixmapPtr)value;
+    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    REQUEST(xCreatePixmapReq);
+    DepthPtr pDepth;
+    register int i;
+
+    REQUEST_SIZE_MATCH(xCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+		(pDraw->pScreen, stuff->width,
+		 stuff->height, stuff->depth);
+    if (pMap)
+    {
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	    return(client->noClientException);
+    }
+    return (BadAlloc);
+}
+
+int
+ProcFreePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+					     SecurityDestroyAccess);
+    if (pMap) 
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client releases a pixmap the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this pixmap looping through the
+         * resources.
+         */
+
+        if (pMap -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
+                       (void *) pMap);
+            #endif
+
+            nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
+                        "resource switching skipped.\n", (void *) pMap);
+          }
+          #endif
+        }
+
+        #endif
+
+	FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadPixmap);
+    }
+}
+
+int
+ProcCreateGC(client)
+    register ClientPtr client;
+{
+    int error;
+    GC *pGC;
+    register DrawablePtr pDraw;
+    unsigned len;
+    REQUEST(xCreateGCReq);
+
+    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+    client->errorValue = stuff->gc;
+    LEGAL_NEW_RESOURCE(stuff->gc, client);
+    SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+			      SecurityReadAccess);
+    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+    pGC = (GC *)CreateGC(pDraw, stuff->mask, 
+			 (XID *) &stuff[1], &error);
+    if (error != Success)
+        return error;
+    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+	return (BadAlloc);
+    return(client->noClientException);
+}
+
+int
+ProcChangeGC(client)
+    register ClientPtr client;
+{
+    GC *pGC;
+    REQUEST(xChangeGCReq);
+    int result;
+    unsigned len;
+		
+    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+    SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+
+    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcCopyGC(client)
+    register ClientPtr client;
+{
+    register GC *dstGC;
+    register GC *pGC;
+    int result;
+    REQUEST(xCopyGCReq);
+
+    REQUEST_SIZE_MATCH(xCopyGCReq);
+    SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+    SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+        return (BadMatch);    
+    result = CopyGC(pGC, dstGC, stuff->mask);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetDashes(client)
+    register ClientPtr client;
+{
+    register GC *pGC;
+    int result;
+    REQUEST(xSetDashesReq);
+
+    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+    if (stuff->nDashes == 0)
+    {
+	 client->errorValue = 0;
+         return BadValue;
+    }
+
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+		       (unsigned char *)&stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetClipRectangles(client)
+    register ClientPtr client;
+{
+    int	nr;
+    int result;
+    register GC *pGC;
+    REQUEST(xSetClipRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+    {
+	client->errorValue = stuff->ordering;
+        return BadValue;
+    }
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+		 
+    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+    if (nr & 4)
+	return(BadLength);
+    nr >>= 3;
+    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcFreeGC(client)
+    register ClientPtr client;
+{
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+    FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcClearToBackground(client)
+    register ClientPtr client;
+{
+    REQUEST(xClearAreaReq);
+    register WindowPtr pWin;
+
+    REQUEST_SIZE_MATCH(xClearAreaReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->drawable.class == InputOnly)
+    {
+	client->errorValue = stuff->window;
+	return (BadMatch);
+    }		    
+    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+    {
+	client->errorValue = stuff->exposures;
+        return(BadValue);
+    }
+    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+			       stuff->width, stuff->height,
+			       (Bool)stuff->exposures);
+    return(client->noClientException);
+}
+
+int
+ProcCopyArea(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDst;
+    register DrawablePtr pSrc;
+    register GC *pGC;
+    REQUEST(xCopyAreaReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        pSrc = pDst;
+
+    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY);
+    if (pGC->graphicsExposures)
+    {
+	(*pDst->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+	if (pRgn)
+	    REGION_DESTROY(pDst->pScreen, pRgn);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcCopyPlane(client)
+    register ClientPtr client;
+{
+    register DrawablePtr psrcDraw, pdstDraw;
+    register GC *pGC;
+    REQUEST(xCopyPlaneReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if (pdstDraw->pScreen != psrcDraw->pScreen)
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        psrcDraw = pdstDraw;
+
+    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+    {
+       client->errorValue = stuff->bitPlane;
+       return(BadValue);
+    }
+
+    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY, stuff->bitPlane);
+    if (pGC->graphicsExposures)
+    {
+	(*pdstDraw->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+	if (pRgn)
+	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyPoint(client)
+    register ClientPtr client;
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyPointReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
+    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+    if (npoint)
+    {
+        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+			  (xPoint *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyLine(client)
+    register ClientPtr client;
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyLineReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+    if (npoint > 1)
+    {
+	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
+			      (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolySegment(client)
+    register ClientPtr client;
+{
+    int nsegs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolySegmentReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+    if (nsegs & 4)
+	return(BadLength);
+    nsegs >>= 3;
+    if (nsegs)
+    {
+        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (client)
+    register ClientPtr client;
+{
+    int nrects;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+    if (nrects & 4)
+	return(BadLength);
+    nrects >>= 3;
+    if (nrects)
+    {
+        (*pGC->ops->PolyRectangle)(pDraw, pGC, 
+		    nrects, (xRectangle *) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyArc(client)
+    register ClientPtr client;
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcFillPoly(client)
+    register ClientPtr client;
+{
+    int          things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xFillPolyReq);
+
+    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
+	(stuff->shape != Convex))
+    {
+	client->errorValue = stuff->shape;
+        return BadValue;
+    }
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+    if (things)
+    {
+        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+			 stuff->coordMode, things,
+			 (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(client)
+    register ClientPtr client;
+{
+    int             things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+
+    if (things)
+    {
+        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+		      (xRectangle *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(client)
+    register ClientPtr client;
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+    int	    whichbyte = 1;
+
+    if (*((char *) &whichbyte))
+	return LSBFirst;
+    return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+    switch (bpp) {
+    case 1:	/* yuck */
+	if (BITMAP_BIT_ORDER != order)
+	    BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+	break;
+    case 4:
+	break;  /* yuck */
+    case 8:
+	break;
+    case 16:
+	if (IMAGE_BYTE_ORDER != order)
+	    TwoByteSwap ((unsigned char *) base, nbytes);
+	break;
+    case 32:
+	if (IMAGE_BYTE_ORDER != order)
+	    FourByteSwap ((unsigned char *) base, nbytes);
+	break;
+    }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(client)
+    register ClientPtr client;
+{
+    register	GC *pGC;
+    register	DrawablePtr pDraw;
+    long	length; 	/* length of scanline server padded */
+    long 	lengthProto; 	/* length of scanline protocol padded */
+    char	*tmpImage;
+    REQUEST(xPutImageReq);
+
+    REQUEST_AT_LEAST_SIZE(xPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    if (stuff->format == XYBitmap)
+    {
+        if ((stuff->depth != 1) ||
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || 
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length      = BitmapBytePad(stuff->width + stuff->leftPad);
+	length      *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+            return BadMatch;
+        length      = PixmapBytePad(stuff->width, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    tmpImage = (char *)&stuff[1];
+    lengthProto = length;
+	
+    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 
+	(sizeof(xPutImageReq) >> 2)) != client->req_len)
+	return BadLength;
+
+    ReformatImage (tmpImage, lengthProto * stuff->height, 
+		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+		   ClientOrder(client));
+    
+    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+		  stuff->width, stuff->height, 
+		  stuff->leftPad, stuff->format, tmpImage);
+
+     return (client->noClientException);
+}
+
+
+int
+DoGetImage(client, format, drawable, x, y, width, height, planemask, im_return)
+    register ClientPtr	client;
+    Drawable drawable;
+    int format;
+    int x, y, width, height;
+    Mask planemask;
+    xGetImageReply **im_return;
+{
+    register DrawablePtr pDraw;
+    int			nlines, linesPerBuf;
+    register int	linesDone;
+    long		widthBytesLine, length;
+    Mask		plane = 0;
+    char		*pBuf;
+    xGetImageReply	xgi;
+    RegionPtr pVisibleRegion = NULL;
+
+    if ((format != XYPixmap) && (format != ZPixmap))
+    {
+	client->errorValue = format;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+    if(pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + x < 0 ||
+ 	 pDraw->x + x + width > pDraw->pScreen->width ||
+         pDraw->y + y < 0 ||
+         pDraw->y + y + height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         x < - wBorderWidth((WindowPtr)pDraw) ||
+         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         y < -wBorderWidth((WindowPtr)pDraw) ||
+         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual (((WindowPtr) pDraw));
+    }
+    else
+    {
+      if(x < 0 ||
+         x+width > (int)pDraw->width ||
+         y < 0 ||
+         y+height > (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+
+    SET_DBE_SRCBUF(pDraw, drawable);
+
+    xgi.type = X_Reply;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(format == ZPixmap)
+    {
+	widthBytesLine = PixmapBytePad(width, pDraw->depth);
+	length = widthBytesLine * height;
+
+    }
+    else 
+    {
+	widthBytesLine = BitmapBytePad(width);
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = widthBytesLine * height *
+		 Ones(planemask & (plane | (plane - 1)));
+
+    }
+
+    xgi.length = length;
+
+    if (im_return) {
+	pBuf = (char *)xalloc(sz_xGetImageReply + length);
+	if (!pBuf)
+	    return (BadAlloc);
+	if (widthBytesLine == 0)
+	    linesPerBuf = 0;
+	else
+	    linesPerBuf = height;
+	*im_return = (xGetImageReply *)pBuf;
+	*(xGetImageReply *)pBuf = xgi;
+	pBuf += sz_xGetImageReply;
+    } else {
+	xgi.length = (xgi.length + 3) >> 2;
+	if (widthBytesLine == 0 || height == 0)
+	    linesPerBuf = 0;
+	else if (widthBytesLine >= IMAGE_BUFSIZE)
+	    linesPerBuf = 1;
+	else
+	{
+	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+	    if (linesPerBuf > height)
+		linesPerBuf = height;
+	}
+	length = linesPerBuf * widthBytesLine;
+	if (linesPerBuf < height)
+	{
+	    /* we have to make sure intermediate buffers don't need padding */
+	    while ((linesPerBuf > 1) &&
+		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+	    {
+		linesPerBuf--;
+		length -= widthBytesLine;
+	    }
+	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+	    {
+		linesPerBuf++;
+		length += widthBytesLine;
+	    }
+	}
+	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+	    return (BadAlloc);
+	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+    }
+
+#ifdef XCSECURITY
+    if (client->trustLevel != XSecurityClientTrusted &&
+	pDraw->type == DRAWABLE_WINDOW)
+    {
+	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+	if (pVisibleRegion)
+	{
+	    REGION_TRANSLATE(pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+	}
+    }
+#endif
+
+    if (linesPerBuf == 0)
+    {
+	/* nothing to do */
+    }
+    else if (format == ZPixmap)
+    {
+        linesDone = 0;
+        while (height - linesDone > 0)
+        {
+	    nlines = min(linesPerBuf, height - linesDone);
+	    (*pDraw->pScreen->GetImage) (pDraw,
+	                                 x,
+				         y + linesDone,
+				         width, 
+				         nlines,
+				         format,
+				         planemask,
+				         (pointer) pBuf);
+#ifdef XCSECURITY
+	    if (pVisibleRegion)
+		SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+			pDraw, x, y + linesDone, width, 
+			nlines, format, pBuf);
+#endif
+
+	    /* Note that this is NOT a call to WriteSwappedDataToClient,
+               as we do NOT byte swap */
+	    if (!im_return)
+	    {
+		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+			       BitsPerPixel (pDraw->depth),
+			       ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+		(void)WriteToClient(client,
+				    (int)(nlines * widthBytesLine),
+				    pBuf);
+	    }
+	    linesDone += nlines;
+        }
+    }
+    else /* XYPixmap */
+    {
+        for (; plane; plane >>= 1)
+	{
+	    if (planemask & plane)
+	    {
+	        linesDone = 0;
+	        while (height - linesDone > 0)
+	        {
+		    nlines = min(linesPerBuf, height - linesDone);
+	            (*pDraw->pScreen->GetImage) (pDraw,
+	                                         x,
+				                 y + linesDone,
+				                 width, 
+				                 nlines,
+				                 format,
+				                 plane,
+				                 (pointer)pBuf);
+#ifdef XCSECURITY
+		    if (pVisibleRegion)
+			SecurityCensorImage(client, pVisibleRegion,
+				widthBytesLine,
+				pDraw, x, y + linesDone, width, 
+				nlines, format, pBuf);
+#endif
+
+		    /* Note: NOT a call to WriteSwappedDataToClient,
+		       as we do NOT byte swap */
+		    if (im_return) {
+			pBuf += nlines * widthBytesLine;
+		    } else {
+			ReformatImage (pBuf, 
+				       (int)(nlines * widthBytesLine), 
+				       1,
+				       ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+			(void)WriteToClient(client,
+					(int)(nlines * widthBytesLine),
+					pBuf);
+		    }
+		    linesDone += nlines;
+		}
+            }
+	}
+    }
+#ifdef XCSECURITY
+    if (pVisibleRegion)
+	REGION_DESTROY(pScreen, pVisibleRegion);
+#endif
+    if (!im_return)
+	DEALLOCATE_LOCAL(pBuf);
+    return (client->noClientException);
+}
+
+int
+ProcGetImage(client)
+    register ClientPtr	client;
+{
+    REQUEST(xGetImageReq);
+
+    REQUEST_SIZE_MATCH(xGetImageReq);
+
+    return DoGetImage(client, stuff->format, stuff->drawable,
+		      stuff->x, stuff->y,
+		      (int)stuff->width, (int)stuff->height,
+		      stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(client)
+    register ClientPtr client;
+{
+    int	err;
+    REQUEST(xPolyTextReq);
+    DrawablePtr pDraw;
+    GC *pGC;
+
+    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = PolyText(client,
+		   pDraw,
+		   pGC,
+		   (unsigned char *)&stuff[1],
+		   ((unsigned char *) stuff) + (client->req_len << 2),
+		   stuff->x,
+		   stuff->y,
+		   stuff->reqType,
+		   stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText8(client)
+    register ClientPtr client;
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText16(client)
+    register ClientPtr client;
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+
+int
+ProcCreateColormap(client)
+    register ClientPtr client;
+{
+    VisualPtr	pVisual;
+    ColormapPtr	pmap;
+    Colormap	mid;
+    register WindowPtr   pWin;
+    ScreenPtr pScreen;
+    REQUEST(xCreateColormapReq);
+    int i, result;
+
+    REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+    {
+	client->errorValue = stuff->alloc;
+        return(BadValue);
+    }
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pScreen = pWin->drawable.pScreen;
+    for (i = 0, pVisual = pScreen->visuals;
+	 i < pScreen->numVisuals;
+	 i++, pVisual++)
+    {
+	if (pVisual->vid != stuff->visual)
+	    continue;
+	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
+				 (int)stuff->alloc, client->index);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+	    return(result);
+    }
+    client->errorValue = stuff->visual;
+    return(BadValue);
+}
+
+int
+ProcFreeColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pmap;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+						SecurityDestroyAccess);
+    if (pmap) 
+    {
+	/* Freeing a default colormap is a no-op */
+	if (!(pmap->flags & IsDefault))
+	    FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadColor);
+    }
+}
+
+
+int
+ProcCopyColormapAndFree(client)
+    register ClientPtr client;
+{
+    Colormap	mid;
+    ColormapPtr	pSrcMap;
+    REQUEST(xCopyColormapAndFreeReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client,	stuff->srcCmap,
+		RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+    {
+	result = CopyColormapAndFree(mid, pSrcMap, client->index);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->srcCmap;
+	return(BadColor);
+    }
+}
+
+int
+ProcInstallColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					    RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+        (*(pcmp->pScreen->InstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcUninstallColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	if(pcmp->mid != pcmp->pScreen->defColormap)
+            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcListInstalledColormaps(client)
+    register ClientPtr client;
+{
+    xListInstalledColormapsReply *preply; 
+    int nummaps;
+    WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+
+    if (!pWin)
+        return(BadWindow);
+
+    preply = (xListInstalledColormapsReply *) 
+		ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+		     pWin->drawable.pScreen->maxInstalledCmaps *
+		     sizeof(Colormap));
+    if(!preply)
+        return(BadAlloc);
+
+    preply->type = X_Reply;
+    preply->sequenceNumber = client->sequence;
+    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+    preply->nColormaps = nummaps;
+    preply->length = nummaps;
+    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+    DEALLOCATE_LOCAL(preply);
+    return(client->noClientException);
+}
+
+int
+ProcAllocColor(client)
+    register ClientPtr client;
+{
+    ColormapPtr pmap;
+    int	retval;
+    xAllocColorReply acr;
+    REQUEST(xAllocColorReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorReq);
+    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pmap)
+    {
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+	    return Success;
+#endif
+	acr.type = X_Reply;
+	acr.length = 0;
+	acr.sequenceNumber = client->sequence;
+	acr.red = stuff->red;
+	acr.green = stuff->green;
+	acr.blue = stuff->blue;
+	acr.pixel = 0;
+	if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+	                       &acr.pixel, client->index)) )
+	{
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return (retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+	return (client->noClientException);
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocNamedColor           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					    RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int		retval;
+
+	xAllocNamedColorReply ancr;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocNamedColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	ancr.type = X_Reply;
+	ancr.length = 0;
+	ancr.sequenceNumber = client->sequence;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+	{
+	    ancr.screenRed = ancr.exactRed;
+	    ancr.screenGreen = ancr.exactGreen;
+	    ancr.screenBlue = ancr.exactBlue;
+	    ancr.pixel = 0;
+	    if( (retval = AllocColor(pcmp,
+	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+			 &ancr.pixel, client->index)) )
+	    {
+                if (client->noClientException != Success)
+                    return(client->noClientException);
+                else
+    	            return(retval);
+	    }
+#ifdef PANORAMIX
+	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+	    return (client->noClientException);
+	}
+	else
+	    return(BadName);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorCells           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorCellsReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorCellsReply	accr;
+	int			npixels, nmasks, retval;
+	long			length;
+	Pixel			*ppixels, *pmasks;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorCells request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	nmasks = stuff->planes;
+	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	pmasks = ppixels + npixels;
+
+	if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 
+				    (Bool)stuff->contiguous, ppixels, pmasks)) )
+	{
+	    DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    accr.type = X_Reply;
+	    accr.length = length >> 2;
+	    accr.sequenceNumber = client->sequence;
+	    accr.nPixels = npixels;
+	    accr.nMasks = nmasks;
+	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorPlanes(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorPlanesReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorPlanesReply	acpr;
+	int			npixels, retval;
+	long			length;
+	Pixel			*ppixels;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorPlanes request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	acpr.type = X_Reply;
+	acpr.sequenceNumber = client->sequence;
+	acpr.nPixels = npixels;
+	length = (long)npixels * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+	    (Bool)stuff->contiguous, ppixels,
+	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+	{
+            DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+	acpr.length = length >> 2;
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcFreeColors          (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xFreeColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+	if(pcmp->flags & AllAllocated)
+	    return(BadAccess);
+	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+	retval =  FreeColors(pcmp, client->index, count,
+	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreColors               (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+	if (count % sizeof(xColorItem))
+	    return(BadLength);
+	count /= sizeof(xColorItem);
+	retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreNamedColor           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xColorItem	def;
+        int             retval;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+	                 stuff->nbytes, &def.red, &def.green, &def.blue))
+	{
+	    def.flags = stuff->flags;
+	    def.pixel = stuff->pixel;
+	    retval = StoreColors(pcmp, 1, &def);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+		return(retval);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcQueryColors(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xQueryColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	int			count, retval;
+	xrgb 			*prgbs;
+	xQueryColorsReply	qcr;
+
+	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+	prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+	if(!prgbs && count)
+            return(BadAlloc);
+	if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+	{
+   	    if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	    if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	    {
+		client->errorValue = clientErrorValue;
+	        return (retval);
+	    }
+	}
+	qcr.type = X_Reply;
+	qcr.length = (count * sizeof(xrgb)) >> 2;
+	qcr.sequenceNumber = client->sequence;
+	qcr.nColors = count;
+	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+	if (count)
+	{
+	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+	}
+	if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	return(client->noClientException);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+} 
+
+int
+ProcLookupColor(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xLookupColorReq);
+
+    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	xLookupColorReply lcr;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+	{
+	    lcr.type = X_Reply;
+	    lcr.length = 0;
+	    lcr.sequenceNumber = client->sequence;
+	    lcr.screenRed = lcr.exactRed;
+	    lcr.screenGreen = lcr.exactGreen;
+	    lcr.screenBlue = lcr.exactBlue;
+	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+	                                   &lcr.screenGreen,
+					   &lcr.screenBlue,
+					   pcmp->pVisual);
+	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+	    return(client->noClientException);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcCreateCursor( client)
+    register ClientPtr client;
+{
+    CursorPtr	pCursor;
+
+    register PixmapPtr 	src;
+    register PixmapPtr 	msk;
+    unsigned char *	srcbits;
+    unsigned char *	mskbits;
+    unsigned short	width, height;
+    long		n;
+    CursorMetricRec cm;
+
+
+    REQUEST(xCreateCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+					      RT_PIXMAP, SecurityReadAccess);
+    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+					      RT_PIXMAP, SecurityReadAccess);
+    if (   src == (PixmapPtr)NULL)
+    {
+	client->errorValue = stuff->source;
+	return (BadPixmap);
+    }
+    if ( msk == (PixmapPtr)NULL)
+    {
+	if (stuff->mask != None)
+	{
+	    client->errorValue = stuff->mask;
+	    return (BadPixmap);
+	}
+    }
+    else if (  src->drawable.width != msk->drawable.width
+	    || src->drawable.height != msk->drawable.height
+	    || src->drawable.depth != 1
+	    || msk->drawable.depth != 1)
+	return (BadMatch);
+
+    width = src->drawable.width;
+    height = src->drawable.height;
+
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+
+    n = BitmapBytePad(width)*height;
+    srcbits = (unsigned char *)xalloc(n);
+    if (!srcbits)
+	return (BadAlloc);
+    mskbits = (unsigned char *)xalloc(n);
+    if (!mskbits)
+    {
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+
+    /* zeroing the (pad) bits helps some ddx cursor handling */
+    bzero((char *)srcbits, n);
+    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+					 XYPixmap, 1, (pointer)srcbits);
+    if ( msk == (PixmapPtr)NULL)
+    {
+	register unsigned char *bits = mskbits;
+	while (--n >= 0)
+	    *bits++ = ~0;
+    }
+    else
+    {
+	/* zeroing the (pad) bits helps some ddx cursor handling */
+	bzero((char *)mskbits, n);
+	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+					height, XYPixmap, 1, (pointer)mskbits);
+    }
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursor( srcbits, mskbits, &cm,
+	    stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+	    stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+    {
+        #ifdef TEST
+        fprintf(stderr, "ProcCreateCursor: Created cursor at [%p].\n", (void *) pCursor);
+        #endif
+
+	    return (client->noClientException);
+    }
+
+    return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor( client)
+    register ClientPtr client;
+{
+    CursorPtr pCursor;
+    int res;
+
+    REQUEST(xCreateGlyphCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+			   stuff->mask, stuff->maskChar,
+			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+			   stuff->backRed, stuff->backGreen, stuff->backBlue,
+			   &pCursor, client);
+    if (res != Success)
+	return res;
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+
+int
+ProcFreeCursor(client)
+    register ClientPtr client;
+{
+    CursorPtr pCursor;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_CURSOR, SecurityDestroyAccess);
+    if (pCursor) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadCursor);
+    }
+}
+
+int
+ProcQueryBestSize   (client)
+    register ClientPtr client;
+{
+    xQueryBestSizeReply	reply;
+    register DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    REQUEST(xQueryBestSizeReq);
+
+    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+    if ((stuff->class != CursorShape) && 
+	(stuff->class != TileShape) && 
+	(stuff->class != StippleShape))
+    {
+	client->errorValue = stuff->class;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+	return (BadMatch);
+    pScreen = pDraw->pScreen;
+    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+			       &stuff->height, pScreen);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.width = stuff->width;
+    reply.height = stuff->height;
+    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+    return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver            (client)
+    register ClientPtr client;
+{
+    int blankingOption, exposureOption;
+    REQUEST(xSetScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+    blankingOption = stuff->preferBlank;
+    if ((blankingOption != DontPreferBlanking) &&
+        (blankingOption != PreferBlanking) &&
+        (blankingOption != DefaultBlanking))
+    {
+	client->errorValue = blankingOption;
+        return BadValue;
+    }
+    exposureOption = stuff->allowExpose;
+    if ((exposureOption != DontAllowExposures) &&
+        (exposureOption != AllowExposures) &&
+        (exposureOption != DefaultExposures))
+    {
+	client->errorValue = exposureOption;
+        return BadValue;
+    }
+    if (stuff->timeout < -1)
+    {
+	client->errorValue = stuff->timeout;
+        return BadValue;
+    }
+    if (stuff->interval < -1)
+    {
+	client->errorValue = stuff->interval;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to change our values.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
+                stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
+    #endif
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      if (blankingOption == DefaultBlanking)
+      {
+	ScreenSaverBlanking = defaultScreenSaverBlanking;
+      }
+      else
+      {
+	ScreenSaverBlanking = blankingOption; 
+      }
+
+      if (exposureOption == DefaultExposures)
+      {
+	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+      }
+      else
+      {
+        ScreenSaverAllowExposures = exposureOption;
+      }
+
+      if (stuff->timeout >= 0)
+      {
+        ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverTime = defaultScreenSaverTime;
+      }
+
+      if (stuff->interval >= 0)
+      {
+        ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverInterval = defaultScreenSaverInterval;
+      }
+    }
+ 
+    #ifdef TEST
+
+    else 
+    {
+      fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
+                  nxagentOption(Timeout));
+    }
+
+    #endif
+
+    return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(client)
+    register ClientPtr client;
+{
+    xGetScreenSaverReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+    rep.preferBlanking = ScreenSaverBlanking;
+    rep.allowExposures = ScreenSaverAllowExposures;
+    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+    return (client->noClientException);
+}
+
+int
+ProcChangeHosts(client)
+    register ClientPtr client;
+{
+    REQUEST(xChangeHostsReq);
+    int result;
+
+    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+    if(stuff->mode == HostInsert)
+	result = AddHost(client, (int)stuff->hostFamily,
+			 stuff->hostLength, (pointer)&stuff[1]);
+    else if (stuff->mode == HostDelete)
+	result = RemoveHost(client, (int)stuff->hostFamily, 
+			    stuff->hostLength, (pointer)&stuff[1]);  
+    else
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcListHosts(client)
+    register ClientPtr client;
+{
+    xListHostsReply reply;
+    int	len, nHosts, result;
+    pointer	pdata;
+    /* REQUEST(xListHostsReq); */
+
+    REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+    /* untrusted clients can't list hosts */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	SecurityAudit("client %d attempted to list hosts\n", client->index);
+	return BadAccess;
+    }
+#endif
+    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+    if (result != Success)
+	return(result);
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.nHosts = nHosts;
+    reply.length = len >> 2;
+    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+    if (nHosts)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+	WriteSwappedDataToClient(client, len, pdata);
+    }
+    xfree(pdata);
+    return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(client)
+    register ClientPtr client;
+{
+    int result;
+    REQUEST(xSetAccessControlReq);
+
+    REQUEST_SIZE_MATCH(xSetAccessControlReq);
+    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcKillClient(client)
+    register ClientPtr client;
+{
+    REQUEST(xResourceReq);
+    ClientPtr	killclient;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (stuff->id == AllTemporary)
+    {
+	CloseDownRetainedResources();
+        return (client->noClientException);
+    }
+
+    if ((killclient = LookupClient(stuff->id, client)))
+    {
+	CloseDownClient(killclient);
+	/* if an LBX proxy gets killed, isItTimeToYield will be set */
+	if (isItTimeToYield || (client == killclient))
+	{
+	    /* force yield and return Success, so that Dispatch()
+	     * doesn't try to touch client
+	     */
+	    isItTimeToYield = TRUE;
+	    return (Success);
+	}
+	return (client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+	return (BadValue);
+    }
+}
+
+int
+ProcSetFontPath(client)
+    register ClientPtr client;
+{
+    unsigned char *ptr;
+    unsigned long nbytes, total;
+    long nfonts;
+    int n, result;
+    int error;
+    REQUEST(xSetFontPathReq);
+    
+    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+    
+    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+    total = nbytes;
+    ptr = (unsigned char *)&stuff[1];
+    nfonts = stuff->nFonts;
+    while (--nfonts >= 0)
+    {
+	if ((total == 0) || (total < (n = (*ptr + 1))))
+	    return(BadLength);
+	total -= n;
+	ptr += n;
+    }
+    if (total >= 4)
+	return(BadLength);
+    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+			 &error);
+    if (!result)
+    {
+	result = client->noClientException;
+	client->errorValue = error;
+    }
+    return (result);
+}
+
+int
+ProcGetFontPath(client)
+    register ClientPtr client;
+{
+    xGetFontPathReply reply;
+    int stringLens, numpaths;
+    unsigned char *bufferStart;
+    /* REQUEST (xReq); */
+
+    REQUEST_SIZE_MATCH(xReq);
+    bufferStart = GetFontPath(&numpaths, &stringLens);
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = (stringLens + numpaths + 3) >> 2;
+    reply.nPaths = numpaths;
+
+    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+    if (stringLens || numpaths)
+	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+    return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(client)
+    register ClientPtr client;
+{
+    REQUEST(xSetCloseDownModeReq);
+
+    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+    if ((stuff->mode == AllTemporary) ||
+	(stuff->mode == RetainPermanent) ||
+	(stuff->mode == RetainTemporary))
+    {
+	client->closeDownMode = stuff->mode;
+	return (client->noClientException);
+    }
+    else   
+    {
+	client->errorValue = stuff->mode;
+	return (BadValue);
+    }
+}
+
+int ProcForceScreenSaver(client)
+    register ClientPtr client;
+{    
+    REQUEST(xForceScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+    
+    if ((stuff->mode != ScreenSaverReset) && 
+	(stuff->mode != ScreenSaverActive))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to force the screen
+     * saver handler execution. 
+     */
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+    }
+
+    #ifdef TEST
+
+    else
+    {
+      fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
+                  stuff -> mode);
+    }
+
+    #endif
+
+    return client->noClientException;
+}
+
+int ProcNoOperation(client)
+    register ClientPtr client;
+{
+    REQUEST_AT_LEAST_SIZE(xReq);
+    
+    /* noop -- don't do anything */
+    return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+    int i;
+    for (i = 0; i<256; i++)
+    {
+	if(!ProcVector[i])
+	{
+            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+	    ReplySwapVector[i] = ReplyNotSwappd;
+	}
+#ifdef K5AUTH
+	if (!k5_Vector[i])
+	{
+	    k5_Vector[i] = k5_bad;
+	}
+#endif
+    }
+    for(i = LASTEvent; i < 128; i++)
+    {
+	EventSwapVector[i] = NotImplemented;
+    }
+    
+}
+
+/**********************
+ * CloseDownClient
+ *
+ *  Client can either mark his resources destroy or retain.  If retained and
+ *  then killed again, the client is really destroyed.
+ *********************/
+
+void
+CloseDownClient(client)
+    register ClientPtr client;
+{
+    Bool really_close_down = client->clientGone ||
+			     client->closeDownMode == DestroyAll;
+
+    /*
+     * There must be a better way to hook a
+     * call-back function to be called any
+     * time a client is going to be closed.
+     */
+
+    nxagentClearClipboard(client, NULL);
+
+    /*
+     * Need to reset the karma counter and
+     * get rid of the pending sync replies.
+     */
+
+    nxagentWakeupByReset(client);
+
+    /*
+     * Check if the client
+     * is a shadow nxagent.
+     */
+
+    nxagentCheckIfShadowAgent(client);
+
+    if (!client->clientGone)
+    {
+	/* ungrab server if grabbing client dies */
+	if (grabState != GrabNone && grabClient == client)
+	{
+	    UngrabServer(client);
+	}
+	BITCLEAR(grabWaiters, client->index);
+	DeleteClientFromAnySelections(client);
+	ReleaseActiveGrabs(client);
+	DeleteClientFontStuff(client);
+	if (!really_close_down)
+	{
+	    /*  This frees resources that should never be retained
+	     *  no matter what the close down mode is.  Actually we
+	     *  could do this unconditionally, but it's probably
+	     *  better not to traverse all the client's resources
+	     *  twice (once here, once a few lines down in
+	     *  FreeClientResources) in the common case of
+	     *  really_close_down == TRUE.
+	     */
+	    FreeClientNeverRetainResources(client);
+	    client->clientState = ClientStateRetained;
+  	    if (ClientStateCallback)
+            {
+		NewClientInfoRec clientinfo;
+
+		clientinfo.client = client; 
+		clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+		clientinfo.setup = (xConnSetup *) NULL;
+		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+            } 
+	}
+	client->clientGone = TRUE;  /* so events aren't sent to client */
+	if (ClientIsAsleep(client))
+	    ClientSignal (client);
+	ProcessWorkQueueZombies();
+#ifdef LBX
+	ProcessQTagZombies();
+#endif
+	CloseDownConnection(client);
+
+	/* If the client made it to the Running stage, nClients has
+	 * been incremented on its behalf, so we need to decrement it
+	 * now.  If it hasn't gotten to Running, nClients has *not*
+	 * been incremented, so *don't* decrement it.
+	 */
+	if (client->clientState != ClientStateInitial &&
+	    client->clientState != ClientStateAuthenticating )
+	{
+	    --nClients;
+	}
+    }
+
+    if (really_close_down)
+    {
+	if (client->clientState == ClientStateRunning && nClients == 0)
+	    dispatchException |= dispatchExceptionAtReset;
+
+	client->clientState = ClientStateGone;
+	if (ClientStateCallback)
+	{
+	    NewClientInfoRec clientinfo;
+
+	    clientinfo.client = client; 
+	    clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+	    clientinfo.setup = (xConnSetup *) NULL;
+	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+	} 	    
+	FreeClientResources(client);
+	if (client->index < nextFreeClientID)
+	    nextFreeClientID = client->index;
+	clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+	SmartLastClient = NullClient;
+#endif
+	xfree(client);
+
+	while (!clients[currentMaxClients-1])
+	    currentMaxClients--;
+    }
+}
+
+static void
+KillAllClients()
+{
+    int i;
+    for (i=1; i<currentMaxClients; i++)
+        if (clients[i]) {
+            /* Make sure Retained clients are released. */
+            clients[i]->closeDownMode = DestroyAll;
+            CloseDownClient(clients[i]);     
+        }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ *    Find all clients that are gone and have terminated in RetainTemporary 
+ *    and  destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+    register int i;
+    register ClientPtr client;
+
+    for (i=1; i<currentMaxClients; i++)
+    {
+        client = clients[i];
+        if (client && (client->closeDownMode == RetainTemporary)
+	    && (client->clientGone))
+	    CloseDownClient(client);
+    }
+}
+
+void InitClient(client, i, ospriv)
+    ClientPtr client;
+    int i;
+    pointer ospriv;
+{
+    client->index = i;
+    client->sequence = 0; 
+    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+    client->clientGone = FALSE;
+    if (i)
+    {
+	client->closeDownMode = DestroyAll;
+	client->lastDrawable = (DrawablePtr)WindowTable[0];
+	client->lastDrawableID = WindowTable[0]->drawable.id;
+    }
+    else
+    {
+	client->closeDownMode = RetainPermanent;
+	client->lastDrawable = (DrawablePtr)NULL;
+	client->lastDrawableID = INVALID;
+    }
+    client->lastGC = (GCPtr) NULL;
+    client->lastGCID = INVALID;
+    client->numSaved = 0;
+    client->saveSet = (pointer *)NULL;
+    client->noClientException = Success;
+#ifdef LOG_DEBUG
+    client->requestLogIndex = 0;
+#endif
+    client->requestVector = InitialVector;
+    client->osPrivate = ospriv;
+    client->swapped = FALSE;
+    client->big_requests = FALSE;
+    client->priority = 0;
+    client->clientState = ClientStateInitial;
+#ifdef XKB
+    if (!noXkbExtension) {
+	client->xkbClientFlags = 0;
+	client->mapNotifyMask = 0;
+	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+    }
+#endif
+    client->replyBytesRemaining = 0;
+#ifdef LBX
+    client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+    client->trustLevel = XSecurityClientTrusted;
+    client->CheckAccess = NULL;
+    client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+    client->appgroup = NULL;
+#endif
+    client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+    client->smart_priority = 0;
+    client->smart_start_tick = SmartScheduleTime;
+    client->smart_stop_tick = SmartScheduleTime;
+    client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(client)
+    ClientPtr client;
+{
+    register char *ptr;
+    DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    if (totalClientSize == sizeof(ClientRec))
+	ppriv = (DevUnion *)NULL;
+    else if (client->index)
+	ppriv = (DevUnion *)(client + 1);
+    else
+    {
+	ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+	if (!ppriv)
+	    return 0;
+    }
+    client->devPrivates = ppriv;
+    sizes = clientPrivateSizes;
+    ptr = (char *)(ppriv + clientPrivateLen);
+    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+
+    /*
+     * Initialize the private members.
+     */
+
+    nxagentInitClientPrivates(client);
+
+    return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr
+NextAvailableClient(ospriv)
+    pointer ospriv;
+{
+    register int i;
+    register ClientPtr client;
+    xReq data;
+
+    i = nextFreeClientID;
+    if (i == MAXCLIENTS)
+	return (ClientPtr)NULL;
+    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+    if (!client)
+	return (ClientPtr)NULL;
+    InitClient(client, i, ospriv);
+    InitClientPrivates(client);
+    if (!InitClientResources(client))
+    {
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    data.reqType = 1;
+    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+    {
+	FreeClientResources(client);
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    if (i == currentMaxClients)
+	currentMaxClients++;
+    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+	nextFreeClientID++;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+        clientinfo.setup = (xConnSetup *) NULL;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return(client);
+}
+
+int
+ProcInitialConnection(client)
+    register ClientPtr client;
+{
+    REQUEST(xReq);
+    register xConnClientPrefix *prefix;
+    int whichbyte = 1;
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+	return (client->noClientException = -1);
+    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+    {
+	client->swapped = TRUE;
+	SwapConnClientPrefix(prefix);
+    }
+    stuff->reqType = 2;
+    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+    if (client->swapped)
+    {
+	swaps(&stuff->length, whichbyte);
+    }
+    ResetCurrentRequest(client);
+    return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+    nClients++;
+}
+#endif
+
+int
+SendConnSetup(client, reason)
+    register ClientPtr client;
+    char *reason;
+{
+    register xWindowRoot *root;
+    register int i;
+    int numScreens;
+    char* lConnectionInfo;
+    xConnSetupPrefix* lconnSetupPrefix;
+
+    if (reason)
+    {
+	xConnSetupPrefix csp;
+
+	csp.success = xFalse;
+	csp.lengthReason = strlen(reason);
+	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+	csp.majorVersion = X_PROTOCOL;
+	csp.minorVersion = X_PROTOCOL_REVISION;
+	if (client->swapped)
+	    WriteSConnSetupPrefix(client, &csp);
+	else
+	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+        (void)WriteToClient(client, (int)csp.lengthReason, reason);
+	return (client->noClientException = -1);
+    }
+
+    numScreens = screenInfo.numScreens;
+    lConnectionInfo = ConnectionInfo;
+    lconnSetupPrefix = &connSetupPrefix;
+
+    /* We're about to start speaking X protocol back to the client by
+     * sending the connection setup info.  This means the authorization
+     * step is complete, and we can count the client as an
+     * authorized one.
+     */
+    nClients++;
+
+    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+    client->sequence = 0;
+#ifdef XAPPGROUP
+    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+    /* fill in the "currentInputMask" */
+    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+    for (i=0; i<numScreens; i++) 
+    {
+	register unsigned int j;
+	register xDepth *pDepth;
+
+        root->currentInputMask = WindowTable[i]->eventMask |
+			         wOtherEventMasks (WindowTable[i]);
+	pDepth = (xDepth *)(root + 1);
+	for (j = 0; j < root->nDepths; j++)
+	{
+	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+				pDepth->nVisuals * sizeof(xVisualType));
+	}
+	root = (xWindowRoot *)pDepth;
+    }
+
+    if (client->swapped)
+    {
+	WriteSConnSetupPrefix(client, lconnSetupPrefix);
+	WriteSConnectionInfo(client,
+			     (unsigned long)(lconnSetupPrefix->length << 2),
+			     lConnectionInfo);
+    }
+    else
+    {
+	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
+			    (char *) lconnSetupPrefix);
+	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+			    lConnectionInfo);
+    }
+    client->clientState = ClientStateRunning;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = lconnSetupPrefix;  
+        clientinfo.setup = (xConnSetup *)lConnectionInfo;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(client)
+    register ClientPtr client;
+{
+    char *reason, *auth_proto, *auth_string;
+    register xConnClientPrefix *prefix;
+    REQUEST(xReq);
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    auth_proto = (char *)prefix + sz_xConnClientPrefix;
+    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+    if ((prefix->majorVersion != X_PROTOCOL) ||
+	(prefix->minorVersion != X_PROTOCOL_REVISION))
+	reason = "Protocol version mismatch";
+    else
+	reason = ClientAuthorized(client,
+				  (unsigned short)prefix->nbytesAuthProto,
+				  auth_proto,
+				  (unsigned short)prefix->nbytesAuthString,
+				  auth_string);
+    /*
+     * If Kerberos is being used for this client, the clientState
+     * will be set to ClientStateAuthenticating at this point.
+     * More messages need to be exchanged among the X server, Kerberos
+     * server, and client to figure out if everyone is authorized.
+     * So we don't want to send the connection setup info yet, since
+     * the auth step isn't really done.
+     */
+    if (client->clientState == ClientStateCheckingSecurity)
+	client->clientState = ClientStateCheckedSecurity;
+    else if (client->clientState != ClientStateAuthenticating)
+	return(SendConnSetup(client, reason));
+    return(client->noClientException);
+}
+
+void
+SendErrorToClient(client, majorCode, minorCode, resId, errorCode)
+    ClientPtr client;
+    unsigned int majorCode;
+    unsigned int minorCode;
+    XID resId;
+    int errorCode;
+{
+    xError rep;
+
+    rep.type = X_Error;
+    rep.sequenceNumber = client->sequence;
+    rep.errorCode = errorCode;
+    rep.majorCode = majorCode;
+    rep.minorCode = minorCode;
+    rep.resourceID = resId;
+
+    WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(pWin)
+    WindowPtr pWin;
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].pWin == pWin)
+        {
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+static void
+DeleteClientFromAnySelections(client)
+    ClientPtr client;
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].client == client)
+        {
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+void
+MarkClientException(client)
+    ClientPtr client;
+{
+    client->noClientException = -1;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.XF86.original
new file mode 100644
index 000000000..a385a8b09
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.XF86.original
@@ -0,0 +1,4110 @@
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/****************************************************************
+*                                                               *
+*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.29 2003/01/12 02:44:26 dawes Exp $ */
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#include "windowstr.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef XAPPGROUP
+#include "Xagsrv.h"
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include "XKBsrv.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(
+#if NeedFunctionPrototypes
+    void
+#endif
+);
+
+static void DeleteClientFromAnySelections(
+#if NeedFunctionPrototypes
+    ClientPtr /*client*/
+#endif
+);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int	nClients;	/* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+char dispatchException = 0;
+char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue;   /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+    (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(c0, c1)
+    HWEventQueuePtr c0, c1;
+{
+    checkForInput[0] = c0;
+    checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+    TimeStamp systime;
+
+    /* To avoid time running backwards, we must call GetTimeInMillis before
+     * calling ProcessInputEvents.
+     */
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] != *checkForInput[1])
+	ProcessInputEvents();
+    if (CompareTimeStamps(systime, currentTime) == LATER)
+	currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+    TimeStamp systime;
+
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] == *checkForInput[1])
+	currentTime = systime;
+}
+
+void
+InitSelections()
+{
+    if (CurrentSelections)
+	xfree(CurrentSelections);
+    CurrentSelections = (Selection *)NULL;
+    NumCurrentSelections = 0;
+}
+
+void 
+FlushClientCaches(id)
+    XID id;
+{
+    int i;
+    register ClientPtr client;
+
+    client = clients[CLIENT_ID(id)];
+    if (client == NullClient)
+        return ;
+    for (i=0; i<currentMaxClients; i++)
+    {
+	client = clients[i];
+        if (client != NullClient)
+	{
+            if (client->lastDrawableID == id)
+	    {
+		client->lastDrawableID = WindowTable[0]->drawable.id;
+		client->lastDrawable = (DrawablePtr)WindowTable[0];
+	    }
+            else if (client->lastGCID == id)
+	    {
+                client->lastGCID = INVALID;
+		client->lastGC = (GCPtr)NULL;
+	    }
+	}
+    }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
+#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
+
+Bool	    SmartScheduleDisable;
+long	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long	    SmartScheduleTime;
+ClientPtr   SmartLastClient;
+int	    SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int         SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long	    SmartLastPrint;
+#endif
+
+void        Dispatch(void);
+void        InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+    ClientPtr	pClient;
+    int		i;
+    int		client;
+    int		bestPrio, best = 0;
+    int		bestRobin, robin;
+    long	now = SmartScheduleTime;
+    long	idle;
+
+    bestPrio = -0x7fffffff;
+    bestRobin = 0;
+    idle = 2 * SmartScheduleSlice;
+    for (i = 0; i < nready; i++)
+    {
+	client = clientReady[i];
+	pClient = clients[client];
+	/* Praise clients which are idle */
+	if ((now - pClient->smart_check_tick) >= idle)
+	{
+	    if (pClient->smart_priority < 0)
+		pClient->smart_priority++;
+	}
+	pClient->smart_check_tick = now;
+	
+	/* check priority to select best client */
+	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+	if (pClient->smart_priority > bestPrio ||
+	    (pClient->smart_priority == bestPrio && robin > bestRobin))
+	{
+	    bestPrio = pClient->smart_priority;
+	    bestRobin = robin;
+	    best = client;
+	}
+#ifdef SMART_DEBUG
+	if ((now - SmartLastPrint) >= 5000)
+	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+    }
+#ifdef SMART_DEBUG
+    if ((now - SmartLastPrint) >= 5000)
+    {
+	fprintf (stderr, " use %2d\n", best);
+	SmartLastPrint = now;
+    }
+#endif
+    pClient = clients[best];
+    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+    /*
+     * Set current client pointer
+     */
+    if (SmartLastClient != pClient)
+    {
+	pClient->smart_start_tick = now;
+	SmartLastClient = pClient;
+    }
+    /*
+     * Adjust slice
+     */
+    if (nready == 1)
+    {
+	/*
+	 * If it's been a long time since another client
+	 * has run, bump the slice up to get maximal
+	 * performance from a single client
+	 */
+	if ((now - pClient->smart_start_tick) > 1000 &&
+	    SmartScheduleSlice < SmartScheduleMaxSlice)
+	{
+	    SmartScheduleSlice += SmartScheduleInterval;
+	}
+    }
+    else
+    {
+	SmartScheduleSlice = SmartScheduleInterval;
+    }
+    return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+    register int        *clientReady;     /* array of request ready clients */
+    register int	result;
+    register ClientPtr	client;
+    register int	nready;
+    register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+    int			start_tick;
+#endif
+
+    #ifdef __DARWIN__
+    extern char dispatchExceptionAtReset;
+    #endif    
+
+    nextFreeClientID = 1;
+    InitSelections();
+    nClients = 0;
+
+    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+    if (!clientReady)
+	return;
+
+    while (!dispatchException)
+    {
+        if (*icheck[0] != *icheck[1])
+	{
+	    ProcessInputEvents();
+	    FlushIfCriticalOutputPending();
+	}
+
+	nready = WaitForSomething(clientReady);
+
+#ifdef SMART_SCHEDULE
+	if (nready && !SmartScheduleDisable)
+	{
+	    clientReady[0] = SmartScheduleClient (clientReady, nready);
+	    nready = 1;
+	}
+#endif
+       /***************** 
+	*  Handle events in round robin fashion, doing input between 
+	*  each round 
+	*****************/
+
+	while (!dispatchException && (--nready >= 0))
+	{
+	    client = clients[clientReady[nready]];
+	    if (! client)
+	    {
+		/* KillClient can cause this to happen */
+		continue;
+	    }
+	    /* GrabServer activation can cause this to be true */
+	    if (grabState == GrabKickout)
+	    {
+		grabState = GrabActive;
+		break;
+	    }
+	    isItTimeToYield = FALSE;
+ 
+            requestingClient = client;
+#ifdef SMART_SCHEDULE
+	    start_tick = SmartScheduleTime;
+#endif
+	    while (!isItTimeToYield)
+	    {
+	        if (*icheck[0] != *icheck[1])
+		{
+		    ProcessInputEvents();
+		    FlushIfCriticalOutputPending();
+		}
+#ifdef SMART_SCHEDULE
+		if (!SmartScheduleDisable && 
+		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+		{
+		    /* Penalize clients which consume ticks */
+		    if (client->smart_priority > SMART_MIN_PRIORITY)
+			client->smart_priority--;
+		    break;
+		}
+#endif
+		/* now, finally, deal with client requests */
+
+	        result = ReadRequestFromClient(client);
+	        if (result <= 0) 
+	        {
+		    if (result < 0)
+			CloseDownClient(client);
+		    break;
+	        }
+
+		client->sequence++;
+#ifdef DEBUG
+		if (client->requestLogIndex == MAX_REQUEST_LOG)
+		    client->requestLogIndex = 0;
+		client->requestLog[client->requestLogIndex] = MAJOROP;
+		client->requestLogIndex++;
+#endif
+		if (result > (MAX_BIG_REQUEST_SIZE << 2))
+		    result = BadLength;
+		else
+		    result = (* client->requestVector[MAJOROP])(client);
+	    
+		if (result != Success) 
+		{
+		    if (client->noClientException != Success)
+                        CloseDownClient(client);
+                    else
+		        SendErrorToClient(client, MAJOROP,
+					  MinorOpcodeOfRequest(client),
+					  client->errorValue, result);
+		    break;
+	        }
+	    }
+	    FlushAllOutput();
+#ifdef SMART_SCHEDULE
+	    client = clients[clientReady[nready]];
+	    if (client)
+		client->smart_stop_tick = SmartScheduleTime;
+#endif
+	    requestingClient = NULL;
+	}
+	dispatchException &= ~DE_PRIORITYCHANGE;
+
+        /* 
+         * On Darwin we found that the it is not possible
+         * to get the correct keyboard layout unless it is
+         * set on the local machine, before the NX session
+         * is started, by using xmodmap. As we set the key-
+         * board locally, we must prevent the X server to
+         * reset, otherwise we would loose any local confi-
+         * guration. The code below is aimed at this. Note
+         * also that a statically compiled version of xmod-
+         * map is included in the MacOS/X package.
+         */
+
+        #ifdef __DARWIN__
+
+        if (dispatchException & DE_RESET )
+        {
+          dispatchException &= ~DE_RESET;
+
+          dispatchExceptionAtReset = DE_TERMINATE;
+        }
+
+        #endif /* __DARWIN__ */
+
+    }
+    KillAllClients();
+    DEALLOCATE_LOCAL(clientReady);
+    dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+/*ARGSUSED*/
+int
+ProcBadRequest(client)
+    ClientPtr client;
+{
+    return (BadRequest);
+}
+
+int
+ProcCreateWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pParent, pWin;
+    REQUEST(xCreateWindowReq);
+    int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+    
+    LEGAL_NEW_RESOURCE(stuff->wid, client);
+    if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+						    SecurityWriteAccess)))
+        return BadWindow;
+    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+    if (Ones(stuff->mask) != len)
+        return BadLength;
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+			      stuff->y, stuff->width, stuff->height, 
+			      stuff->borderWidth, stuff->class,
+			      stuff->mask, (XID *) &stuff[1], 
+			      (int)stuff->depth, 
+			      client, stuff->visual, &result);
+    if (pWin)
+    {
+	Mask mask = pWin->eventMask;
+
+	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+	    return BadAlloc;
+	pWin->eventMask = mask;
+    }
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcChangeWindowAttributes(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeWindowAttributesReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+    if (len != Ones(stuff->valueMask))
+        return BadLength;
+    result =  ChangeWindowAttributes(pWin, 
+				  stuff->valueMask, 
+				  (XID *) &stuff[1], 
+				  client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcGetWindowAttributes(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+    xGetWindowAttributesReply wa;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    GetWindowAttributes(pWin, client, &wa);
+    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+    return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->parent)
+	FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    DestroySubwindows(pWin, client);
+    return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeSaveSetReq);
+    register int result;
+		  
+    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+        return BadMatch;
+    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+    {
+        result = AlterSaveSetForClient(client, pWin, stuff->mode);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->mode;
+	return( BadValue );
+    }
+}
+
+int
+ProcReparentWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin, pParent;
+    REQUEST(xReparentWindowReq);
+    register int result;
+
+    REQUEST_SIZE_MATCH(xReparentWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+					      SecurityWriteAccess);
+    if (!pParent)
+        return(BadWindow);
+    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+    {
+        if ((pWin->backgroundState == ParentRelative) &&
+            (pParent->drawable.depth != pWin->drawable.depth))
+            return BadMatch;
+	if ((pWin->drawable.class != InputOnly) &&
+	    (pParent->drawable.class == InputOnly))
+	    return BadMatch;
+        result =  ReparentWindow(pWin, pParent, 
+			 (short)stuff->x, (short)stuff->y, client);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else 
+        return (BadMatch);
+}
+
+int
+ProcMapWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapWindow(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapSubwindows(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapWindow(pWin, FALSE);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapSubwindows(pWin);
+    return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xConfigureWindowReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+    if (Ones((Mask)stuff->mask) != len)
+        return BadLength;
+    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
+			      client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcCirculateWindow(client)
+    register ClientPtr client;
+{
+    register WindowPtr pWin;
+    REQUEST(xCirculateWindowReq);
+
+    REQUEST_SIZE_MATCH(xCirculateWindowReq);
+    if ((stuff->direction != RaiseLowest) &&
+	(stuff->direction != LowerHighest))
+    {
+	client->errorValue = stuff->direction;
+        return BadValue;
+    }
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    CirculateWindow(pWin, (int)stuff->direction, client);
+    return(client->noClientException);
+}
+
+int
+GetGeometry(client, rep)
+    register ClientPtr client;
+    xGetGeometryReply *rep;
+{
+    register DrawablePtr pDraw;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+    rep->type = X_Reply;
+    rep->length = 0;
+    rep->sequenceNumber = client->sequence;
+    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+    rep->depth = pDraw->depth;
+    rep->width = pDraw->width;
+    rep->height = pDraw->height;
+
+    /* XXX - Because the pixmap-implementation of the multibuffer extension 
+     *       may have the buffer-id's drawable resource value be a pointer
+     *       to the buffer's window instead of the buffer itself
+     *       (this happens if the buffer is the displayed buffer),
+     *       we also have to check that the id matches before we can
+     *       truly say that it is a DRAWABLE_WINDOW.
+     */
+
+    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+    {
+        register WindowPtr pWin = (WindowPtr)pDraw;
+	rep->x = pWin->origin.x - wBorderWidth (pWin);
+	rep->y = pWin->origin.y - wBorderWidth (pWin);
+	rep->borderWidth = pWin->borderWidth;
+    }
+    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+    {
+	rep->x = rep->y = rep->borderWidth = 0;
+    }
+
+    return Success;
+}
+
+
+int
+ProcGetGeometry(client)
+    register ClientPtr client;
+{
+    xGetGeometryReply rep;
+    int status;
+
+    if ((status = GetGeometry(client, &rep)) != Success)
+	return status;
+
+    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+    return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(client)
+    register ClientPtr client;
+{
+    xQueryTreeReply reply;
+    int numChildren = 0;
+    register WindowPtr pChild, pWin, pHead;
+    Window  *childIDs = (Window *)NULL;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    reply.type = X_Reply;
+    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+    reply.sequenceNumber = client->sequence;
+    if (pWin->parent)
+	reply.parent = pWin->parent->drawable.id;
+    else
+        reply.parent = (Window)None;
+    pHead = RealChildHead(pWin);
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+	numChildren++;
+    if (numChildren)
+    {
+	int curChild = 0;
+
+	childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+	if (!childIDs)
+	    return BadAlloc;
+	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+	    childIDs[curChild++] = pChild->drawable.id;
+    }
+    
+    reply.nChildren = numChildren;
+    reply.length = (numChildren * sizeof(Window)) >> 2;
+    
+    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+    if (numChildren)
+    {
+    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+	DEALLOCATE_LOCAL(childIDs);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcInternAtom(client)
+    register ClientPtr client;
+{
+    Atom atom;
+    char *tchar;
+    REQUEST(xInternAtomReq);
+
+    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+    {
+	client->errorValue = stuff->onlyIfExists;
+        return(BadValue);
+    }
+    tchar = (char *) &stuff[1];
+    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+    if (atom != BAD_RESOURCE)
+    {
+	xInternAtomReply reply;
+	reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+	reply.atom = atom;
+	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+	return(client->noClientException);
+    }
+    else
+	return (BadAlloc);
+}
+
+int
+ProcGetAtomName(client)
+    register ClientPtr client;
+{
+    char *str;
+    xGetAtomNameReply reply;
+    int len;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if ( (str = NameForAtom(stuff->id)) )
+    {
+	len = strlen(str);
+	reply.type = X_Reply;
+	reply.length = (len + 3) >> 2;
+	reply.sequenceNumber = client->sequence;
+	reply.nameLength = len;
+	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+	(void)WriteToClient(client, len, str);
+	return(client->noClientException);
+    }
+    else 
+    { 
+	client->errorValue = stuff->id;
+	return (BadAtom);
+    }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(client)
+    register ClientPtr client;
+{
+    WindowPtr pWin;
+    TimeStamp time;
+    REQUEST(xSetSelectionOwnerReq);
+
+    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+    UpdateCurrentTime();
+    time = ClientTimeToServerTime(stuff->time);
+
+    /* If the client's time stamp is in the future relative to the server's
+	time stamp, do not set the selection, just return success. */
+    if (CompareTimeStamps(time, currentTime) == LATER)
+    	return Success;
+    if (stuff->window != None)
+    {
+        pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					       SecurityReadAccess);
+        if (!pWin)
+            return(BadWindow);
+    }
+    else
+        pWin = (WindowPtr)None;
+    if (ValidAtom(stuff->selection))
+    {
+	int i = 0;
+
+	/*
+	 * First, see if the selection is already set... 
+	 */
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) 
+            i++;
+        if (i < NumCurrentSelections)
+        {        
+	    xEvent event;
+
+	    /* If the timestamp in client's request is in the past relative
+		to the time stamp indicating the last time the owner of the
+		selection was set, do not set the selection, just return 
+		success. */
+            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+		== EARLIER)
+		return Success;
+	    if (CurrentSelections[i].client &&
+		(!pWin || (CurrentSelections[i].client != client)))
+	    {
+		event.u.u.type = SelectionClear;
+		event.u.selectionClear.time = time.milliseconds;
+		event.u.selectionClear.window = CurrentSelections[i].window;
+		event.u.selectionClear.atom = CurrentSelections[i].selection;
+		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+				NoEventMask, NoEventMask /* CantBeFiltered */,
+				NullGrab);
+	    }
+	}
+	else
+	{
+	    /*
+	     * It doesn't exist, so add it...
+	     */
+	    Selection *newsels;
+
+	    if (i == 0)
+		newsels = (Selection *)xalloc(sizeof(Selection));
+	    else
+		newsels = (Selection *)xrealloc(CurrentSelections,
+			    (NumCurrentSelections + 1) * sizeof(Selection));
+	    if (!newsels)
+		return BadAlloc;
+	    NumCurrentSelections++;
+	    CurrentSelections = newsels;
+	    CurrentSelections[i].selection = stuff->selection;
+	}
+        CurrentSelections[i].lastTimeChanged = time;
+	CurrentSelections[i].window = stuff->window;
+	CurrentSelections[i].pWin = pWin;
+	CurrentSelections[i].client = (pWin ? client : NullClient);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->selection;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGetSelectionOwner(client)
+    register ClientPtr client;
+{
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (ValidAtom(stuff->id))
+    {
+	int i;
+        xGetSelectionOwnerReply reply;
+
+	i = 0;
+        while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->id) i++;
+        reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+        if (i < NumCurrentSelections)
+            reply.owner = CurrentSelections[i].window;
+        else
+            reply.owner = None;
+        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+        return(client->noClientException);
+    }
+    else            
+    {
+	client->errorValue = stuff->id;
+        return (BadAtom); 
+    }
+}
+
+int
+ProcConvertSelection(client)
+    register ClientPtr client;
+{
+    Bool paramsOkay;
+    xEvent event;
+    WindowPtr pWin;
+    REQUEST(xConvertSelectionReq);
+
+    REQUEST_SIZE_MATCH(xConvertSelectionReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+    if (stuff->property != None)
+	paramsOkay &= ValidAtom(stuff->property);
+    if (paramsOkay)
+    {
+	int i;
+
+	i = 0;
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) i++;
+	if ((i < NumCurrentSelections) && 
+	    (CurrentSelections[i].window != None)
+#ifdef XCSECURITY
+	    && (!client->CheckAccess ||
+		(* client->CheckAccess)(client, CurrentSelections[i].window,
+					RT_WINDOW, SecurityReadAccess,
+					CurrentSelections[i].pWin))
+#endif
+	    )
+	{        
+	    event.u.u.type = SelectionRequest;
+	    event.u.selectionRequest.time = stuff->time;
+	    event.u.selectionRequest.owner = 
+			CurrentSelections[i].window;
+	    event.u.selectionRequest.requestor = stuff->requestor;
+	    event.u.selectionRequest.selection = stuff->selection;
+	    event.u.selectionRequest.target = stuff->target;
+	    event.u.selectionRequest.property = stuff->property;
+	    if (TryClientEvents(
+		CurrentSelections[i].client, &event, 1, NoEventMask,
+		NoEventMask /* CantBeFiltered */, NullGrab))
+		return (client->noClientException);
+	}
+	event.u.u.type = SelectionNotify;
+	event.u.selectionNotify.time = stuff->time;
+	event.u.selectionNotify.requestor = stuff->requestor;
+	event.u.selectionNotify.selection = stuff->selection;
+	event.u.selectionNotify.target = stuff->target;
+	event.u.selectionNotify.property = None;
+	(void) TryClientEvents(client, &event, 1, NoEventMask,
+			       NoEventMask /* CantBeFiltered */, NullGrab);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->property;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGrabServer(client)
+    register ClientPtr client;
+{
+    REQUEST_SIZE_MATCH(xReq);
+    if (grabState != GrabNone && client != grabClient)
+    {
+	ResetCurrentRequest(client);
+	client->sequence--;
+	BITSET(grabWaiters, client->index);
+	IgnoreClient(client);
+	return(client->noClientException);
+    }
+    OnlyListenToOneClient(client);
+    grabState = GrabKickout;
+    grabClient = client;
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_GRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+
+    return(client->noClientException);
+}
+
+static void
+#if NeedFunctionPrototypes
+UngrabServer(ClientPtr client)
+#else
+UngrabServer(client)
+    ClientPtr client;
+#endif
+{
+    int i;
+
+    grabState = GrabNone;
+    ListenToAllClients();
+    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+	;
+    if (i >= 0)
+    {
+	i <<= 5;
+	while (!GETBIT(grabWaiters, i))
+	    i++;
+	BITCLEAR(grabWaiters, i);
+	AttendClient(clients[i]);
+    }
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_UNGRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+}
+
+int
+ProcUngrabServer(client)
+    register ClientPtr client;
+{
+    REQUEST_SIZE_MATCH(xReq);
+    UngrabServer(client);
+    return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(client)
+    register ClientPtr client;
+{
+    REQUEST(xTranslateCoordsReq);
+
+    register WindowPtr pWin, pDst;
+    xTranslateCoordsReply rep;
+
+    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+					   SecurityReadAccess);
+    if (!pDst)
+        return(BadWindow);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+    {
+	rep.sameScreen = xFalse;
+        rep.child = None;
+	rep.dstX = rep.dstY = 0;
+    }
+    else
+    {
+	INT16 x, y;
+	rep.sameScreen = xTrue;
+	rep.child = None;
+	/* computing absolute coordinates -- adjust to destination later */
+	x = pWin->drawable.x + stuff->srcX;
+	y = pWin->drawable.y + stuff->srcY;
+	pWin = pDst->firstChild;
+	while (pWin)
+	{
+#ifdef SHAPE
+	    BoxRec  box;
+#endif
+	    if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		 wBorderWidth (pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		 wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen, 
+					&pWin->borderSize, x, y, &box))
+#endif
+		)
+            {
+		rep.child = pWin->drawable.id;
+		pWin = (WindowPtr) NULL;
+	    }
+	    else
+		pWin = pWin->nextSib;
+	}
+	/* adjust to destination coordinates */
+	rep.dstX = x - pDst->drawable.x;
+	rep.dstY = y - pDst->drawable.y;
+    }
+    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+    return(client->noClientException);
+}
+
+int
+ProcOpenFont(client)
+    register ClientPtr client;
+{
+    int	err;
+    REQUEST(xOpenFontReq);
+
+    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+    client->errorValue = stuff->fid;
+    LEGAL_NEW_RESOURCE(stuff->fid, client);
+    err = OpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcCloseFont(client)
+    register ClientPtr client;
+{
+    FontPtr pFont;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityDestroyAccess);
+    if ( pFont != (FontPtr)NULL)	/* id was valid */
+    {
+        FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+        return (BadFont);
+    }
+}
+
+int
+ProcQueryFont(client)
+    register ClientPtr client;
+{
+    xQueryFontReply	*reply;
+    FontPtr pFont;
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    client->errorValue = stuff->id;		/* EITHER font or gc */
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+	  /* can't use VERIFY_GC because it might return BadGC */
+	pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+					    SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->id;
+            return(BadFont);     /* procotol spec says only error is BadFont */
+	}
+	pFont = pGC->font;
+    }
+
+    {
+	xCharInfo	*pmax = FONTINKMAX(pFont);
+	xCharInfo	*pmin = FONTINKMIN(pFont);
+	int		nprotoxcistructs;
+	int		rlength;
+
+	nprotoxcistructs = (
+	   pmax->rightSideBearing == pmin->rightSideBearing &&
+	   pmax->leftSideBearing == pmin->leftSideBearing &&
+	   pmax->descent == pmin->descent &&
+	   pmax->ascent == pmin->ascent &&
+	   pmax->characterWidth == pmin->characterWidth) ?
+		0 : N2dChars(pFont);
+
+	rlength = sizeof(xQueryFontReply) +
+	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
+		     nprotoxcistructs * sizeof(xCharInfo);
+	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+	if(!reply)
+	{
+	    return(BadAlloc);
+	}
+
+	reply->type = X_Reply;
+	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+	reply->sequenceNumber = client->sequence;
+	QueryFont( pFont, reply, nprotoxcistructs);
+
+        WriteReplyToClient(client, rlength, reply);
+	DEALLOCATE_LOCAL(reply);
+	return(client->noClientException);
+    }
+}
+
+int
+ProcQueryTextExtents(client)
+    register ClientPtr client;
+{
+    REQUEST(xQueryTextExtentsReq);
+    xQueryTextExtentsReply reply;
+    FontPtr pFont;
+    GC *pGC;
+    ExtentInfoRec info;
+    unsigned long length;
+
+    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+        
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+					   SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->fid;
+            return(BadFont);
+	}
+	pFont = pGC->font;
+    }
+    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+    length = length << 1;
+    if (stuff->oddLength)
+    {
+	if (length == 0)
+	    return(BadLength);
+        length--;
+    }
+    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+	return(BadAlloc);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.drawDirection = info.drawDirection;
+    reply.fontAscent = info.fontAscent;
+    reply.fontDescent = info.fontDescent;
+    reply.overallAscent = info.overallAscent;
+    reply.overallDescent = info.overallDescent;
+    reply.overallWidth = info.overallWidth;
+    reply.overallLeft = info.overallLeft;
+    reply.overallRight = info.overallRight;
+    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListFonts(client)
+    register ClientPtr client;
+{
+    REQUEST(xListFontsReq);
+
+    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+
+    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
+	stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(client)
+    register ClientPtr client;
+{
+    REQUEST(xListFontsWithInfoReq);
+
+    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+    return StartListFontsWithInfo(client, stuff->nbytes,
+				  (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/*ARGSUSED*/
+int
+dixDestroyPixmap(value, pid)
+    pointer value; /* must conform to DeleteType */
+    XID pid;
+{
+    PixmapPtr pPixmap = (PixmapPtr)value;
+    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    REQUEST(xCreatePixmapReq);
+    DepthPtr pDepth;
+    register int i;
+
+    REQUEST_SIZE_MATCH(xCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+		(pDraw->pScreen, stuff->width,
+		 stuff->height, stuff->depth);
+    if (pMap)
+    {
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	    return(client->noClientException);
+    }
+    return (BadAlloc);
+}
+
+int
+ProcFreePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+					     SecurityDestroyAccess);
+    if (pMap) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadPixmap);
+    }
+}
+
+int
+ProcCreateGC(client)
+    register ClientPtr client;
+{
+    int error;
+    GC *pGC;
+    register DrawablePtr pDraw;
+    unsigned len;
+    REQUEST(xCreateGCReq);
+
+    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+    client->errorValue = stuff->gc;
+    LEGAL_NEW_RESOURCE(stuff->gc, client);
+    SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+			      SecurityReadAccess);
+    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+    pGC = (GC *)CreateGC(pDraw, stuff->mask, 
+			 (XID *) &stuff[1], &error);
+    if (error != Success)
+        return error;
+    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+	return (BadAlloc);
+    return(client->noClientException);
+}
+
+int
+ProcChangeGC(client)
+    register ClientPtr client;
+{
+    GC *pGC;
+    REQUEST(xChangeGCReq);
+    int result;
+    unsigned len;
+		
+    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+    SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+
+    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcCopyGC(client)
+    register ClientPtr client;
+{
+    register GC *dstGC;
+    register GC *pGC;
+    int result;
+    REQUEST(xCopyGCReq);
+
+    REQUEST_SIZE_MATCH(xCopyGCReq);
+    SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+    SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+        return (BadMatch);    
+    result = CopyGC(pGC, dstGC, stuff->mask);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetDashes(client)
+    register ClientPtr client;
+{
+    register GC *pGC;
+    int result;
+    REQUEST(xSetDashesReq);
+
+    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+    if (stuff->nDashes == 0)
+    {
+	 client->errorValue = 0;
+         return BadValue;
+    }
+
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+		       (unsigned char *)&stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetClipRectangles(client)
+    register ClientPtr client;
+{
+    int	nr;
+    int result;
+    register GC *pGC;
+    REQUEST(xSetClipRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+    {
+	client->errorValue = stuff->ordering;
+        return BadValue;
+    }
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+		 
+    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+    if (nr & 4)
+	return(BadLength);
+    nr >>= 3;
+    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcFreeGC(client)
+    register ClientPtr client;
+{
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+    FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcClearToBackground(client)
+    register ClientPtr client;
+{
+    REQUEST(xClearAreaReq);
+    register WindowPtr pWin;
+
+    REQUEST_SIZE_MATCH(xClearAreaReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->drawable.class == InputOnly)
+    {
+	client->errorValue = stuff->window;
+	return (BadMatch);
+    }		    
+    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+    {
+	client->errorValue = stuff->exposures;
+        return(BadValue);
+    }
+    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+			       stuff->width, stuff->height,
+			       (Bool)stuff->exposures);
+    return(client->noClientException);
+}
+
+int
+ProcCopyArea(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDst;
+    register DrawablePtr pSrc;
+    register GC *pGC;
+    REQUEST(xCopyAreaReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        pSrc = pDst;
+
+    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY);
+    if (pGC->graphicsExposures)
+    {
+	(*pDst->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+	if (pRgn)
+	    REGION_DESTROY(pDst->pScreen, pRgn);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcCopyPlane(client)
+    register ClientPtr client;
+{
+    register DrawablePtr psrcDraw, pdstDraw;
+    register GC *pGC;
+    REQUEST(xCopyPlaneReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if (pdstDraw->pScreen != psrcDraw->pScreen)
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        psrcDraw = pdstDraw;
+
+    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+    {
+       client->errorValue = stuff->bitPlane;
+       return(BadValue);
+    }
+
+    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY, stuff->bitPlane);
+    if (pGC->graphicsExposures)
+    {
+	(*pdstDraw->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+	if (pRgn)
+	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyPoint(client)
+    register ClientPtr client;
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyPointReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
+    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+    if (npoint)
+        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+			  (xPoint *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcPolyLine(client)
+    register ClientPtr client;
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyLineReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+    if (npoint > 1)
+	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
+			      (DDXPointPtr) &stuff[1]);
+    return(client->noClientException);
+}
+
+int
+ProcPolySegment(client)
+    register ClientPtr client;
+{
+    int nsegs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolySegmentReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+    if (nsegs & 4)
+	return(BadLength);
+    nsegs >>= 3;
+    if (nsegs)
+        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (client)
+    register ClientPtr client;
+{
+    int nrects;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+    if (nrects & 4)
+	return(BadLength);
+    nrects >>= 3;
+    if (nrects)
+        (*pGC->ops->PolyRectangle)(pDraw, pGC, 
+		    nrects, (xRectangle *) &stuff[1]);
+    return(client->noClientException);
+}
+
+int
+ProcPolyArc(client)
+    register ClientPtr client;
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcFillPoly(client)
+    register ClientPtr client;
+{
+    int          things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xFillPolyReq);
+
+    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
+	(stuff->shape != Convex))
+    {
+	client->errorValue = stuff->shape;
+        return BadValue;
+    }
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+    if (things)
+        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+			 stuff->coordMode, things,
+			 (DDXPointPtr) &stuff[1]);
+    return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(client)
+    register ClientPtr client;
+{
+    int             things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+
+    if (things)
+        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+		      (xRectangle *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(client)
+    register ClientPtr client;
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+    int	    whichbyte = 1;
+
+    if (*((char *) &whichbyte))
+	return LSBFirst;
+    return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+    switch (bpp) {
+    case 1:	/* yuck */
+	if (BITMAP_BIT_ORDER != order)
+	    BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+	break;
+    case 4:
+	break;  /* yuck */
+    case 8:
+	break;
+    case 16:
+	if (IMAGE_BYTE_ORDER != order)
+	    TwoByteSwap ((unsigned char *) base, nbytes);
+	break;
+    case 32:
+	if (IMAGE_BYTE_ORDER != order)
+	    FourByteSwap ((unsigned char *) base, nbytes);
+	break;
+    }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(client)
+    register ClientPtr client;
+{
+    register	GC *pGC;
+    register	DrawablePtr pDraw;
+    long	length; 	/* length of scanline server padded */
+    long 	lengthProto; 	/* length of scanline protocol padded */
+    char	*tmpImage;
+    REQUEST(xPutImageReq);
+
+    REQUEST_AT_LEAST_SIZE(xPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    if (stuff->format == XYBitmap)
+    {
+        if ((stuff->depth != 1) ||
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || 
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length      = BitmapBytePad(stuff->width + stuff->leftPad);
+	length      *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+            return BadMatch;
+        length      = PixmapBytePad(stuff->width, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    tmpImage = (char *)&stuff[1];
+    lengthProto = length;
+	
+    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 
+	(sizeof(xPutImageReq) >> 2)) != client->req_len)
+	return BadLength;
+
+    ReformatImage (tmpImage, lengthProto * stuff->height, 
+		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+		   ClientOrder(client));
+    
+    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+		  stuff->width, stuff->height, 
+		  stuff->leftPad, stuff->format, tmpImage);
+
+     return (client->noClientException);
+}
+
+
+int
+DoGetImage(client, format, drawable, x, y, width, height, planemask, im_return)
+    register ClientPtr	client;
+    Drawable drawable;
+    int format;
+    int x, y, width, height;
+    Mask planemask;
+    xGetImageReply **im_return;
+{
+    register DrawablePtr pDraw;
+    int			nlines, linesPerBuf;
+    register int	linesDone;
+    long		widthBytesLine, length;
+    Mask		plane = 0;
+    char		*pBuf;
+    xGetImageReply	xgi;
+    RegionPtr pVisibleRegion = NULL;
+
+    if ((format != XYPixmap) && (format != ZPixmap))
+    {
+	client->errorValue = format;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+    if(pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + x < 0 ||
+ 	 pDraw->x + x + width > pDraw->pScreen->width ||
+         pDraw->y + y < 0 ||
+         pDraw->y + y + height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         x < - wBorderWidth((WindowPtr)pDraw) ||
+         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         y < -wBorderWidth((WindowPtr)pDraw) ||
+         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual (((WindowPtr) pDraw));
+    }
+    else
+    {
+      if(x < 0 ||
+         x+width > (int)pDraw->width ||
+         y < 0 ||
+         y+height > (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+
+    SET_DBE_SRCBUF(pDraw, drawable);
+
+    xgi.type = X_Reply;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(format == ZPixmap)
+    {
+	widthBytesLine = PixmapBytePad(width, pDraw->depth);
+	length = widthBytesLine * height;
+
+    }
+    else 
+    {
+	widthBytesLine = BitmapBytePad(width);
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = widthBytesLine * height *
+		 Ones(planemask & (plane | (plane - 1)));
+
+    }
+
+    xgi.length = length;
+
+    if (im_return) {
+	pBuf = (char *)xalloc(sz_xGetImageReply + length);
+	if (!pBuf)
+	    return (BadAlloc);
+	if (widthBytesLine == 0)
+	    linesPerBuf = 0;
+	else
+	    linesPerBuf = height;
+	*im_return = (xGetImageReply *)pBuf;
+	*(xGetImageReply *)pBuf = xgi;
+	pBuf += sz_xGetImageReply;
+    } else {
+	xgi.length = (xgi.length + 3) >> 2;
+	if (widthBytesLine == 0 || height == 0)
+	    linesPerBuf = 0;
+	else if (widthBytesLine >= IMAGE_BUFSIZE)
+	    linesPerBuf = 1;
+	else
+	{
+	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+	    if (linesPerBuf > height)
+		linesPerBuf = height;
+	}
+	length = linesPerBuf * widthBytesLine;
+	if (linesPerBuf < height)
+	{
+	    /* we have to make sure intermediate buffers don't need padding */
+	    while ((linesPerBuf > 1) &&
+		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+	    {
+		linesPerBuf--;
+		length -= widthBytesLine;
+	    }
+	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+	    {
+		linesPerBuf++;
+		length += widthBytesLine;
+	    }
+	}
+	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+	    return (BadAlloc);
+	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+    }
+
+#ifdef XCSECURITY
+    if (client->trustLevel != XSecurityClientTrusted &&
+	pDraw->type == DRAWABLE_WINDOW)
+    {
+	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+	if (pVisibleRegion)
+	{
+	    REGION_TRANSLATE(pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+	}
+    }
+#endif
+
+    if (linesPerBuf == 0)
+    {
+	/* nothing to do */
+    }
+    else if (format == ZPixmap)
+    {
+        linesDone = 0;
+        while (height - linesDone > 0)
+        {
+	    nlines = min(linesPerBuf, height - linesDone);
+	    (*pDraw->pScreen->GetImage) (pDraw,
+	                                 x,
+				         y + linesDone,
+				         width, 
+				         nlines,
+				         format,
+				         planemask,
+				         (pointer) pBuf);
+#ifdef XCSECURITY
+	    if (pVisibleRegion)
+		SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+			pDraw, x, y + linesDone, width, 
+			nlines, format, pBuf);
+#endif
+
+	    /* Note that this is NOT a call to WriteSwappedDataToClient,
+               as we do NOT byte swap */
+	    if (!im_return)
+	    {
+		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+			       BitsPerPixel (pDraw->depth),
+			       ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+		(void)WriteToClient(client,
+				    (int)(nlines * widthBytesLine),
+				    pBuf);
+	    }
+	    linesDone += nlines;
+        }
+    }
+    else /* XYPixmap */
+    {
+        for (; plane; plane >>= 1)
+	{
+	    if (planemask & plane)
+	    {
+	        linesDone = 0;
+	        while (height - linesDone > 0)
+	        {
+		    nlines = min(linesPerBuf, height - linesDone);
+	            (*pDraw->pScreen->GetImage) (pDraw,
+	                                         x,
+				                 y + linesDone,
+				                 width, 
+				                 nlines,
+				                 format,
+				                 plane,
+				                 (pointer)pBuf);
+#ifdef XCSECURITY
+		    if (pVisibleRegion)
+			SecurityCensorImage(client, pVisibleRegion,
+				widthBytesLine,
+				pDraw, x, y + linesDone, width, 
+				nlines, format, pBuf);
+#endif
+
+		    /* Note: NOT a call to WriteSwappedDataToClient,
+		       as we do NOT byte swap */
+		    if (im_return) {
+			pBuf += nlines * widthBytesLine;
+		    } else {
+			ReformatImage (pBuf, 
+				       (int)(nlines * widthBytesLine), 
+				       1,
+				       ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+			(void)WriteToClient(client,
+					(int)(nlines * widthBytesLine),
+					pBuf);
+		    }
+		    linesDone += nlines;
+		}
+            }
+	}
+    }
+#ifdef XCSECURITY
+    if (pVisibleRegion)
+	REGION_DESTROY(pScreen, pVisibleRegion);
+#endif
+    if (!im_return)
+	DEALLOCATE_LOCAL(pBuf);
+    return (client->noClientException);
+}
+
+int
+ProcGetImage(client)
+    register ClientPtr	client;
+{
+    REQUEST(xGetImageReq);
+
+    REQUEST_SIZE_MATCH(xGetImageReq);
+
+    return DoGetImage(client, stuff->format, stuff->drawable,
+		      stuff->x, stuff->y,
+		      (int)stuff->width, (int)stuff->height,
+		      stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(client)
+    register ClientPtr client;
+{
+    int	err;
+    REQUEST(xPolyTextReq);
+    DrawablePtr pDraw;
+    GC *pGC;
+
+    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = PolyText(client,
+		   pDraw,
+		   pGC,
+		   (unsigned char *)&stuff[1],
+		   ((unsigned char *) stuff) + (client->req_len << 2),
+		   stuff->x,
+		   stuff->y,
+		   stuff->reqType,
+		   stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText8(client)
+    register ClientPtr client;
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText16(client)
+    register ClientPtr client;
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+
+int
+ProcCreateColormap(client)
+    register ClientPtr client;
+{
+    VisualPtr	pVisual;
+    ColormapPtr	pmap;
+    Colormap	mid;
+    register WindowPtr   pWin;
+    ScreenPtr pScreen;
+    REQUEST(xCreateColormapReq);
+    int i, result;
+
+    REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+    {
+	client->errorValue = stuff->alloc;
+        return(BadValue);
+    }
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pScreen = pWin->drawable.pScreen;
+    for (i = 0, pVisual = pScreen->visuals;
+	 i < pScreen->numVisuals;
+	 i++, pVisual++)
+    {
+	if (pVisual->vid != stuff->visual)
+	    continue;
+	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
+				 (int)stuff->alloc, client->index);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+	    return(result);
+    }
+    client->errorValue = stuff->visual;
+    return(BadValue);
+}
+
+int
+ProcFreeColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pmap;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+						SecurityDestroyAccess);
+    if (pmap) 
+    {
+	/* Freeing a default colormap is a no-op */
+	if (!(pmap->flags & IsDefault))
+	    FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadColor);
+    }
+}
+
+
+int
+ProcCopyColormapAndFree(client)
+    register ClientPtr client;
+{
+    Colormap	mid;
+    ColormapPtr	pSrcMap;
+    REQUEST(xCopyColormapAndFreeReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client,	stuff->srcCmap,
+		RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+    {
+	result = CopyColormapAndFree(mid, pSrcMap, client->index);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->srcCmap;
+	return(BadColor);
+    }
+}
+
+int
+ProcInstallColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					    RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+        (*(pcmp->pScreen->InstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcUninstallColormap(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	if(pcmp->mid != pcmp->pScreen->defColormap)
+            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcListInstalledColormaps(client)
+    register ClientPtr client;
+{
+    xListInstalledColormapsReply *preply; 
+    int nummaps;
+    WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+
+    if (!pWin)
+        return(BadWindow);
+
+    preply = (xListInstalledColormapsReply *) 
+		ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+		     pWin->drawable.pScreen->maxInstalledCmaps *
+		     sizeof(Colormap));
+    if(!preply)
+        return(BadAlloc);
+
+    preply->type = X_Reply;
+    preply->sequenceNumber = client->sequence;
+    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+    preply->nColormaps = nummaps;
+    preply->length = nummaps;
+    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+    DEALLOCATE_LOCAL(preply);
+    return(client->noClientException);
+}
+
+int
+ProcAllocColor(client)
+    register ClientPtr client;
+{
+    ColormapPtr pmap;
+    int	retval;
+    xAllocColorReply acr;
+    REQUEST(xAllocColorReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorReq);
+    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pmap)
+    {
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+	    return Success;
+#endif
+	acr.type = X_Reply;
+	acr.length = 0;
+	acr.sequenceNumber = client->sequence;
+	acr.red = stuff->red;
+	acr.green = stuff->green;
+	acr.blue = stuff->blue;
+	acr.pixel = 0;
+	if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+	                       &acr.pixel, client->index)) )
+	{
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return (retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+	return (client->noClientException);
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocNamedColor           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					    RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int		retval;
+
+	xAllocNamedColorReply ancr;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocNamedColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	ancr.type = X_Reply;
+	ancr.length = 0;
+	ancr.sequenceNumber = client->sequence;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+	{
+	    ancr.screenRed = ancr.exactRed;
+	    ancr.screenGreen = ancr.exactGreen;
+	    ancr.screenBlue = ancr.exactBlue;
+	    ancr.pixel = 0;
+	    if( (retval = AllocColor(pcmp,
+	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+			 &ancr.pixel, client->index)) )
+	    {
+                if (client->noClientException != Success)
+                    return(client->noClientException);
+                else
+    	            return(retval);
+	    }
+#ifdef PANORAMIX
+	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+	    return (client->noClientException);
+	}
+	else
+	    return(BadName);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorCells           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorCellsReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorCellsReply	accr;
+	int			npixels, nmasks, retval;
+	long			length;
+	Pixel			*ppixels, *pmasks;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorCells request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	nmasks = stuff->planes;
+	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	pmasks = ppixels + npixels;
+
+	if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 
+				    (Bool)stuff->contiguous, ppixels, pmasks)) )
+	{
+	    DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    accr.type = X_Reply;
+	    accr.length = length >> 2;
+	    accr.sequenceNumber = client->sequence;
+	    accr.nPixels = npixels;
+	    accr.nMasks = nmasks;
+	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorPlanes(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorPlanesReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorPlanesReply	acpr;
+	int			npixels, retval;
+	long			length;
+	Pixel			*ppixels;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorPlanes request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	acpr.type = X_Reply;
+	acpr.sequenceNumber = client->sequence;
+	acpr.nPixels = npixels;
+	length = (long)npixels * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+	    (Bool)stuff->contiguous, ppixels,
+	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+	{
+            DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+	acpr.length = length >> 2;
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcFreeColors          (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xFreeColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+	if(pcmp->flags & AllAllocated)
+	    return(BadAccess);
+	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+	retval =  FreeColors(pcmp, client->index, count,
+	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreColors               (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+	if (count % sizeof(xColorItem))
+	    return(BadLength);
+	count /= sizeof(xColorItem);
+	retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreNamedColor           (client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xColorItem	def;
+        int             retval;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+	                 stuff->nbytes, &def.red, &def.green, &def.blue))
+	{
+	    def.flags = stuff->flags;
+	    def.pixel = stuff->pixel;
+	    retval = StoreColors(pcmp, 1, &def);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+		return(retval);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcQueryColors(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xQueryColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	int			count, retval;
+	xrgb 			*prgbs;
+	xQueryColorsReply	qcr;
+
+	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+	prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+	if(!prgbs && count)
+            return(BadAlloc);
+	if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+	{
+   	    if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	    if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	    {
+		client->errorValue = clientErrorValue;
+	        return (retval);
+	    }
+	}
+	qcr.type = X_Reply;
+	qcr.length = (count * sizeof(xrgb)) >> 2;
+	qcr.sequenceNumber = client->sequence;
+	qcr.nColors = count;
+	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+	if (count)
+	{
+	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+	}
+	if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	return(client->noClientException);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+} 
+
+int
+ProcLookupColor(client)
+    register ClientPtr client;
+{
+    ColormapPtr pcmp;
+    REQUEST(xLookupColorReq);
+
+    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	xLookupColorReply lcr;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+	{
+	    lcr.type = X_Reply;
+	    lcr.length = 0;
+	    lcr.sequenceNumber = client->sequence;
+	    lcr.screenRed = lcr.exactRed;
+	    lcr.screenGreen = lcr.exactGreen;
+	    lcr.screenBlue = lcr.exactBlue;
+	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+	                                   &lcr.screenGreen,
+					   &lcr.screenBlue,
+					   pcmp->pVisual);
+	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+	    return(client->noClientException);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcCreateCursor( client)
+    register ClientPtr client;
+{
+    CursorPtr	pCursor;
+
+    register PixmapPtr 	src;
+    register PixmapPtr 	msk;
+    unsigned char *	srcbits;
+    unsigned char *	mskbits;
+    unsigned short	width, height;
+    long		n;
+    CursorMetricRec cm;
+
+
+    REQUEST(xCreateCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+					      RT_PIXMAP, SecurityReadAccess);
+    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+					      RT_PIXMAP, SecurityReadAccess);
+    if (   src == (PixmapPtr)NULL)
+    {
+	client->errorValue = stuff->source;
+	return (BadPixmap);
+    }
+    if ( msk == (PixmapPtr)NULL)
+    {
+	if (stuff->mask != None)
+	{
+	    client->errorValue = stuff->mask;
+	    return (BadPixmap);
+	}
+    }
+    else if (  src->drawable.width != msk->drawable.width
+	    || src->drawable.height != msk->drawable.height
+	    || src->drawable.depth != 1
+	    || msk->drawable.depth != 1)
+	return (BadMatch);
+
+    width = src->drawable.width;
+    height = src->drawable.height;
+
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+
+    n = BitmapBytePad(width)*height;
+    srcbits = (unsigned char *)xalloc(n);
+    if (!srcbits)
+	return (BadAlloc);
+    mskbits = (unsigned char *)xalloc(n);
+    if (!mskbits)
+    {
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+
+    /* zeroing the (pad) bits helps some ddx cursor handling */
+    bzero((char *)srcbits, n);
+    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+					 XYPixmap, 1, (pointer)srcbits);
+    if ( msk == (PixmapPtr)NULL)
+    {
+	register unsigned char *bits = mskbits;
+	while (--n >= 0)
+	    *bits++ = ~0;
+    }
+    else
+    {
+	/* zeroing the (pad) bits helps some ddx cursor handling */
+	bzero((char *)mskbits, n);
+	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+					height, XYPixmap, 1, (pointer)mskbits);
+    }
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursor( srcbits, mskbits, &cm,
+	    stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+	    stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	    return (client->noClientException);
+    return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor( client)
+    register ClientPtr client;
+{
+    CursorPtr pCursor;
+    int res;
+
+    REQUEST(xCreateGlyphCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+			   stuff->mask, stuff->maskChar,
+			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+			   stuff->backRed, stuff->backGreen, stuff->backBlue,
+			   &pCursor, client);
+    if (res != Success)
+	return res;
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+
+int
+ProcFreeCursor(client)
+    register ClientPtr client;
+{
+    CursorPtr pCursor;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_CURSOR, SecurityDestroyAccess);
+    if (pCursor) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadCursor);
+    }
+}
+
+int
+ProcQueryBestSize   (client)
+    register ClientPtr client;
+{
+    xQueryBestSizeReply	reply;
+    register DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    REQUEST(xQueryBestSizeReq);
+
+    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+    if ((stuff->class != CursorShape) && 
+	(stuff->class != TileShape) && 
+	(stuff->class != StippleShape))
+    {
+	client->errorValue = stuff->class;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+	return (BadMatch);
+    pScreen = pDraw->pScreen;
+    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+			       &stuff->height, pScreen);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.width = stuff->width;
+    reply.height = stuff->height;
+    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+    return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver            (client)
+    register ClientPtr client;
+{
+    int blankingOption, exposureOption;
+    REQUEST(xSetScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+    blankingOption = stuff->preferBlank;
+    if ((blankingOption != DontPreferBlanking) &&
+        (blankingOption != PreferBlanking) &&
+        (blankingOption != DefaultBlanking))
+    {
+	client->errorValue = blankingOption;
+        return BadValue;
+    }
+    exposureOption = stuff->allowExpose;
+    if ((exposureOption != DontAllowExposures) &&
+        (exposureOption != AllowExposures) &&
+        (exposureOption != DefaultExposures))
+    {
+	client->errorValue = exposureOption;
+        return BadValue;
+    }
+    if (stuff->timeout < -1)
+    {
+	client->errorValue = stuff->timeout;
+        return BadValue;
+    }
+    if (stuff->interval < -1)
+    {
+	client->errorValue = stuff->interval;
+        return BadValue;
+    }
+
+    if (blankingOption == DefaultBlanking)
+	ScreenSaverBlanking = defaultScreenSaverBlanking;
+    else
+	ScreenSaverBlanking = blankingOption; 
+    if (exposureOption == DefaultExposures)
+	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+    else
+	ScreenSaverAllowExposures = exposureOption;
+
+    if (stuff->timeout >= 0)
+	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+    else 
+	ScreenSaverTime = defaultScreenSaverTime;
+    if (stuff->interval >= 0)
+	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+    else
+	ScreenSaverInterval = defaultScreenSaverInterval;
+    return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(client)
+    register ClientPtr client;
+{
+    xGetScreenSaverReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+    rep.preferBlanking = ScreenSaverBlanking;
+    rep.allowExposures = ScreenSaverAllowExposures;
+    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+    return (client->noClientException);
+}
+
+int
+ProcChangeHosts(client)
+    register ClientPtr client;
+{
+    REQUEST(xChangeHostsReq);
+    int result;
+
+    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+    if(stuff->mode == HostInsert)
+	result = AddHost(client, (int)stuff->hostFamily,
+			 stuff->hostLength, (pointer)&stuff[1]);
+    else if (stuff->mode == HostDelete)
+	result = RemoveHost(client, (int)stuff->hostFamily, 
+			    stuff->hostLength, (pointer)&stuff[1]);  
+    else
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcListHosts(client)
+    register ClientPtr client;
+{
+    xListHostsReply reply;
+    int	len, nHosts, result;
+    pointer	pdata;
+    /* REQUEST(xListHostsReq); */
+
+    REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+    /* untrusted clients can't list hosts */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	SecurityAudit("client %d attempted to list hosts\n", client->index);
+	return BadAccess;
+    }
+#endif
+    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+    if (result != Success)
+	return(result);
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.nHosts = nHosts;
+    reply.length = len >> 2;
+    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+    if (nHosts)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+	WriteSwappedDataToClient(client, len, pdata);
+    }
+    xfree(pdata);
+    return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(client)
+    register ClientPtr client;
+{
+    int result;
+    REQUEST(xSetAccessControlReq);
+
+    REQUEST_SIZE_MATCH(xSetAccessControlReq);
+    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcKillClient(client)
+    register ClientPtr client;
+{
+    REQUEST(xResourceReq);
+    ClientPtr	killclient;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (stuff->id == AllTemporary)
+    {
+	CloseDownRetainedResources();
+        return (client->noClientException);
+    }
+
+    if ((killclient = LookupClient(stuff->id, client)))
+    {
+	CloseDownClient(killclient);
+	/* if an LBX proxy gets killed, isItTimeToYield will be set */
+	if (isItTimeToYield || (client == killclient))
+	{
+	    /* force yield and return Success, so that Dispatch()
+	     * doesn't try to touch client
+	     */
+	    isItTimeToYield = TRUE;
+	    return (Success);
+	}
+	return (client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+	return (BadValue);
+    }
+}
+
+int
+ProcSetFontPath(client)
+    register ClientPtr client;
+{
+    unsigned char *ptr;
+    unsigned long nbytes, total;
+    long nfonts;
+    int n, result;
+    int error;
+    REQUEST(xSetFontPathReq);
+    
+    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+    
+    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+    total = nbytes;
+    ptr = (unsigned char *)&stuff[1];
+    nfonts = stuff->nFonts;
+    while (--nfonts >= 0)
+    {
+	if ((total == 0) || (total < (n = (*ptr + 1))))
+	    return(BadLength);
+	total -= n;
+	ptr += n;
+    }
+    if (total >= 4)
+	return(BadLength);
+    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+			 &error);
+    if (!result)
+    {
+	result = client->noClientException;
+	client->errorValue = error;
+    }
+    return (result);
+}
+
+int
+ProcGetFontPath(client)
+    register ClientPtr client;
+{
+    xGetFontPathReply reply;
+    int stringLens, numpaths;
+    unsigned char *bufferStart;
+    /* REQUEST (xReq); */
+
+    REQUEST_SIZE_MATCH(xReq);
+    bufferStart = GetFontPath(&numpaths, &stringLens);
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = (stringLens + numpaths + 3) >> 2;
+    reply.nPaths = numpaths;
+
+    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+    if (stringLens || numpaths)
+	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+    return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(client)
+    register ClientPtr client;
+{
+    REQUEST(xSetCloseDownModeReq);
+
+    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+    if ((stuff->mode == AllTemporary) ||
+	(stuff->mode == RetainPermanent) ||
+	(stuff->mode == RetainTemporary))
+    {
+	client->closeDownMode = stuff->mode;
+	return (client->noClientException);
+    }
+    else   
+    {
+	client->errorValue = stuff->mode;
+	return (BadValue);
+    }
+}
+
+int ProcForceScreenSaver(client)
+    register ClientPtr client;
+{    
+    REQUEST(xForceScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+    
+    if ((stuff->mode != ScreenSaverReset) && 
+	(stuff->mode != ScreenSaverActive))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+    return client->noClientException;
+}
+
+int ProcNoOperation(client)
+    register ClientPtr client;
+{
+    REQUEST_AT_LEAST_SIZE(xReq);
+    
+    /* noop -- don't do anything */
+    return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+    int i;
+    for (i = 0; i<256; i++)
+    {
+	if(!ProcVector[i])
+	{
+            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+	    ReplySwapVector[i] = ReplyNotSwappd;
+	}
+#ifdef K5AUTH
+	if (!k5_Vector[i])
+	{
+	    k5_Vector[i] = k5_bad;
+	}
+#endif
+    }
+    for(i = LASTEvent; i < 128; i++)
+    {
+	EventSwapVector[i] = NotImplemented;
+    }
+    
+}
+
+/**********************
+ * CloseDownClient
+ *
+ *  Client can either mark his resources destroy or retain.  If retained and
+ *  then killed again, the client is really destroyed.
+ *********************/
+
+char dispatchExceptionAtReset = DE_RESET;
+
+void
+CloseDownClient(client)
+    register ClientPtr client;
+{
+    Bool really_close_down = client->clientGone ||
+			     client->closeDownMode == DestroyAll;
+
+    if (!client->clientGone)
+    {
+	/* ungrab server if grabbing client dies */
+	if (grabState != GrabNone && grabClient == client)
+	{
+	    UngrabServer(client);
+	}
+	BITCLEAR(grabWaiters, client->index);
+	DeleteClientFromAnySelections(client);
+	ReleaseActiveGrabs(client);
+	DeleteClientFontStuff(client);
+	if (!really_close_down)
+	{
+	    /*  This frees resources that should never be retained
+	     *  no matter what the close down mode is.  Actually we
+	     *  could do this unconditionally, but it's probably
+	     *  better not to traverse all the client's resources
+	     *  twice (once here, once a few lines down in
+	     *  FreeClientResources) in the common case of
+	     *  really_close_down == TRUE.
+	     */
+	    FreeClientNeverRetainResources(client);
+	    client->clientState = ClientStateRetained;
+  	    if (ClientStateCallback)
+            {
+		NewClientInfoRec clientinfo;
+
+		clientinfo.client = client; 
+		clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+		clientinfo.setup = (xConnSetup *) NULL;
+		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+            } 
+	}
+	client->clientGone = TRUE;  /* so events aren't sent to client */
+	if (ClientIsAsleep(client))
+	    ClientSignal (client);
+	ProcessWorkQueueZombies();
+#ifdef LBX
+	ProcessQTagZombies();
+#endif
+	CloseDownConnection(client);
+
+	/* If the client made it to the Running stage, nClients has
+	 * been incremented on its behalf, so we need to decrement it
+	 * now.  If it hasn't gotten to Running, nClients has *not*
+	 * been incremented, so *don't* decrement it.
+	 */
+	if (client->clientState != ClientStateInitial &&
+	    client->clientState != ClientStateAuthenticating )
+	{
+	    --nClients;
+	}
+    }
+
+    if (really_close_down)
+    {
+	if (client->clientState == ClientStateRunning && nClients == 0)
+	    dispatchException |= dispatchExceptionAtReset;
+
+	client->clientState = ClientStateGone;
+	if (ClientStateCallback)
+	{
+	    NewClientInfoRec clientinfo;
+
+	    clientinfo.client = client; 
+	    clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+	    clientinfo.setup = (xConnSetup *) NULL;
+	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+	} 	    
+	FreeClientResources(client);
+	if (client->index < nextFreeClientID)
+	    nextFreeClientID = client->index;
+	clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+	SmartLastClient = NullClient;
+#endif
+	xfree(client);
+
+	while (!clients[currentMaxClients-1])
+	    currentMaxClients--;
+    }
+}
+
+static void
+KillAllClients()
+{
+    int i;
+    for (i=1; i<currentMaxClients; i++)
+        if (clients[i]) {
+            /* Make sure Retained clients are released. */
+            clients[i]->closeDownMode = DestroyAll;
+            CloseDownClient(clients[i]);     
+        }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ *    Find all clients that are gone and have terminated in RetainTemporary 
+ *    and  destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+    register int i;
+    register ClientPtr client;
+
+    for (i=1; i<currentMaxClients; i++)
+    {
+        client = clients[i];
+        if (client && (client->closeDownMode == RetainTemporary)
+	    && (client->clientGone))
+	    CloseDownClient(client);
+    }
+}
+
+void InitClient(client, i, ospriv)
+    ClientPtr client;
+    int i;
+    pointer ospriv;
+{
+    client->index = i;
+    client->sequence = 0; 
+    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+    client->clientGone = FALSE;
+    if (i)
+    {
+	client->closeDownMode = DestroyAll;
+	client->lastDrawable = (DrawablePtr)WindowTable[0];
+	client->lastDrawableID = WindowTable[0]->drawable.id;
+    }
+    else
+    {
+	client->closeDownMode = RetainPermanent;
+	client->lastDrawable = (DrawablePtr)NULL;
+	client->lastDrawableID = INVALID;
+    }
+    client->lastGC = (GCPtr) NULL;
+    client->lastGCID = INVALID;
+    client->numSaved = 0;
+    client->saveSet = (pointer *)NULL;
+    client->noClientException = Success;
+#ifdef DEBUG
+    client->requestLogIndex = 0;
+#endif
+    client->requestVector = InitialVector;
+    client->osPrivate = ospriv;
+    client->swapped = FALSE;
+    client->big_requests = FALSE;
+    client->priority = 0;
+    client->clientState = ClientStateInitial;
+#ifdef XKB
+    if (!noXkbExtension) {
+	client->xkbClientFlags = 0;
+	client->mapNotifyMask = 0;
+	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+    }
+#endif
+    client->replyBytesRemaining = 0;
+#ifdef LBX
+    client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+    client->trustLevel = XSecurityClientTrusted;
+    client->CheckAccess = NULL;
+    client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+    client->appgroup = NULL;
+#endif
+    client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+    client->smart_priority = 0;
+    client->smart_start_tick = SmartScheduleTime;
+    client->smart_stop_tick = SmartScheduleTime;
+    client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(client)
+    ClientPtr client;
+{
+    register char *ptr;
+    DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    if (totalClientSize == sizeof(ClientRec))
+	ppriv = (DevUnion *)NULL;
+    else if (client->index)
+	ppriv = (DevUnion *)(client + 1);
+    else
+    {
+	ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+	if (!ppriv)
+	    return 0;
+    }
+    client->devPrivates = ppriv;
+    sizes = clientPrivateSizes;
+    ptr = (char *)(ppriv + clientPrivateLen);
+    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr
+NextAvailableClient(ospriv)
+    pointer ospriv;
+{
+    register int i;
+    register ClientPtr client;
+    xReq data;
+
+    i = nextFreeClientID;
+    if (i == MAXCLIENTS)
+	return (ClientPtr)NULL;
+    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+    if (!client)
+	return (ClientPtr)NULL;
+    InitClient(client, i, ospriv);
+    InitClientPrivates(client);
+    if (!InitClientResources(client))
+    {
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    data.reqType = 1;
+    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+    {
+	FreeClientResources(client);
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    if (i == currentMaxClients)
+	currentMaxClients++;
+    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+	nextFreeClientID++;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+        clientinfo.setup = (xConnSetup *) NULL;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return(client);
+}
+
+int
+ProcInitialConnection(client)
+    register ClientPtr client;
+{
+    REQUEST(xReq);
+    register xConnClientPrefix *prefix;
+    int whichbyte = 1;
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+	return (client->noClientException = -1);
+    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+    {
+	client->swapped = TRUE;
+	SwapConnClientPrefix(prefix);
+    }
+    stuff->reqType = 2;
+    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+    if (client->swapped)
+    {
+	swaps(&stuff->length, whichbyte);
+    }
+    ResetCurrentRequest(client);
+    return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+    nClients++;
+}
+#endif
+
+int
+SendConnSetup(client, reason)
+    register ClientPtr client;
+    char *reason;
+{
+    register xWindowRoot *root;
+    register int i;
+    int numScreens;
+    char* lConnectionInfo;
+    xConnSetupPrefix* lconnSetupPrefix;
+
+    if (reason)
+    {
+	xConnSetupPrefix csp;
+
+	csp.success = xFalse;
+	csp.lengthReason = strlen(reason);
+	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+	csp.majorVersion = X_PROTOCOL;
+	csp.minorVersion = X_PROTOCOL_REVISION;
+	if (client->swapped)
+	    WriteSConnSetupPrefix(client, &csp);
+	else
+	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+        (void)WriteToClient(client, (int)csp.lengthReason, reason);
+	return (client->noClientException = -1);
+    }
+
+    numScreens = screenInfo.numScreens;
+    lConnectionInfo = ConnectionInfo;
+    lconnSetupPrefix = &connSetupPrefix;
+
+    /* We're about to start speaking X protocol back to the client by
+     * sending the connection setup info.  This means the authorization
+     * step is complete, and we can count the client as an
+     * authorized one.
+     */
+    nClients++;
+
+    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+    client->sequence = 0;
+#ifdef XAPPGROUP
+    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+    /* fill in the "currentInputMask" */
+    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+    for (i=0; i<numScreens; i++) 
+    {
+	register unsigned int j;
+	register xDepth *pDepth;
+
+        root->currentInputMask = WindowTable[i]->eventMask |
+			         wOtherEventMasks (WindowTable[i]);
+	pDepth = (xDepth *)(root + 1);
+	for (j = 0; j < root->nDepths; j++)
+	{
+	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+				pDepth->nVisuals * sizeof(xVisualType));
+	}
+	root = (xWindowRoot *)pDepth;
+    }
+
+    if (client->swapped)
+    {
+	WriteSConnSetupPrefix(client, lconnSetupPrefix);
+	WriteSConnectionInfo(client,
+			     (unsigned long)(lconnSetupPrefix->length << 2),
+			     lConnectionInfo);
+    }
+    else
+    {
+	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
+			    (char *) lconnSetupPrefix);
+	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+			    lConnectionInfo);
+    }
+    client->clientState = ClientStateRunning;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = lconnSetupPrefix;  
+        clientinfo.setup = (xConnSetup *)lConnectionInfo;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(client)
+    register ClientPtr client;
+{
+    char *reason, *auth_proto, *auth_string;
+    register xConnClientPrefix *prefix;
+    REQUEST(xReq);
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    auth_proto = (char *)prefix + sz_xConnClientPrefix;
+    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+    if ((prefix->majorVersion != X_PROTOCOL) ||
+	(prefix->minorVersion != X_PROTOCOL_REVISION))
+	reason = "Protocol version mismatch";
+    else
+	reason = ClientAuthorized(client,
+				  (unsigned short)prefix->nbytesAuthProto,
+				  auth_proto,
+				  (unsigned short)prefix->nbytesAuthString,
+				  auth_string);
+    /*
+     * If Kerberos is being used for this client, the clientState
+     * will be set to ClientStateAuthenticating at this point.
+     * More messages need to be exchanged among the X server, Kerberos
+     * server, and client to figure out if everyone is authorized.
+     * So we don't want to send the connection setup info yet, since
+     * the auth step isn't really done.
+     */
+    if (client->clientState == ClientStateCheckingSecurity)
+	client->clientState = ClientStateCheckedSecurity;
+    else if (client->clientState != ClientStateAuthenticating)
+	return(SendConnSetup(client, reason));
+    return(client->noClientException);
+}
+
+void
+SendErrorToClient(client, majorCode, minorCode, resId, errorCode)
+    ClientPtr client;
+    unsigned int majorCode;
+    unsigned int minorCode;
+    XID resId;
+    int errorCode;
+{
+    xError rep;
+
+    rep.type = X_Error;
+    rep.sequenceNumber = client->sequence;
+    rep.errorCode = errorCode;
+    rep.majorCode = majorCode;
+    rep.minorCode = minorCode;
+    rep.resourceID = resId;
+
+    WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(pWin)
+    WindowPtr pWin;
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].pWin == pWin)
+        {
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+static void
+DeleteClientFromAnySelections(client)
+    ClientPtr client;
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].client == client)
+        {
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+void
+MarkClientException(client)
+    ClientPtr client;
+{
+    client->noClientException = -1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
new file mode 100644
index 000000000..83103ffd6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
@@ -0,0 +1,2883 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXdixfonts.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.27 2003/02/15 03:47:05 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+/*
+#define NXAGENT_DEBUG
+*/
+
+#ifdef DEBUG
+#include	<stdio.h>
+#endif
+
+#include "Agent.h"
+#include "Font.h"
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+char _NXFontPath[1024];
+
+/*
+ * Override the default font path and make
+ * it configurable at run time, based on
+ * the NX_FONT environment.
+ */
+
+static const char *_NXGetFontPath(const char *path)
+{
+  const char *fontEnv;
+
+    /*
+     * Check the environment only once.
+     */
+
+    if (*_NXFontPath != '\0')
+    {
+        return _NXFontPath;
+    }
+
+    fontEnv = getenv("NX_FONT");
+
+    if (fontEnv != NULL && *fontEnv != '\0')
+    {
+        if (strlen(fontEnv) + 1 > 1024)
+        {
+#ifdef NX_TRANS_TEST
+            fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
+#endif
+            goto _NXGetFontPathError;
+        }
+
+        strcpy(_NXFontPath, fontEnv);
+
+#ifdef NX_TRANS_TEST
+        fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
+#endif
+
+        return _NXFontPath;
+    }
+
+_NXGetFontPathError:
+
+    strcpy(_NXFontPath, path);
+
+#ifdef NX_TRANS_TEST
+    fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
+#endif
+
+    return _NXFontPath;
+}
+
+#endif
+
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include "xf86bigfont.h"
+#endif
+
+#define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int  num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int  num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int  num_slept_fpes = 0;
+static int  size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+    int         err;
+{
+    switch (err) {
+    case Successful:
+	return Success;
+    case AllocError:
+	return BadAlloc;
+    case BadFontName:
+	return BadName;
+    case BadFontPath:
+    case BadFontFormat:	/* is there something better? */
+    case BadCharRange:
+	return BadValue;
+    default:
+	return err;
+    }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(defaultfontname)
+    char       *defaultfontname;
+{
+    int         err;
+    FontPtr     pf;
+    XID         fid;
+
+    fid = FakeClientID(0);
+    err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+		   (unsigned) strlen(defaultfontname), defaultfontname);
+    if (err != Success)
+	return FALSE;
+    pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+    if (pf == (FontPtr) NULL)
+	return FALSE;
+    defaultFont = pf;
+    return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted.  this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(fpe)
+    FontPathElementPtr fpe;
+{
+    int         i;
+    FontPathElementPtr *new;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+	    return;
+	}
+    }
+    if (num_slept_fpes == size_slept_fpes) {
+	new = (FontPathElementPtr *)
+	    xrealloc(slept_fpes,
+		     sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+	if (!new)
+	    return;
+	slept_fpes = new;
+	size_slept_fpes += 4;
+    }
+    slept_fpes[num_slept_fpes] = fpe;
+    num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(fpe)
+    FontPathElementPtr fpe;
+{
+    int         i,
+                j;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+	    for (j = i; j < num_slept_fpes; j++) {
+		slept_fpes[j] = slept_fpes[j + 1];
+	    }
+	    num_slept_fpes--;
+	    return;
+	}
+    }
+}
+
+/* ARGSUSED */
+void
+FontWakeup(data, count, LastSelectMask)
+    pointer     data;
+    int		count;
+    pointer     LastSelectMask;
+{
+    int         i;
+    FontPathElementPtr fpe;
+
+    if (count < 0)
+	return;
+    /* wake up any fpe's that may be waiting for information */
+    for (i = 0; i < num_slept_fpes; i++) {
+	fpe = slept_fpes[i];
+	(void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+    }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+#if NeedFunctionPrototypes
+UseFPE(FontPathElementPtr fpe)
+#else
+UseFPE(fpe)
+    FontPathElementPtr fpe;
+#endif
+{
+    fpe->refcount++;
+}
+
+static void
+#if NeedFunctionPrototypes
+FreeFPE (FontPathElementPtr fpe)
+#else
+FreeFPE (fpe)
+    FontPathElementPtr	fpe;
+#endif
+{
+    fpe->refcount--;
+    if (fpe->refcount == 0) {
+	(*fpe_functions[fpe->type].free_fpe) (fpe);
+	xfree(fpe->name);
+	xfree(fpe);
+    }
+}
+
+static Bool
+#if NeedFunctionPrototypes
+doOpenFont(ClientPtr client, OFclosurePtr c)
+#else
+doOpenFont(client, c)
+    ClientPtr   client;
+    OFclosurePtr c;
+#endif
+{
+    FontPtr     pfont = NullFont;
+    FontPathElementPtr fpe = NULL;
+    ScreenPtr   pScr;
+    int         err = Successful;
+    int         i;
+    char       *alias,
+               *newname;
+    int         newlen;
+    int		aliascount = 20;
+    char nxagentOrigFontName[256];
+    int nxagentOrigFontNameLen;
+
+    /*
+     * Decide at runtime what FontFormat to use.
+     */
+    Mask FontFormat = 
+
+	((screenInfo.imageByteOrder == LSBFirst) ?
+	    BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+	((screenInfo.bitmapBitOrder == LSBFirst) ?
+	    BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+	BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+	BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+	BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+	BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+	BitmapFormatScanlinePad64 |
+#endif
+
+	BitmapFormatScanlineUnit8;
+
+
+    nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
+
+    memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
+
+    nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    while (c->current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current_fpe];
+	err = (*fpe_functions[fpe->type].open_font)
+	    ((pointer) client, fpe, c->flags,
+	     c->fontname, c->fnamelen, FontFormat,
+	     BitmapFormatMaskByte |
+	     BitmapFormatMaskBit |
+	     BitmapFormatMaskImageRectangle |
+	     BitmapFormatMaskScanLinePad |
+	     BitmapFormatMaskScanLineUnit,
+	     c->fontid, &pfont, &alias,
+	     c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+		 c->non_cachable_font :
+		 (FontPtr)0);
+
+	if (err == FontNameAlias && alias) {
+	    newlen = strlen(alias);
+	    newname = (char *) xrealloc(c->fontname, newlen);
+	    if (!newname) {
+		err = AllocError;
+		break;
+	    }
+	    memmove(newname, alias, newlen);
+	    c->fontname = newname;
+	    c->fnamelen = newlen;
+	    c->current_fpe = 0;
+	    if (--aliascount <= 0)
+		break;
+	    continue;
+	}
+	if (err == BadFontName) {
+	    c->current_fpe++;
+	    continue;
+	}
+	if (err == Suspended) {
+	    if (!c->slept) {
+		c->slept = TRUE;
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+#ifdef NXAGENT_DEBUG
+                fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
+#endif
+	    }
+	    return TRUE;
+	}
+	break;
+    }
+
+    if (err != Successful)
+	goto bail;
+    if (!pfont) {
+	err = BadFontName;
+	goto bail;
+    }
+    if (!pfont->fpe)
+	pfont->fpe = fpe;
+    pfont->refcnt++;
+    if (pfont->refcnt == 1) {
+	UseFPE(pfont->fpe);
+	for (i = 0; i < screenInfo.numScreens; i++) {
+	    pScr = screenInfo.screens[i];
+	    if (pScr->RealizeFont)
+	    {
+
+                /* NXAGENT uses useless screen pointer to pass the original font name
+                *  to realizeFont, could be a source of problems in the future.
+                */
+
+		if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+		{
+		    CloseFont (pfont, (Font) 0);
+		    err=BadFontName;
+		    goto bail;
+		}
+	    }
+	}
+    }
+    if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+	err = AllocError;
+	goto bail;
+    }
+    if( nxagentFontPriv(pfont) -> mirrorID == 0 )
+    {
+      extern RESTYPE RT_NX_FONT;
+
+      nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
+      if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
+        FreeResource(c->fontid, RT_NONE);
+        err = AllocError;
+        goto bail;
+      }
+    }
+    if (patternCache && pfont != c->non_cachable_font)
+	CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+			 pfont);
+bail:
+    if (err != Successful && c->client != serverClient) {
+	SendErrorToClient(c->client, X_OpenFont, 0,
+			  c->fontid, FontToXError(err));
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++) {
+	FreeFPE(c->fpe_list[i]);
+    }
+    xfree(c->fpe_list);
+    xfree(c->fontname);
+    xfree(c);
+    return TRUE;
+}
+
+int
+OpenFont(client, fid, flags, lenfname, pfontname)
+    ClientPtr   client;
+    XID         fid;
+    Mask        flags;
+    unsigned    lenfname;
+    char       *pfontname;
+{
+    OFclosurePtr c;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!c)
+	return BadAlloc;
+    c->fontname = (char *) xalloc(lenfname);
+    c->origFontName = pfontname;
+    c->origFontNameLen = lenfname;
+    if (!c->fontname) {
+	xfree(c);
+	return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c->fontname);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove(c->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->fontid = fid;
+    c->current_fpe = 0;
+    c->num_fpes = num_fpes;
+    c->fnamelen = lenfname;
+    c->slept = FALSE;
+    c->flags = flags;
+    c->non_cachable_font = cached;
+
+    (void) doOpenFont(client, c);
+    return Success;
+}
+
+/*
+ * Decrement font's ref count, and free storage if ref count equals zero
+ */
+/*ARGSUSED*/
+int
+CloseFont(value, fid)
+    pointer	value;  /* must conform to DeleteType */
+    XID		fid;
+{
+    int         nscr;
+    ScreenPtr   pscr;
+    FontPathElementPtr fpe;
+    FontPtr     pfont = (FontPtr)value;
+
+    if (pfont == NullFont)
+	return (Success);
+    if (--pfont->refcnt == 0) {
+	if (patternCache)
+	    RemoveCachedFontPattern (patternCache, pfont);
+	/*
+	 * since the last reference is gone, ask each screen to free any
+	 * storage it may have allocated locally for it.
+	 */
+	for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+	    pscr = screenInfo.screens[nscr];
+	    if (pscr->UnrealizeFont)
+		(*pscr->UnrealizeFont) (pscr, pfont);
+	}
+	if (pfont == defaultFont)
+	    defaultFont = NULL;
+#ifdef LBX
+	LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+        {
+           extern void XF86BigfontFreeFontShm(FontPtr);
+           XF86BigfontFreeFontShm(pfont);
+        }
+#endif
+	fpe = pfont->fpe;
+	(*fpe_functions[fpe->type].close_font) (fpe, pfont);
+	FreeFPE(fpe);
+    }
+    return (Success);
+}
+
+
+/***====================================================================***/
+
+ /*
+  * \ Sets up pReply as the correct QueryFontReply for pFont with the first
+  * nProtoCCIStructs char infos. \
+  */
+
+void
+QueryFont(pFont, pReply, nProtoCCIStructs)
+    FontPtr          pFont;
+    xQueryFontReply *pReply;	/* caller must allocate this storage */
+    int              nProtoCCIStructs;
+{
+    FontPropPtr      pFP;
+    int              r,
+                     c,
+                     i;
+    xFontProp       *prFP;
+    xCharInfo       *prCI;
+    xCharInfo       *charInfos[256];
+    unsigned char    chars[512];
+    int              ninfos;
+    unsigned long    ncols;
+    unsigned long    count;
+
+    /* pr->length set in dispatch */
+    pReply->minCharOrByte2 = pFont->info.firstCol;
+    pReply->defaultChar = pFont->info.defaultCh;
+    pReply->maxCharOrByte2 = pFont->info.lastCol;
+    pReply->drawDirection = pFont->info.drawDirection;
+    pReply->allCharsExist = pFont->info.allExist;
+    pReply->minByte1 = pFont->info.firstRow;
+    pReply->maxByte1 = pFont->info.lastRow;
+    pReply->fontAscent = pFont->info.fontAscent;
+    pReply->fontDescent = pFont->info.fontDescent;
+
+    pReply->minBounds = pFont->info.ink_minbounds;
+    pReply->maxBounds = pFont->info.ink_maxbounds;
+
+    pReply->nFontProps = pFont->info.nprops;
+    pReply->nCharInfos = nProtoCCIStructs;
+
+    for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+	    i < pFont->info.nprops;
+	    i++, pFP++, prFP++) {
+	prFP->name = pFP->name;
+	prFP->value = pFP->value;
+    }
+
+    ninfos = 0;
+    ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+    prCI = (xCharInfo *) (prFP);
+    for (r = pFont->info.firstRow;
+	    ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+	    r++) {
+	i = 0;
+	for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+	    chars[i++] = r;
+	    chars[i++] = c;
+	}
+	(*pFont->get_metrics) (pFont, ncols, chars, 
+				TwoD16Bit, &count, charInfos);
+	i = 0;
+	for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+	    *prCI = *charInfos[i];
+	    prCI++;
+	    ninfos++;
+	}
+    }
+    return;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+#else
+doListFontsAndAliases(client, c)
+    ClientPtr   client;
+    LFclosurePtr c;
+#endif
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    FontNamesPtr names = NULL;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int		nnames;
+    int         stringLens;
+    int         i;
+    xListFontsReply reply;
+    char	*bufptr;
+    char	*bufferStart;
+    int		aliascount = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)doListFontsAndAliases,
+			(pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+			memmove(resolved, tmpname, resolvedlen + 1);
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+			(void)AddFontNamesName(c->names, c->savedName,
+					       c->savedNameLen);
+		}
+		else
+		    (void)AddFontNamesName(c->names, name, namelen);
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+			memmove(c->savedName, name, namelen + 1);
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+    if (err != Successful) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+	goto bail;
+    }
+
+finish:
+
+    names = c->names;
+    nnames = names->nnames;
+    client = c->client;
+    stringLens = 0;
+    for (i = 0; i < nnames; i++)
+	stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+    reply.type = X_Reply;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    reply.nFonts = nnames;
+    reply.sequenceNumber = client->sequence;
+
+    bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+    if (!bufptr && reply.length) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+	goto bail;
+    }
+    /*
+     * since WriteToClient long word aligns things, copy to temp buffer and
+     * write all at once
+     */
+    for (i = 0; i < nnames; i++) {
+	if (names->length[i] > 255)
+	    reply.nFonts--;
+	else
+	{
+	    {
+	      /* dirty hack: don't list to client fonts not existing on the remote side */
+	      char tmp[256];
+
+	      memcpy(tmp, names->names[i], names->length[i]);
+	      tmp[ names->length[i] ] = 0;
+
+	      if (nxagentFontLookUp(tmp) == 0)
+		{
+#ifdef NXAGENT_FONTMATCH_DEBUG
+		  fprintf(stderr, "doListFontsAndAliases:\n");
+		  fprintf(stderr, "      removing font: %s \n", tmp);
+#endif
+		  reply.nFonts--;
+		  stringLens -= names->length[i];
+		  continue;
+		}
+	    }
+	    *bufptr++ = names->length[i];
+	    memmove( bufptr, names->names[i], names->length[i]);
+	    bufptr += names->length[i];
+	}
+    }
+    nnames = reply.nFonts;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+    WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+    (void) WriteToClient(client, stringLens + nnames, bufferStart);
+    DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(names);
+    xfree(c);
+    if (resolved) xfree(resolved);
+    return TRUE;
+}
+
+int
+ListFonts(client, pattern, length, max_names)
+    ClientPtr   client;
+    unsigned char *pattern;
+    unsigned int length;
+    unsigned int max_names;
+{
+    int         i;
+    LFclosurePtr c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+	return BadAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsAndAliases(client, c);
+    return Success;
+}
+
+int
+doListFontsWithInfo(client, c)
+    ClientPtr   client;
+    LFWIclosurePtr c;
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name;
+    int         namelen;
+    int         numFonts;
+    FontInfoRec fontInfo,
+               *pFontInfo;
+    xListFontsWithInfoReply *reply;
+    int         length;
+    xFontProp  *pFP;
+    int         i;
+    int		aliascount = 0;
+    xListFontsWithInfoReply finalReply;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+ 	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+    if (!c->current.patlen)
+	goto finish;
+    while (c->current.current_fpe < c->num_fpes)
+    {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+	if (!c->current.list_started)
+ 	{
+	    err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+		(client, fpe, c->current.pattern, c->current.patlen,
+		 c->current.max_names, &c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	    if (err == Successful)
+		c->current.list_started = TRUE;
+	}
+	if (err == Successful)
+ 	{
+	    name = 0;
+	    pFontInfo = &fontInfo;
+	    err = (*fpe_functions[fpe->type].list_next_font_with_info)
+		(client, fpe, &name, &namelen, &pFontInfo,
+		 &numFonts, c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doListFontsWithInfo,
+			     c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	}
+	/*
+	 * When we get an alias back, save our state and reset back to the
+	 * start of the FPE looking for the specified name.  As soon as a real
+	 * font is found for the alias, pop back to the old state
+	 */
+	if (err == FontNameAlias)
+ 	{
+	    /*
+	     * when an alias recurses, we need to give
+	     * the last FPE a chance to clean up; so we call
+	     * it again, and assume that the error returned
+	     * is BadFontName, indicating the alias resolution
+	     * is complete.
+	     */
+	    if (c->haveSaved)
+	    {
+		char	*tmpname;
+		int	tmpnamelen;
+		FontInfoPtr tmpFontInfo;
+
+	    	tmpname = 0;
+	    	tmpFontInfo = &fontInfo;
+	    	(void) (*fpe_functions[fpe->type].list_next_font_with_info)
+		    (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+		     &numFonts, c->current.private);
+		if (--aliascount <= 0)
+		{
+		    err = BadFontName;
+		    goto ContBadFontName;
+		}
+	    }
+	    else
+	    {
+		c->saved = c->current;
+		c->haveSaved = TRUE;
+		c->savedNumFonts = numFonts;
+		c->savedName = (char *) pFontInfo;
+		aliascount = 20;
+	    }
+	    memmove(c->current.pattern, name, namelen);
+	    c->current.patlen = namelen;
+	    c->current.max_names = 1;
+	    c->current.current_fpe = 0;
+	    c->current.private = 0;
+	    c->current.list_started = FALSE;
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back.  If we've sent enough font
+	 * names, quit.  Always wait for BadFontName to let the FPE
+	 * have a chance to clean up.
+	 */
+	else if (err == BadFontName)
+ 	{
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+ 	    {
+		if (c->current.max_names == 0 ||
+			c->current.current_fpe == c->num_fpes)
+ 		{
+		    c->haveSaved = FALSE;
+		    c->saved.max_names -= (1 - c->current.max_names);
+		    c->current = c->saved;
+		}
+	    }
+	    else if (c->current.max_names == 0)
+		break;
+	}
+ 	else if (err == Successful)
+ 	{
+
+	    if (c->haveSaved)
+ 	    {
+		numFonts = c->savedNumFonts;
+		name = c->savedName;
+		namelen = strlen(name);
+	    }
+
+	   if (nxagentFontLookUp(name) == 0)
+	   {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "doListFontsAndAliases (with info):\n");
+	      fprintf(stderr, "      removing font: %s \n", name);
+#endif
+	       continue;
+           }
+
+	    length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+	    reply = c->reply;
+	    if (c->length < length)
+ 	    {
+		reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+		if (!reply)
+ 		{
+		    err = AllocError;
+		    break;
+		}
+		c->reply = reply;
+		c->length = length;
+	    }
+	    reply->type = X_Reply;
+	    reply->length = (sizeof *reply - sizeof(xGenericReply) +
+			     pFontInfo->nprops * sizeof(xFontProp) +
+			     namelen + 3) >> 2;
+	    reply->sequenceNumber = client->sequence;
+	    reply->nameLength = namelen;
+	    reply->minBounds = pFontInfo->ink_minbounds;
+	    reply->maxBounds = pFontInfo->ink_maxbounds;
+	    reply->minCharOrByte2 = pFontInfo->firstCol;
+	    reply->maxCharOrByte2 = pFontInfo->lastCol;
+	    reply->defaultChar = pFontInfo->defaultCh;
+	    reply->nFontProps = pFontInfo->nprops;
+	    reply->drawDirection = pFontInfo->drawDirection;
+	    reply->minByte1 = pFontInfo->firstRow;
+	    reply->maxByte1 = pFontInfo->lastRow;
+	    reply->allCharsExist = pFontInfo->allExist;
+	    reply->fontAscent = pFontInfo->fontAscent;
+	    reply->fontDescent = pFontInfo->fontDescent;
+	    reply->nReplies = numFonts;
+	    pFP = (xFontProp *) (reply + 1);
+	    for (i = 0; i < pFontInfo->nprops; i++)
+ 	    {
+		pFP->name = pFontInfo->props[i].name;
+		pFP->value = pFontInfo->props[i].value;
+		pFP++;
+	    }
+	    WriteSwappedDataToClient(client, length, reply);
+	    (void) WriteToClient(client, namelen, name);
+	    if (pFontInfo == &fontInfo)
+ 	    {
+		xfree(fontInfo.props);
+		xfree(fontInfo.isStringProp);
+	    }
+	    --c->current.max_names;
+	}
+    }
+finish:
+    length = sizeof(xListFontsWithInfoReply);
+    bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+    finalReply.type = X_Reply;
+    finalReply.sequenceNumber = client->sequence;
+    finalReply.length = (sizeof(xListFontsWithInfoReply)
+		     - sizeof(xGenericReply)) >> 2;
+    WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->reply);
+    xfree(c->fpe_list);
+    xfree(c);
+    return TRUE;
+}
+
+int
+StartListFontsWithInfo(client, length, pattern, max_names)
+    ClientPtr   client;
+    int         length;
+    unsigned char       *pattern;
+    int         max_names;
+{
+    int		    i;
+    LFWIclosurePtr  c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+	goto badAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list)
+    {
+	xfree(c);
+	goto badAlloc;
+    }
+    memmove(c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++)
+    {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->reply = 0;
+    c->length = 0;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->savedNumFonts = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    doListFontsWithInfo(client, c);
+    return Success;
+badAlloc:
+    return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(client, c)
+    ClientPtr   client;
+    register PTclosurePtr c;
+{
+    register FontPtr pFont = c->pGC->font, oldpFont;
+    Font	fid, oldfid;
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+    FontPathElementPtr fpe;
+    GC *origGC = NULL;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+	if (c->slept)
+	{
+	    /* Client has died, but we cannot bail out right now.  We
+	       need to clean up after the work we did when going to
+	       sleep.  Setting the drawable pointer to 0 makes this
+	       happen without any attempts to render or perform other
+	       unnecessary activities.  */
+	    c->pDraw = (DrawablePtr)0;
+	}
+	else
+	{
+	    err = Success;
+	    goto bail;
+	}
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client and avoid further
+	   rendering while we clean up after ourself.  */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	c->pDraw = (DrawablePtr)0;
+    }
+
+    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+    while (c->endReq - c->pElt > TextEltHeader)
+    {
+	if (*c->pElt == FontChange)
+        {
+	    if (c->endReq - c->pElt < FontShiftSize)
+	    {
+		 err = BadLength;
+		 goto bail;
+	    }
+
+	    oldpFont = pFont;
+	    oldfid = fid;
+
+	    fid =  ((Font)*(c->pElt+4))		/* big-endian */
+		 | ((Font)*(c->pElt+3)) << 8
+		 | ((Font)*(c->pElt+2)) << 16
+		 | ((Font)*(c->pElt+1)) << 24;
+	    pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+						    SecurityReadAccess);
+	    if (!pFont)
+	    {
+		client->errorValue = fid;
+		err = BadFont;
+		/* restore pFont and fid for step 4 (described below) */
+		pFont = oldpFont;
+		fid = oldfid;
+
+		/* If we're in START_SLEEP mode, the following step
+		   shortens the request...  in the unlikely event that
+		   the fid somehow becomes valid before we come through
+		   again to actually execute the polytext, which would
+		   then mess up our refcounting scheme badly.  */
+		c->err = err;
+		c->endReq = c->pElt;
+
+		goto bail;
+	    }
+
+	    /* Step 3 (described below) on our new font */
+	    if (client_state == START_SLEEP)
+		pFont->refcnt++;
+	    else
+	    {
+		if (pFont != c->pGC->font && c->pDraw)
+		{
+		    ChangeGC( c->pGC, GCFont, &fid);
+		    ValidateGC(c->pDraw, c->pGC);
+		    if (c->reqType == X_PolyText8)
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+		    else
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+		}
+
+		/* Undo the refcnt++ we performed when going to sleep */
+		if (client_state == SLEEPING)
+		    (void)CloseFont(c->pGC->font, (Font)0);
+	    }
+	    c->pElt += FontShiftSize;
+	}
+	else	/* print a string */
+	{
+	    unsigned char *pNextElt;
+	    pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+	    if ( pNextElt > c->endReq)
+	    {
+		err = BadLength;
+		goto bail;
+	    }
+	    if (client_state == START_SLEEP)
+	    {
+		c->pElt = pNextElt;
+		continue;
+	    }
+	    if (c->pDraw)
+	    {
+		lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+				   c->pElt + TextEltHeader);
+	    }
+	    else lgerr = Successful;
+
+	    if (lgerr == Suspended)
+	    {
+		if (!c->slept) {
+		    int len;
+		    GC *pGC;
+		    PTclosurePtr new_closure;
+
+    /*  We're putting the client to sleep.  We need to do a few things
+	to ensure successful and atomic-appearing execution of the
+	remainder of the request.  First, copy the remainder of the
+	request into a safe malloc'd area.  Second, create a scratch GC
+	to use for the remainder of the request.  Third, mark all fonts
+	referenced in the remainder of the request to prevent their
+	deallocation.  Fourth, make the original GC look like the
+	request has completed...  set its font to the final font value
+	from this request.  These GC manipulations are for the unlikely
+	(but possible) event that some other client is using the GC.
+	Steps 3 and 4 are performed by running this procedure through
+	the remainder of the request in a special no-render mode
+	indicated by client_state = START_SLEEP.  */
+
+		    /* Step 1 */
+		    /* Allocate a malloc'd closure structure to replace
+		       the local one we were passed */
+		    new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+		    if (!new_closure)
+		    {
+			err = BadAlloc;
+			goto bail;
+		    }
+		    *new_closure = *c;
+		    c = new_closure;
+
+		    len = c->endReq - c->pElt;
+		    c->data = (unsigned char *)xalloc(len);
+		    if (!c->data)
+		    {
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    memmove(c->data, c->pElt, len);
+		    c->pElt = c->data;
+		    c->endReq = c->pElt + len;
+
+		    /* Step 2 */
+
+		    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+		    if (!pGC)
+		    {
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+
+                    pGC->tileIsPixel = TRUE;
+                    pGC->tile.pixel = 0;
+                    pGC->stipple = NullPixmap;
+
+		    if ((err = CopyGC(c->pGC, pGC, GCFunction |
+				      GCPlaneMask | GCForeground |
+				      GCBackground | GCFillStyle |
+				      GCTile | GCStipple |
+				      GCTileStipXOrigin |
+				      GCTileStipYOrigin | GCFont |
+				      GCSubwindowMode | GCClipXOrigin |
+				      GCClipYOrigin | GCClipMask)) !=
+				      Success)
+		    {
+			FreeScratchGC(pGC);
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    origGC = c->pGC;
+		    c->pGC = pGC;
+		    ValidateGC(c->pDraw, c->pGC);
+		    
+		    c->slept = TRUE;
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doPolyText,
+			     (pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
+#endif
+
+		    /* Set up to perform steps 3 and 4 */
+		    client_state = START_SLEEP;
+		    continue;	/* on to steps 3 and 4 */
+		}
+		return TRUE;
+	    }
+	    else if (lgerr != Successful)
+	    {
+		err = FontToXError(lgerr);
+		goto bail;
+	    }
+	    if (c->pDraw)
+	    {
+		c->xorg += *((INT8 *)(c->pElt + 1));	/* must be signed */
+		c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+		    *c->pElt, c->pElt + TextEltHeader);
+	    }
+	    c->pElt = pNextElt;
+	}
+    }
+
+bail:
+
+    if (client_state == START_SLEEP)
+    {
+	/* Step 4 */
+	if (pFont != origGC->font)
+	{
+	    ChangeGC(origGC, GCFont, &fid);
+	    ValidateGC(c->pDraw, origGC);
+	}
+
+	/* restore pElt pointer for execution of remainder of the request */
+	c->pElt = c->data;
+	return TRUE;
+    }
+
+    if (c->err != Success) err = c->err;
+    if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+        if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+PolyText(client, pDraw, pGC, pElt, endReq, xorg, yorg, reqType, did)
+    ClientPtr client;
+    DrawablePtr pDraw;
+    GC *pGC;
+    unsigned char *pElt;
+    unsigned char *endReq;
+    int xorg;
+    int yorg;
+    int reqType;
+    XID did;
+{
+    PTclosureRec local_closure;
+
+    local_closure.pElt = pElt;
+    local_closure.endReq = endReq;
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_PolyText8)
+    {
+	local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.polyText =  (PolyTextPtr) pGC->ops->PolyText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.pGC = pGC;
+    local_closure.did = did;
+    local_closure.err = Success;
+    local_closure.slept = FALSE;
+
+    (void) doPolyText(client, &local_closure);
+    return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(client, c)
+    ClientPtr   client;
+    register ITclosurePtr c;
+{
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    FontPathElementPtr fpe;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client. */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+    if (lgerr == Suspended)
+    {
+        if (!c->slept) {
+	    GC *pGC;
+	    unsigned char *data;
+	    ITclosurePtr new_closure;
+
+	    /* We're putting the client to sleep.  We need to
+	       save some state.  Similar problem to that handled
+	       in doPolyText, but much simpler because the
+	       request structure is much simpler. */
+
+	    new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+	    if (!new_closure)
+	    {
+		err = BadAlloc;
+		goto bail;
+	    }
+	    *new_closure = *c;
+	    c = new_closure;
+
+	    data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+	    if (!data)
+	    {
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    memmove(data, c->data, c->nChars * c->itemSize);
+	    c->data = data;
+
+	    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+	    if (!pGC)
+	    {
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+
+            pGC->tileIsPixel = TRUE;
+            pGC->tile.pixel = 0;
+            pGC->stipple = NullPixmap;
+
+	    if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+			      GCForeground | GCBackground | GCFillStyle |
+			      GCTile | GCStipple | GCTileStipXOrigin |
+			      GCTileStipYOrigin | GCFont |
+			      GCSubwindowMode | GCClipXOrigin |
+			      GCClipYOrigin | GCClipMask)) != Success)
+	    {
+		FreeScratchGC(pGC);
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    c->pGC = pGC;
+	    ValidateGC(c->pDraw, c->pGC);
+
+	    c->slept = TRUE;
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+#ifdef NXAGENT_DEBUG
+            fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
+#endif
+
+        }
+        return TRUE;
+    }
+    else if (lgerr != Successful)
+    {
+        err = FontToXError(lgerr);
+        goto bail;
+    }
+    if (c->pDraw)
+    {
+	(* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+	    c->nChars, c->data);
+    }
+
+bail:
+
+    if (err != Success && c->client != serverClient) {
+	SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+ImageText(client, pDraw, pGC, nChars, data, xorg, yorg, reqType, did)
+    ClientPtr client;
+    DrawablePtr pDraw;
+    GC *pGC;
+    int nChars;
+    unsigned char *data;
+    int xorg;
+    int yorg;
+    int reqType;
+    XID did;
+{
+    ITclosureRec local_closure;
+
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.pGC = pGC;
+    local_closure.nChars = nChars;
+    local_closure.data = data;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_ImageText8)
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.did = did;
+    local_closure.slept = FALSE;
+
+    (void) doImageText(client, &local_closure);
+    return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+#if NeedFunctionPrototypes
+DetermineFPEType(char *pathname)
+#else
+DetermineFPEType(pathname)
+    char       *pathname;
+#endif
+{
+    int         i;
+
+    for (i = 0; i < num_fpe_types; i++) {
+	if ((*fpe_functions[i].name_check) (pathname))
+	    return i;
+    }
+    return -1;
+}
+
+
+static void
+#if NeedFunctionPrototypes
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+#else
+FreeFontPath(list, n, force)
+    FontPathElementPtr	*list;
+    Bool		force;
+    int         n;
+#endif
+{
+    int         i;
+
+    for (i = 0; i < n; i++) {
+	if (force) {
+	    /* Sanity check that all refcounts will be 0 by the time
+	       we get to the end of the list. */
+	    int found = 1;	/* the first reference is us */
+	    int j;
+	    for (j = i+1; j < n; j++) {
+		if (list[j] == list[i])
+		    found++;
+	    }
+	    if (list[i]->refcount != found) {
+		ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+		       list[i]->name_length, list[i]->name,
+		       list[i]->refcount, found);
+		list[i]->refcount = found; /* ensure it will get freed */
+	    }
+	}
+	FreeFPE(list[i]);
+    }
+    xfree((char *) list);
+}
+
+static FontPathElementPtr
+#if NeedFunctionPrototypes
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+#else
+find_existing_fpe(list, num, name, len)
+    FontPathElementPtr *list;
+    int         num;
+    unsigned char *name;
+    int         len;
+#endif
+{
+    FontPathElementPtr fpe;
+    int         i;
+
+    for (i = 0; i < num; i++) {
+	fpe = list[i];
+	if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+	    return fpe;
+    }
+    return (FontPathElementPtr) 0;
+}
+
+
+static int
+#if NeedFunctionPrototypes
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+#else
+SetFontPathElements(npaths, paths, bad, persist)
+    int         npaths;
+    unsigned char *paths;
+    int        *bad;
+    Bool	persist;
+#endif
+{
+    int         i, err = 0;
+    int         valid_paths = 0;
+    unsigned int len;
+    unsigned char *cp = paths;
+    FontPathElementPtr fpe = NULL, *fplist;
+
+    fplist = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * npaths);
+    if (!fplist) {
+	*bad = 0;
+	return BadAlloc;
+    }
+    for (i = 0; i < num_fpe_types; i++) {
+	if (fpe_functions[i].set_path_hook)
+	    (*fpe_functions[i].set_path_hook) ();
+    }
+    for (i = 0; i < npaths; i++) 
+    {
+	len = (unsigned int) (*cp++);
+
+	if (len == 0) 
+	{
+	    if (persist)
+		ErrorF ("Removing empty element from the valid list of fontpaths\n");
+	    err = BadValue;
+	}
+	else
+	{
+	    /* if it's already in our active list, just reset it */
+	    /*
+	     * note that this can miss FPE's in limbo -- may be worth catching
+	     * them, though it'd muck up refcounting
+	     */
+	    fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+	    if (fpe) 
+	    {
+		err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+		if (err == Successful) 
+		{
+		    UseFPE(fpe);/* since it'll be decref'd later when freed
+				 * from the old list */
+		}
+		else
+		    fpe = 0;
+	    }
+	    /* if error or can't do it, act like it's a new one */
+	    if (!fpe)
+	    {
+		fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+		if (!fpe) 
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->name = (char *) xalloc(len + 1);
+		if (!fpe->name) 
+		{
+		    xfree(fpe);
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->refcount = 1;
+    
+		strncpy(fpe->name, (char *) cp, (int) len);
+		fpe->name[len] = '\0';
+		fpe->name_length = len;
+		fpe->type = DetermineFPEType(fpe->name);
+		if (fpe->type == -1)
+		    err = BadValue;
+		else
+		    err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+		if (err != Successful)
+		{
+		    if (persist)
+		    {
+			ErrorF("Could not init font path element %s, removing from list!\n",
+			       fpe->name);
+		    }
+		    xfree (fpe->name);
+		    xfree (fpe);
+		}
+	    }
+	}
+	if (err != Successful)
+	{
+	    if (!persist)
+		goto bail;
+	}
+	else
+	{
+	    fplist[valid_paths++] = fpe;
+	}
+	cp += len;
+    }
+
+    FreeFontPath(font_path_elements, num_fpes, FALSE);
+    font_path_elements = fplist;
+    if (patternCache)
+	EmptyFontPatternCache(patternCache);
+    num_fpes = valid_paths;
+
+    return Success;
+bail:
+    *bad = i;
+    while (--valid_paths >= 0)
+	FreeFPE(fplist[valid_paths]);
+    xfree(fplist);
+    return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(client, npaths, paths, error)
+    ClientPtr   client;
+    int         npaths;
+    unsigned char *paths;
+    int        *error;
+{
+    int   err = Success;
+
+    if (npaths == 0) {
+	if (SetDefaultFontPath(defaultFontPath) != Success)
+	    return BadValue;
+    } else {
+	err = SetFontPathElements(npaths, paths, error, FALSE);
+    }
+    return err;
+}
+
+int
+SetDefaultFontPath(path)
+    char       *path;
+{
+    unsigned char *cp,
+               *pp,
+               *nump,
+               *newpath;
+    int         num = 1,
+                len,
+                err,
+                size = 0,
+                bad;
+
+    /* get enough for string, plus values -- use up commas */
+#ifdef NX_TRANS_SOCKET
+    len = strlen(_NXGetFontPath(path)) + 1;
+#else
+    len = strlen(path) + 1;
+#endif
+    nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+    if (!newpath)
+	return BadAlloc;
+#ifdef NX_TRANS_SOCKET
+    pp = (unsigned char *) _NXGetFontPath(path);
+#else
+    pp = (unsigned char *) path;
+#endif
+    cp++;
+    while (*pp) {
+	if (*pp == ',') {
+	    *nump = (unsigned char) size;
+	    nump = cp++;
+	    pp++;
+	    num++;
+	    size = 0;
+	} else {
+	    *cp++ = *pp++;
+	    size++;
+	}
+    }
+    *nump = (unsigned char) size;
+
+    err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+    DEALLOCATE_LOCAL(newpath);
+
+    return err;
+}
+
+unsigned char *
+GetFontPath(count, length)
+    int			*count;
+    int			*length;
+{
+    int			i;
+    unsigned char       *c;
+    int			len;
+    FontPathElementPtr	fpe;
+
+    len = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	len += fpe->name_length + 1;
+    }
+    font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+    if (!font_path_string)
+	return NULL;
+
+    c = font_path_string;
+    *length = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	*c = fpe->name_length;
+	*length += *c++;
+	memmove(c, fpe->name, fpe->name_length);
+	c += fpe->name_length;
+    }
+    *count = num_fpes;
+    return font_path_string;
+}
+
+int
+LoadGlyphs(client, pfont, nchars, item_size, data)
+    ClientPtr   client;
+    FontPtr     pfont;
+    unsigned    nchars;
+    int         item_size;
+    unsigned char *data;
+{
+    if (fpe_functions[pfont->fpe->type].load_glyphs)
+	return (*fpe_functions[pfont->fpe->type].load_glyphs)
+	    (client, pfont, 0, nchars, item_size, data);
+    else
+	return Successful;
+}
+
+void
+DeleteClientFontStuff(client)
+    ClientPtr	client;
+{
+    int			i;
+    FontPathElementPtr	fpe;
+
+    for (i = 0; i < num_fpes; i++)
+    {
+	fpe = font_path_elements[i];
+	if (fpe_functions[fpe->type].client_died)
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+    }
+}
+
+void
+InitFonts ()
+{
+    patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+    if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+	PrinterFontRegisterFpeFunctions();
+	FontFileCheckRegisterFpeFunctions();
+	check_fs_register_fpe_functions();
+    } else 
+#endif
+    {
+#ifdef KDRIVESERVER
+	BuiltinRegisterFpeFunctions();
+#endif
+	FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+	fs_register_fpe_functions();
+#endif
+    }
+}
+
+int
+GetDefaultPointSize ()
+{
+    return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (num)
+    int        *num;
+{
+    if (requestingClient && requestingClient->fontResFunc != NULL &&
+	!requestingClient->clientGone)
+    {
+	return (*requestingClient->fontResFunc)(requestingClient, num);
+    }
+    else {
+	static struct _FontResolution res;
+	ScreenPtr   pScreen;
+
+	pScreen = screenInfo.screens[0];
+	res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+	/*
+	 * XXX - we'll want this as long as bitmap instances are prevalent 
+	 so that we can match them from scalable fonts
+	 */
+	if (res.x_resolution < 88)
+	    res.x_resolution = 75;
+	else
+	    res.x_resolution = 100;
+	res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+	if (res.y_resolution < 88)
+	    res.y_resolution = 75;
+	else
+	    res.y_resolution = 100;
+	res.point_size = 120;
+	*num = 1;
+	return &res;
+    }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func, 
+		     InitFpeFunc init_func, 
+		     FreeFpeFunc free_func, 
+		     ResetFpeFunc reset_func, 
+		     OpenFontFunc open_func, 
+		     CloseFontFunc close_func, 
+		     ListFontsFunc list_func, 
+		     StartLfwiFunc start_lfwi_func, 
+		     NextLfwiFunc next_lfwi_func, 
+		     WakeupFpeFunc wakeup_func, 
+		     ClientDiedFunc client_died, 
+		     LoadGlyphsFunc load_glyphs, 
+		     StartLaFunc start_list_alias_func, 
+		     NextLaFunc next_list_alias_func, 
+		     SetPathFunc set_path_func)
+{
+    FPEFunctions *new;
+
+    /* grow the list */
+    new = (FPEFunctions *) xrealloc(fpe_functions,
+				 (num_fpe_types + 1) * sizeof(FPEFunctions));
+    if (!new)
+	return -1;
+    fpe_functions = new;
+
+    fpe_functions[num_fpe_types].name_check = name_func;
+    fpe_functions[num_fpe_types].open_font = open_func;
+    fpe_functions[num_fpe_types].close_font = close_func;
+    fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+    fpe_functions[num_fpe_types].list_fonts = list_func;
+    fpe_functions[num_fpe_types].start_list_fonts_with_info =
+	start_lfwi_func;
+    fpe_functions[num_fpe_types].list_next_font_with_info =
+	next_lfwi_func;
+    fpe_functions[num_fpe_types].init_fpe = init_func;
+    fpe_functions[num_fpe_types].free_fpe = free_func;
+    fpe_functions[num_fpe_types].reset_fpe = reset_func;
+    fpe_functions[num_fpe_types].client_died = client_died;
+    fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+    fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+	start_list_alias_func;
+    fpe_functions[num_fpe_types].list_next_font_or_alias =
+	next_list_alias_func;
+    fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+    return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+    if (patternCache) {
+	FreeFontPatternCache(patternCache);
+	patternCache = 0;
+    }
+    FreeFontPath(font_path_elements, num_fpes, TRUE);
+    font_path_elements = 0;
+    num_fpes = 0;
+    xfree(fpe_functions);
+    num_fpe_types = 0;
+    fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(id)
+    XID         id;
+{
+    return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+					    SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+    return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(pfont, id)
+    FontPtr     pfont;
+    Font        id;
+{
+    return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(id)
+    Font        id;
+{
+    FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(client)
+    ClientPtr client;
+{
+    return 0;
+}
+
+static int  fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(fpe, block_handler)
+    FontPathElementPtr fpe;
+    BlockHandlerProcPtr block_handler;
+{
+    /* if server has reset, make sure the b&w handlers are reinstalled */
+    if (last_server_gen < serverGeneration) {
+	last_server_gen = serverGeneration;
+	fs_handlers_installed = 0;
+    }
+    if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+	if (!RegisterBlockAndWakeupHandlers(block_handler,
+					    FontWakeup, (pointer) 0))
+	    return AllocError;
+	fs_handlers_installed++;
+    }
+    QueueFontWakeup(fpe);
+    return Successful;
+}
+
+void
+remove_fs_handlers(fpe, block_handler, all)
+    FontPathElementPtr fpe;
+    BlockHandlerProcPtr block_handler;
+    Bool        all;
+{
+    if (all) {
+	/* remove the handlers if no one else is using them */
+	if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+	    RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+					 (pointer) 0);
+	}
+    }
+    RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+	((nbytes) == 1 ? (((bits)+7)>>3)        /* pad to 1 byte */ \
+	:(nbytes) == 2 ? ((((bits)+15)>>3)&~1)  /* pad to 2 bytes */ \
+	:(nbytes) == 4 ? ((((bits)+31)>>3)&~3)  /* pad to 4 bytes */ \
+	:(nbytes) == 8 ? ((((bits)+63)>>3)&~7)  /* pad to 8 bytes */ \
+	: 0)
+
+#define GLYPH_SIZE(ch, nbytes)          \
+	GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+			(ch)->metrics.leftSideBearing, (nbytes))
+dump_char_ascii(cip)
+    CharInfoPtr cip;
+{
+    int         r,
+                l;
+    int         bpr;
+    int         byte;
+    static unsigned maskTab[] = {
+	(1 << 7), (1 << 6), (1 << 5), (1 << 4),
+	(1 << 3), (1 << 2), (1 << 1), (1 << 0),
+    };
+
+    bpr = GLYPH_SIZE(cip, 4);
+    for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+	pointer     row = (pointer) cip->bits + r * bpr;
+
+	byte = 0;
+	for (l = 0; l <= (cip->metrics.rightSideBearing -
+			  cip->metrics.leftSideBearing); l++) {
+	    if (maskTab[l & 7] & row[l >> 3])
+		putchar('X');
+	    else
+		putchar('.');
+	}
+	putchar('\n');
+    }
+}
+
+#endif
+
+
+typedef struct
+{
+   LFclosurePtr c;
+   OFclosurePtr oc;
+} nxFs,*nxFsPtr;
+
+static Bool
+#if NeedFunctionPrototypes
+nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
+#else
+nxdoListFontsAndAliases(client, fss)
+    ClientPtr   client;
+    nxFsPtr fss;
+#endif
+{
+    LFclosurePtr c=fss->c;
+    OFclosurePtr oc=fss->oc;
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int         i;
+    int		aliascount = 0;
+    char        tmp[256];
+    tmp[0]=0;
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)nxdoListFontsAndAliases,
+			(pointer) fss);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+                    {
+                        memmove(resolved, tmpname, resolvedlen);
+                        resolved[resolvedlen] = '\0';
+                    }
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+		    {
+		       memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
+		       tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
+		       if (nxagentFontLookUp(tmp))
+		          break;
+			else tmp[0]=0;
+		    }
+		}
+		else
+		{
+		   memcpy(tmp,name,namelen>255?255:namelen);
+		   tmp[namelen>255?256:namelen]=0;
+		   if (nxagentFontLookUp(tmp))
+		      break;
+		   else tmp[0]=0;
+		}
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+                    {
+                        memmove(c->savedName, name, namelen);
+                        c->savedName[namelen] = '\0';
+                    }
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+bail:
+finish:
+    if (strlen(tmp))
+    {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+      fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
+#endif
+      memcpy(oc->fontname, tmp, strlen(tmp));
+      oc->fnamelen = strlen(tmp);
+
+      oc->origFontName = oc->fontname;
+      oc->origFontNameLen = oc->fnamelen;
+
+    }
+    else
+    {
+        for (i = 0; i < c->names->nnames; i++)
+	{
+	  if (c->names->length[i] > 255)
+	     continue;
+	  else
+	  {
+	      memcpy(tmp, c->names->names[i], c->names->length[i]);
+	      tmp[ c->names->length[i] ] = 0;
+	      if (nxagentFontLookUp(tmp) == 0)
+		continue;
+	      memcpy(oc->fontname, tmp, strlen(tmp));
+	      oc->fnamelen = strlen(tmp);
+
+              oc->origFontName = oc->fontname;
+              oc->origFontNameLen = oc->fnamelen;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
+#endif
+	      break;
+	  }
+	}
+    }
+
+    if (c->slept)
+    {
+       ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+       fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(c->names);
+    xfree(c);
+    xfree(fss);
+    if (resolved) xfree(resolved);
+
+    return doOpenFont(client, oc);
+}
+
+int
+nxOpenFont(client, fid, flags, lenfname, pfontname)
+    ClientPtr   client;
+    XID         fid;
+    Mask        flags;
+    unsigned    lenfname;
+    char       *pfontname;
+{
+    nxFsPtr      fss;
+    LFclosurePtr c;
+    OFclosurePtr oc;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
+        return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+    {
+	xfree(fss);
+	return BadAlloc;
+    }
+        c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(100);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = lenfname;
+    c->current.current_fpe = 0;
+    c->current.max_names = nxagentMaxFontNames;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+
+    oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!oc)
+    {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(fss);
+      return BadAlloc;
+    }
+    oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
+    oc->origFontName = pfontname;
+    oc->origFontNameLen = lenfname;
+    if (!oc->fontname) {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(oc);
+      xfree(fss);
+      return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    oc->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!oc->fpe_list) {
+	xfree(oc->fontname);
+	xfree(oc);
+      for (i = 0; i < c->num_fpes; i++)
+         FreeFPE(c->fpe_list[i]);
+       xfree(c->fpe_list);
+       xfree(c);
+       xfree(fss);
+       return BadAlloc;
+    }
+    memmove(oc->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	oc->fpe_list[i] = font_path_elements[i];
+	UseFPE(oc->fpe_list[i]);
+    }
+    oc->client = client;
+    oc->fontid = fid;
+    oc->current_fpe = 0;
+    oc->num_fpes = num_fpes;
+    oc->fnamelen = lenfname;
+    oc->slept = FALSE;
+    oc->flags = flags;
+    oc->non_cachable_font = cached;
+    fss->c=c;
+    fss->oc=oc;
+    nxdoListFontsAndAliases(client, fss);
+    return Success;
+}
+
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
new file mode 100644
index 000000000..83103ffd6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
@@ -0,0 +1,2883 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXdixfonts.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.27 2003/02/15 03:47:05 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+/*
+#define NXAGENT_DEBUG
+*/
+
+#ifdef DEBUG
+#include	<stdio.h>
+#endif
+
+#include "Agent.h"
+#include "Font.h"
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+char _NXFontPath[1024];
+
+/*
+ * Override the default font path and make
+ * it configurable at run time, based on
+ * the NX_FONT environment.
+ */
+
+static const char *_NXGetFontPath(const char *path)
+{
+  const char *fontEnv;
+
+    /*
+     * Check the environment only once.
+     */
+
+    if (*_NXFontPath != '\0')
+    {
+        return _NXFontPath;
+    }
+
+    fontEnv = getenv("NX_FONT");
+
+    if (fontEnv != NULL && *fontEnv != '\0')
+    {
+        if (strlen(fontEnv) + 1 > 1024)
+        {
+#ifdef NX_TRANS_TEST
+            fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
+#endif
+            goto _NXGetFontPathError;
+        }
+
+        strcpy(_NXFontPath, fontEnv);
+
+#ifdef NX_TRANS_TEST
+        fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
+#endif
+
+        return _NXFontPath;
+    }
+
+_NXGetFontPathError:
+
+    strcpy(_NXFontPath, path);
+
+#ifdef NX_TRANS_TEST
+    fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
+#endif
+
+    return _NXFontPath;
+}
+
+#endif
+
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include "xf86bigfont.h"
+#endif
+
+#define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int  num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int  num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int  num_slept_fpes = 0;
+static int  size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+    int         err;
+{
+    switch (err) {
+    case Successful:
+	return Success;
+    case AllocError:
+	return BadAlloc;
+    case BadFontName:
+	return BadName;
+    case BadFontPath:
+    case BadFontFormat:	/* is there something better? */
+    case BadCharRange:
+	return BadValue;
+    default:
+	return err;
+    }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(defaultfontname)
+    char       *defaultfontname;
+{
+    int         err;
+    FontPtr     pf;
+    XID         fid;
+
+    fid = FakeClientID(0);
+    err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+		   (unsigned) strlen(defaultfontname), defaultfontname);
+    if (err != Success)
+	return FALSE;
+    pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+    if (pf == (FontPtr) NULL)
+	return FALSE;
+    defaultFont = pf;
+    return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted.  this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(fpe)
+    FontPathElementPtr fpe;
+{
+    int         i;
+    FontPathElementPtr *new;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+	    return;
+	}
+    }
+    if (num_slept_fpes == size_slept_fpes) {
+	new = (FontPathElementPtr *)
+	    xrealloc(slept_fpes,
+		     sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+	if (!new)
+	    return;
+	slept_fpes = new;
+	size_slept_fpes += 4;
+    }
+    slept_fpes[num_slept_fpes] = fpe;
+    num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(fpe)
+    FontPathElementPtr fpe;
+{
+    int         i,
+                j;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+	    for (j = i; j < num_slept_fpes; j++) {
+		slept_fpes[j] = slept_fpes[j + 1];
+	    }
+	    num_slept_fpes--;
+	    return;
+	}
+    }
+}
+
+/* ARGSUSED */
+void
+FontWakeup(data, count, LastSelectMask)
+    pointer     data;
+    int		count;
+    pointer     LastSelectMask;
+{
+    int         i;
+    FontPathElementPtr fpe;
+
+    if (count < 0)
+	return;
+    /* wake up any fpe's that may be waiting for information */
+    for (i = 0; i < num_slept_fpes; i++) {
+	fpe = slept_fpes[i];
+	(void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+    }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+#if NeedFunctionPrototypes
+UseFPE(FontPathElementPtr fpe)
+#else
+UseFPE(fpe)
+    FontPathElementPtr fpe;
+#endif
+{
+    fpe->refcount++;
+}
+
+static void
+#if NeedFunctionPrototypes
+FreeFPE (FontPathElementPtr fpe)
+#else
+FreeFPE (fpe)
+    FontPathElementPtr	fpe;
+#endif
+{
+    fpe->refcount--;
+    if (fpe->refcount == 0) {
+	(*fpe_functions[fpe->type].free_fpe) (fpe);
+	xfree(fpe->name);
+	xfree(fpe);
+    }
+}
+
+static Bool
+#if NeedFunctionPrototypes
+doOpenFont(ClientPtr client, OFclosurePtr c)
+#else
+doOpenFont(client, c)
+    ClientPtr   client;
+    OFclosurePtr c;
+#endif
+{
+    FontPtr     pfont = NullFont;
+    FontPathElementPtr fpe = NULL;
+    ScreenPtr   pScr;
+    int         err = Successful;
+    int         i;
+    char       *alias,
+               *newname;
+    int         newlen;
+    int		aliascount = 20;
+    char nxagentOrigFontName[256];
+    int nxagentOrigFontNameLen;
+
+    /*
+     * Decide at runtime what FontFormat to use.
+     */
+    Mask FontFormat = 
+
+	((screenInfo.imageByteOrder == LSBFirst) ?
+	    BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+	((screenInfo.bitmapBitOrder == LSBFirst) ?
+	    BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+	BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+	BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+	BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+	BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+	BitmapFormatScanlinePad64 |
+#endif
+
+	BitmapFormatScanlineUnit8;
+
+
+    nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
+
+    memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
+
+    nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    while (c->current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current_fpe];
+	err = (*fpe_functions[fpe->type].open_font)
+	    ((pointer) client, fpe, c->flags,
+	     c->fontname, c->fnamelen, FontFormat,
+	     BitmapFormatMaskByte |
+	     BitmapFormatMaskBit |
+	     BitmapFormatMaskImageRectangle |
+	     BitmapFormatMaskScanLinePad |
+	     BitmapFormatMaskScanLineUnit,
+	     c->fontid, &pfont, &alias,
+	     c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+		 c->non_cachable_font :
+		 (FontPtr)0);
+
+	if (err == FontNameAlias && alias) {
+	    newlen = strlen(alias);
+	    newname = (char *) xrealloc(c->fontname, newlen);
+	    if (!newname) {
+		err = AllocError;
+		break;
+	    }
+	    memmove(newname, alias, newlen);
+	    c->fontname = newname;
+	    c->fnamelen = newlen;
+	    c->current_fpe = 0;
+	    if (--aliascount <= 0)
+		break;
+	    continue;
+	}
+	if (err == BadFontName) {
+	    c->current_fpe++;
+	    continue;
+	}
+	if (err == Suspended) {
+	    if (!c->slept) {
+		c->slept = TRUE;
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+#ifdef NXAGENT_DEBUG
+                fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
+#endif
+	    }
+	    return TRUE;
+	}
+	break;
+    }
+
+    if (err != Successful)
+	goto bail;
+    if (!pfont) {
+	err = BadFontName;
+	goto bail;
+    }
+    if (!pfont->fpe)
+	pfont->fpe = fpe;
+    pfont->refcnt++;
+    if (pfont->refcnt == 1) {
+	UseFPE(pfont->fpe);
+	for (i = 0; i < screenInfo.numScreens; i++) {
+	    pScr = screenInfo.screens[i];
+	    if (pScr->RealizeFont)
+	    {
+
+                /* NXAGENT uses useless screen pointer to pass the original font name
+                *  to realizeFont, could be a source of problems in the future.
+                */
+
+		if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+		{
+		    CloseFont (pfont, (Font) 0);
+		    err=BadFontName;
+		    goto bail;
+		}
+	    }
+	}
+    }
+    if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+	err = AllocError;
+	goto bail;
+    }
+    if( nxagentFontPriv(pfont) -> mirrorID == 0 )
+    {
+      extern RESTYPE RT_NX_FONT;
+
+      nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
+      if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
+        FreeResource(c->fontid, RT_NONE);
+        err = AllocError;
+        goto bail;
+      }
+    }
+    if (patternCache && pfont != c->non_cachable_font)
+	CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+			 pfont);
+bail:
+    if (err != Successful && c->client != serverClient) {
+	SendErrorToClient(c->client, X_OpenFont, 0,
+			  c->fontid, FontToXError(err));
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++) {
+	FreeFPE(c->fpe_list[i]);
+    }
+    xfree(c->fpe_list);
+    xfree(c->fontname);
+    xfree(c);
+    return TRUE;
+}
+
+int
+OpenFont(client, fid, flags, lenfname, pfontname)
+    ClientPtr   client;
+    XID         fid;
+    Mask        flags;
+    unsigned    lenfname;
+    char       *pfontname;
+{
+    OFclosurePtr c;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!c)
+	return BadAlloc;
+    c->fontname = (char *) xalloc(lenfname);
+    c->origFontName = pfontname;
+    c->origFontNameLen = lenfname;
+    if (!c->fontname) {
+	xfree(c);
+	return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c->fontname);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove(c->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->fontid = fid;
+    c->current_fpe = 0;
+    c->num_fpes = num_fpes;
+    c->fnamelen = lenfname;
+    c->slept = FALSE;
+    c->flags = flags;
+    c->non_cachable_font = cached;
+
+    (void) doOpenFont(client, c);
+    return Success;
+}
+
+/*
+ * Decrement font's ref count, and free storage if ref count equals zero
+ */
+/*ARGSUSED*/
+int
+CloseFont(value, fid)
+    pointer	value;  /* must conform to DeleteType */
+    XID		fid;
+{
+    int         nscr;
+    ScreenPtr   pscr;
+    FontPathElementPtr fpe;
+    FontPtr     pfont = (FontPtr)value;
+
+    if (pfont == NullFont)
+	return (Success);
+    if (--pfont->refcnt == 0) {
+	if (patternCache)
+	    RemoveCachedFontPattern (patternCache, pfont);
+	/*
+	 * since the last reference is gone, ask each screen to free any
+	 * storage it may have allocated locally for it.
+	 */
+	for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+	    pscr = screenInfo.screens[nscr];
+	    if (pscr->UnrealizeFont)
+		(*pscr->UnrealizeFont) (pscr, pfont);
+	}
+	if (pfont == defaultFont)
+	    defaultFont = NULL;
+#ifdef LBX
+	LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+        {
+           extern void XF86BigfontFreeFontShm(FontPtr);
+           XF86BigfontFreeFontShm(pfont);
+        }
+#endif
+	fpe = pfont->fpe;
+	(*fpe_functions[fpe->type].close_font) (fpe, pfont);
+	FreeFPE(fpe);
+    }
+    return (Success);
+}
+
+
+/***====================================================================***/
+
+ /*
+  * \ Sets up pReply as the correct QueryFontReply for pFont with the first
+  * nProtoCCIStructs char infos. \
+  */
+
+void
+QueryFont(pFont, pReply, nProtoCCIStructs)
+    FontPtr          pFont;
+    xQueryFontReply *pReply;	/* caller must allocate this storage */
+    int              nProtoCCIStructs;
+{
+    FontPropPtr      pFP;
+    int              r,
+                     c,
+                     i;
+    xFontProp       *prFP;
+    xCharInfo       *prCI;
+    xCharInfo       *charInfos[256];
+    unsigned char    chars[512];
+    int              ninfos;
+    unsigned long    ncols;
+    unsigned long    count;
+
+    /* pr->length set in dispatch */
+    pReply->minCharOrByte2 = pFont->info.firstCol;
+    pReply->defaultChar = pFont->info.defaultCh;
+    pReply->maxCharOrByte2 = pFont->info.lastCol;
+    pReply->drawDirection = pFont->info.drawDirection;
+    pReply->allCharsExist = pFont->info.allExist;
+    pReply->minByte1 = pFont->info.firstRow;
+    pReply->maxByte1 = pFont->info.lastRow;
+    pReply->fontAscent = pFont->info.fontAscent;
+    pReply->fontDescent = pFont->info.fontDescent;
+
+    pReply->minBounds = pFont->info.ink_minbounds;
+    pReply->maxBounds = pFont->info.ink_maxbounds;
+
+    pReply->nFontProps = pFont->info.nprops;
+    pReply->nCharInfos = nProtoCCIStructs;
+
+    for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+	    i < pFont->info.nprops;
+	    i++, pFP++, prFP++) {
+	prFP->name = pFP->name;
+	prFP->value = pFP->value;
+    }
+
+    ninfos = 0;
+    ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+    prCI = (xCharInfo *) (prFP);
+    for (r = pFont->info.firstRow;
+	    ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+	    r++) {
+	i = 0;
+	for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+	    chars[i++] = r;
+	    chars[i++] = c;
+	}
+	(*pFont->get_metrics) (pFont, ncols, chars, 
+				TwoD16Bit, &count, charInfos);
+	i = 0;
+	for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+	    *prCI = *charInfos[i];
+	    prCI++;
+	    ninfos++;
+	}
+    }
+    return;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+#else
+doListFontsAndAliases(client, c)
+    ClientPtr   client;
+    LFclosurePtr c;
+#endif
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    FontNamesPtr names = NULL;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int		nnames;
+    int         stringLens;
+    int         i;
+    xListFontsReply reply;
+    char	*bufptr;
+    char	*bufferStart;
+    int		aliascount = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)doListFontsAndAliases,
+			(pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+			memmove(resolved, tmpname, resolvedlen + 1);
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+			(void)AddFontNamesName(c->names, c->savedName,
+					       c->savedNameLen);
+		}
+		else
+		    (void)AddFontNamesName(c->names, name, namelen);
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+			memmove(c->savedName, name, namelen + 1);
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+    if (err != Successful) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+	goto bail;
+    }
+
+finish:
+
+    names = c->names;
+    nnames = names->nnames;
+    client = c->client;
+    stringLens = 0;
+    for (i = 0; i < nnames; i++)
+	stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+    reply.type = X_Reply;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    reply.nFonts = nnames;
+    reply.sequenceNumber = client->sequence;
+
+    bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+    if (!bufptr && reply.length) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+	goto bail;
+    }
+    /*
+     * since WriteToClient long word aligns things, copy to temp buffer and
+     * write all at once
+     */
+    for (i = 0; i < nnames; i++) {
+	if (names->length[i] > 255)
+	    reply.nFonts--;
+	else
+	{
+	    {
+	      /* dirty hack: don't list to client fonts not existing on the remote side */
+	      char tmp[256];
+
+	      memcpy(tmp, names->names[i], names->length[i]);
+	      tmp[ names->length[i] ] = 0;
+
+	      if (nxagentFontLookUp(tmp) == 0)
+		{
+#ifdef NXAGENT_FONTMATCH_DEBUG
+		  fprintf(stderr, "doListFontsAndAliases:\n");
+		  fprintf(stderr, "      removing font: %s \n", tmp);
+#endif
+		  reply.nFonts--;
+		  stringLens -= names->length[i];
+		  continue;
+		}
+	    }
+	    *bufptr++ = names->length[i];
+	    memmove( bufptr, names->names[i], names->length[i]);
+	    bufptr += names->length[i];
+	}
+    }
+    nnames = reply.nFonts;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+    WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+    (void) WriteToClient(client, stringLens + nnames, bufferStart);
+    DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(names);
+    xfree(c);
+    if (resolved) xfree(resolved);
+    return TRUE;
+}
+
+int
+ListFonts(client, pattern, length, max_names)
+    ClientPtr   client;
+    unsigned char *pattern;
+    unsigned int length;
+    unsigned int max_names;
+{
+    int         i;
+    LFclosurePtr c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+	return BadAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsAndAliases(client, c);
+    return Success;
+}
+
+int
+doListFontsWithInfo(client, c)
+    ClientPtr   client;
+    LFWIclosurePtr c;
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name;
+    int         namelen;
+    int         numFonts;
+    FontInfoRec fontInfo,
+               *pFontInfo;
+    xListFontsWithInfoReply *reply;
+    int         length;
+    xFontProp  *pFP;
+    int         i;
+    int		aliascount = 0;
+    xListFontsWithInfoReply finalReply;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+ 	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+    if (!c->current.patlen)
+	goto finish;
+    while (c->current.current_fpe < c->num_fpes)
+    {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+	if (!c->current.list_started)
+ 	{
+	    err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+		(client, fpe, c->current.pattern, c->current.patlen,
+		 c->current.max_names, &c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	    if (err == Successful)
+		c->current.list_started = TRUE;
+	}
+	if (err == Successful)
+ 	{
+	    name = 0;
+	    pFontInfo = &fontInfo;
+	    err = (*fpe_functions[fpe->type].list_next_font_with_info)
+		(client, fpe, &name, &namelen, &pFontInfo,
+		 &numFonts, c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doListFontsWithInfo,
+			     c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	}
+	/*
+	 * When we get an alias back, save our state and reset back to the
+	 * start of the FPE looking for the specified name.  As soon as a real
+	 * font is found for the alias, pop back to the old state
+	 */
+	if (err == FontNameAlias)
+ 	{
+	    /*
+	     * when an alias recurses, we need to give
+	     * the last FPE a chance to clean up; so we call
+	     * it again, and assume that the error returned
+	     * is BadFontName, indicating the alias resolution
+	     * is complete.
+	     */
+	    if (c->haveSaved)
+	    {
+		char	*tmpname;
+		int	tmpnamelen;
+		FontInfoPtr tmpFontInfo;
+
+	    	tmpname = 0;
+	    	tmpFontInfo = &fontInfo;
+	    	(void) (*fpe_functions[fpe->type].list_next_font_with_info)
+		    (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+		     &numFonts, c->current.private);
+		if (--aliascount <= 0)
+		{
+		    err = BadFontName;
+		    goto ContBadFontName;
+		}
+	    }
+	    else
+	    {
+		c->saved = c->current;
+		c->haveSaved = TRUE;
+		c->savedNumFonts = numFonts;
+		c->savedName = (char *) pFontInfo;
+		aliascount = 20;
+	    }
+	    memmove(c->current.pattern, name, namelen);
+	    c->current.patlen = namelen;
+	    c->current.max_names = 1;
+	    c->current.current_fpe = 0;
+	    c->current.private = 0;
+	    c->current.list_started = FALSE;
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back.  If we've sent enough font
+	 * names, quit.  Always wait for BadFontName to let the FPE
+	 * have a chance to clean up.
+	 */
+	else if (err == BadFontName)
+ 	{
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+ 	    {
+		if (c->current.max_names == 0 ||
+			c->current.current_fpe == c->num_fpes)
+ 		{
+		    c->haveSaved = FALSE;
+		    c->saved.max_names -= (1 - c->current.max_names);
+		    c->current = c->saved;
+		}
+	    }
+	    else if (c->current.max_names == 0)
+		break;
+	}
+ 	else if (err == Successful)
+ 	{
+
+	    if (c->haveSaved)
+ 	    {
+		numFonts = c->savedNumFonts;
+		name = c->savedName;
+		namelen = strlen(name);
+	    }
+
+	   if (nxagentFontLookUp(name) == 0)
+	   {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "doListFontsAndAliases (with info):\n");
+	      fprintf(stderr, "      removing font: %s \n", name);
+#endif
+	       continue;
+           }
+
+	    length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+	    reply = c->reply;
+	    if (c->length < length)
+ 	    {
+		reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+		if (!reply)
+ 		{
+		    err = AllocError;
+		    break;
+		}
+		c->reply = reply;
+		c->length = length;
+	    }
+	    reply->type = X_Reply;
+	    reply->length = (sizeof *reply - sizeof(xGenericReply) +
+			     pFontInfo->nprops * sizeof(xFontProp) +
+			     namelen + 3) >> 2;
+	    reply->sequenceNumber = client->sequence;
+	    reply->nameLength = namelen;
+	    reply->minBounds = pFontInfo->ink_minbounds;
+	    reply->maxBounds = pFontInfo->ink_maxbounds;
+	    reply->minCharOrByte2 = pFontInfo->firstCol;
+	    reply->maxCharOrByte2 = pFontInfo->lastCol;
+	    reply->defaultChar = pFontInfo->defaultCh;
+	    reply->nFontProps = pFontInfo->nprops;
+	    reply->drawDirection = pFontInfo->drawDirection;
+	    reply->minByte1 = pFontInfo->firstRow;
+	    reply->maxByte1 = pFontInfo->lastRow;
+	    reply->allCharsExist = pFontInfo->allExist;
+	    reply->fontAscent = pFontInfo->fontAscent;
+	    reply->fontDescent = pFontInfo->fontDescent;
+	    reply->nReplies = numFonts;
+	    pFP = (xFontProp *) (reply + 1);
+	    for (i = 0; i < pFontInfo->nprops; i++)
+ 	    {
+		pFP->name = pFontInfo->props[i].name;
+		pFP->value = pFontInfo->props[i].value;
+		pFP++;
+	    }
+	    WriteSwappedDataToClient(client, length, reply);
+	    (void) WriteToClient(client, namelen, name);
+	    if (pFontInfo == &fontInfo)
+ 	    {
+		xfree(fontInfo.props);
+		xfree(fontInfo.isStringProp);
+	    }
+	    --c->current.max_names;
+	}
+    }
+finish:
+    length = sizeof(xListFontsWithInfoReply);
+    bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+    finalReply.type = X_Reply;
+    finalReply.sequenceNumber = client->sequence;
+    finalReply.length = (sizeof(xListFontsWithInfoReply)
+		     - sizeof(xGenericReply)) >> 2;
+    WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->reply);
+    xfree(c->fpe_list);
+    xfree(c);
+    return TRUE;
+}
+
+int
+StartListFontsWithInfo(client, length, pattern, max_names)
+    ClientPtr   client;
+    int         length;
+    unsigned char       *pattern;
+    int         max_names;
+{
+    int		    i;
+    LFWIclosurePtr  c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+	goto badAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list)
+    {
+	xfree(c);
+	goto badAlloc;
+    }
+    memmove(c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++)
+    {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->reply = 0;
+    c->length = 0;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->savedNumFonts = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    doListFontsWithInfo(client, c);
+    return Success;
+badAlloc:
+    return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(client, c)
+    ClientPtr   client;
+    register PTclosurePtr c;
+{
+    register FontPtr pFont = c->pGC->font, oldpFont;
+    Font	fid, oldfid;
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+    FontPathElementPtr fpe;
+    GC *origGC = NULL;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+	if (c->slept)
+	{
+	    /* Client has died, but we cannot bail out right now.  We
+	       need to clean up after the work we did when going to
+	       sleep.  Setting the drawable pointer to 0 makes this
+	       happen without any attempts to render or perform other
+	       unnecessary activities.  */
+	    c->pDraw = (DrawablePtr)0;
+	}
+	else
+	{
+	    err = Success;
+	    goto bail;
+	}
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client and avoid further
+	   rendering while we clean up after ourself.  */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	c->pDraw = (DrawablePtr)0;
+    }
+
+    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+    while (c->endReq - c->pElt > TextEltHeader)
+    {
+	if (*c->pElt == FontChange)
+        {
+	    if (c->endReq - c->pElt < FontShiftSize)
+	    {
+		 err = BadLength;
+		 goto bail;
+	    }
+
+	    oldpFont = pFont;
+	    oldfid = fid;
+
+	    fid =  ((Font)*(c->pElt+4))		/* big-endian */
+		 | ((Font)*(c->pElt+3)) << 8
+		 | ((Font)*(c->pElt+2)) << 16
+		 | ((Font)*(c->pElt+1)) << 24;
+	    pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+						    SecurityReadAccess);
+	    if (!pFont)
+	    {
+		client->errorValue = fid;
+		err = BadFont;
+		/* restore pFont and fid for step 4 (described below) */
+		pFont = oldpFont;
+		fid = oldfid;
+
+		/* If we're in START_SLEEP mode, the following step
+		   shortens the request...  in the unlikely event that
+		   the fid somehow becomes valid before we come through
+		   again to actually execute the polytext, which would
+		   then mess up our refcounting scheme badly.  */
+		c->err = err;
+		c->endReq = c->pElt;
+
+		goto bail;
+	    }
+
+	    /* Step 3 (described below) on our new font */
+	    if (client_state == START_SLEEP)
+		pFont->refcnt++;
+	    else
+	    {
+		if (pFont != c->pGC->font && c->pDraw)
+		{
+		    ChangeGC( c->pGC, GCFont, &fid);
+		    ValidateGC(c->pDraw, c->pGC);
+		    if (c->reqType == X_PolyText8)
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+		    else
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+		}
+
+		/* Undo the refcnt++ we performed when going to sleep */
+		if (client_state == SLEEPING)
+		    (void)CloseFont(c->pGC->font, (Font)0);
+	    }
+	    c->pElt += FontShiftSize;
+	}
+	else	/* print a string */
+	{
+	    unsigned char *pNextElt;
+	    pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+	    if ( pNextElt > c->endReq)
+	    {
+		err = BadLength;
+		goto bail;
+	    }
+	    if (client_state == START_SLEEP)
+	    {
+		c->pElt = pNextElt;
+		continue;
+	    }
+	    if (c->pDraw)
+	    {
+		lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+				   c->pElt + TextEltHeader);
+	    }
+	    else lgerr = Successful;
+
+	    if (lgerr == Suspended)
+	    {
+		if (!c->slept) {
+		    int len;
+		    GC *pGC;
+		    PTclosurePtr new_closure;
+
+    /*  We're putting the client to sleep.  We need to do a few things
+	to ensure successful and atomic-appearing execution of the
+	remainder of the request.  First, copy the remainder of the
+	request into a safe malloc'd area.  Second, create a scratch GC
+	to use for the remainder of the request.  Third, mark all fonts
+	referenced in the remainder of the request to prevent their
+	deallocation.  Fourth, make the original GC look like the
+	request has completed...  set its font to the final font value
+	from this request.  These GC manipulations are for the unlikely
+	(but possible) event that some other client is using the GC.
+	Steps 3 and 4 are performed by running this procedure through
+	the remainder of the request in a special no-render mode
+	indicated by client_state = START_SLEEP.  */
+
+		    /* Step 1 */
+		    /* Allocate a malloc'd closure structure to replace
+		       the local one we were passed */
+		    new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+		    if (!new_closure)
+		    {
+			err = BadAlloc;
+			goto bail;
+		    }
+		    *new_closure = *c;
+		    c = new_closure;
+
+		    len = c->endReq - c->pElt;
+		    c->data = (unsigned char *)xalloc(len);
+		    if (!c->data)
+		    {
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    memmove(c->data, c->pElt, len);
+		    c->pElt = c->data;
+		    c->endReq = c->pElt + len;
+
+		    /* Step 2 */
+
+		    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+		    if (!pGC)
+		    {
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+
+                    pGC->tileIsPixel = TRUE;
+                    pGC->tile.pixel = 0;
+                    pGC->stipple = NullPixmap;
+
+		    if ((err = CopyGC(c->pGC, pGC, GCFunction |
+				      GCPlaneMask | GCForeground |
+				      GCBackground | GCFillStyle |
+				      GCTile | GCStipple |
+				      GCTileStipXOrigin |
+				      GCTileStipYOrigin | GCFont |
+				      GCSubwindowMode | GCClipXOrigin |
+				      GCClipYOrigin | GCClipMask)) !=
+				      Success)
+		    {
+			FreeScratchGC(pGC);
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    origGC = c->pGC;
+		    c->pGC = pGC;
+		    ValidateGC(c->pDraw, c->pGC);
+		    
+		    c->slept = TRUE;
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doPolyText,
+			     (pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
+#endif
+
+		    /* Set up to perform steps 3 and 4 */
+		    client_state = START_SLEEP;
+		    continue;	/* on to steps 3 and 4 */
+		}
+		return TRUE;
+	    }
+	    else if (lgerr != Successful)
+	    {
+		err = FontToXError(lgerr);
+		goto bail;
+	    }
+	    if (c->pDraw)
+	    {
+		c->xorg += *((INT8 *)(c->pElt + 1));	/* must be signed */
+		c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+		    *c->pElt, c->pElt + TextEltHeader);
+	    }
+	    c->pElt = pNextElt;
+	}
+    }
+
+bail:
+
+    if (client_state == START_SLEEP)
+    {
+	/* Step 4 */
+	if (pFont != origGC->font)
+	{
+	    ChangeGC(origGC, GCFont, &fid);
+	    ValidateGC(c->pDraw, origGC);
+	}
+
+	/* restore pElt pointer for execution of remainder of the request */
+	c->pElt = c->data;
+	return TRUE;
+    }
+
+    if (c->err != Success) err = c->err;
+    if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+        if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+PolyText(client, pDraw, pGC, pElt, endReq, xorg, yorg, reqType, did)
+    ClientPtr client;
+    DrawablePtr pDraw;
+    GC *pGC;
+    unsigned char *pElt;
+    unsigned char *endReq;
+    int xorg;
+    int yorg;
+    int reqType;
+    XID did;
+{
+    PTclosureRec local_closure;
+
+    local_closure.pElt = pElt;
+    local_closure.endReq = endReq;
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_PolyText8)
+    {
+	local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.polyText =  (PolyTextPtr) pGC->ops->PolyText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.pGC = pGC;
+    local_closure.did = did;
+    local_closure.err = Success;
+    local_closure.slept = FALSE;
+
+    (void) doPolyText(client, &local_closure);
+    return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(client, c)
+    ClientPtr   client;
+    register ITclosurePtr c;
+{
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    FontPathElementPtr fpe;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client. */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+    if (lgerr == Suspended)
+    {
+        if (!c->slept) {
+	    GC *pGC;
+	    unsigned char *data;
+	    ITclosurePtr new_closure;
+
+	    /* We're putting the client to sleep.  We need to
+	       save some state.  Similar problem to that handled
+	       in doPolyText, but much simpler because the
+	       request structure is much simpler. */
+
+	    new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+	    if (!new_closure)
+	    {
+		err = BadAlloc;
+		goto bail;
+	    }
+	    *new_closure = *c;
+	    c = new_closure;
+
+	    data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+	    if (!data)
+	    {
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    memmove(data, c->data, c->nChars * c->itemSize);
+	    c->data = data;
+
+	    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+	    if (!pGC)
+	    {
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+
+            pGC->tileIsPixel = TRUE;
+            pGC->tile.pixel = 0;
+            pGC->stipple = NullPixmap;
+
+	    if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+			      GCForeground | GCBackground | GCFillStyle |
+			      GCTile | GCStipple | GCTileStipXOrigin |
+			      GCTileStipYOrigin | GCFont |
+			      GCSubwindowMode | GCClipXOrigin |
+			      GCClipYOrigin | GCClipMask)) != Success)
+	    {
+		FreeScratchGC(pGC);
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    c->pGC = pGC;
+	    ValidateGC(c->pDraw, c->pGC);
+
+	    c->slept = TRUE;
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+#ifdef NXAGENT_DEBUG
+            fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
+#endif
+
+        }
+        return TRUE;
+    }
+    else if (lgerr != Successful)
+    {
+        err = FontToXError(lgerr);
+        goto bail;
+    }
+    if (c->pDraw)
+    {
+	(* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+	    c->nChars, c->data);
+    }
+
+bail:
+
+    if (err != Success && c->client != serverClient) {
+	SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+ImageText(client, pDraw, pGC, nChars, data, xorg, yorg, reqType, did)
+    ClientPtr client;
+    DrawablePtr pDraw;
+    GC *pGC;
+    int nChars;
+    unsigned char *data;
+    int xorg;
+    int yorg;
+    int reqType;
+    XID did;
+{
+    ITclosureRec local_closure;
+
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.pGC = pGC;
+    local_closure.nChars = nChars;
+    local_closure.data = data;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_ImageText8)
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.did = did;
+    local_closure.slept = FALSE;
+
+    (void) doImageText(client, &local_closure);
+    return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+#if NeedFunctionPrototypes
+DetermineFPEType(char *pathname)
+#else
+DetermineFPEType(pathname)
+    char       *pathname;
+#endif
+{
+    int         i;
+
+    for (i = 0; i < num_fpe_types; i++) {
+	if ((*fpe_functions[i].name_check) (pathname))
+	    return i;
+    }
+    return -1;
+}
+
+
+static void
+#if NeedFunctionPrototypes
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+#else
+FreeFontPath(list, n, force)
+    FontPathElementPtr	*list;
+    Bool		force;
+    int         n;
+#endif
+{
+    int         i;
+
+    for (i = 0; i < n; i++) {
+	if (force) {
+	    /* Sanity check that all refcounts will be 0 by the time
+	       we get to the end of the list. */
+	    int found = 1;	/* the first reference is us */
+	    int j;
+	    for (j = i+1; j < n; j++) {
+		if (list[j] == list[i])
+		    found++;
+	    }
+	    if (list[i]->refcount != found) {
+		ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+		       list[i]->name_length, list[i]->name,
+		       list[i]->refcount, found);
+		list[i]->refcount = found; /* ensure it will get freed */
+	    }
+	}
+	FreeFPE(list[i]);
+    }
+    xfree((char *) list);
+}
+
+static FontPathElementPtr
+#if NeedFunctionPrototypes
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+#else
+find_existing_fpe(list, num, name, len)
+    FontPathElementPtr *list;
+    int         num;
+    unsigned char *name;
+    int         len;
+#endif
+{
+    FontPathElementPtr fpe;
+    int         i;
+
+    for (i = 0; i < num; i++) {
+	fpe = list[i];
+	if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+	    return fpe;
+    }
+    return (FontPathElementPtr) 0;
+}
+
+
+static int
+#if NeedFunctionPrototypes
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+#else
+SetFontPathElements(npaths, paths, bad, persist)
+    int         npaths;
+    unsigned char *paths;
+    int        *bad;
+    Bool	persist;
+#endif
+{
+    int         i, err = 0;
+    int         valid_paths = 0;
+    unsigned int len;
+    unsigned char *cp = paths;
+    FontPathElementPtr fpe = NULL, *fplist;
+
+    fplist = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * npaths);
+    if (!fplist) {
+	*bad = 0;
+	return BadAlloc;
+    }
+    for (i = 0; i < num_fpe_types; i++) {
+	if (fpe_functions[i].set_path_hook)
+	    (*fpe_functions[i].set_path_hook) ();
+    }
+    for (i = 0; i < npaths; i++) 
+    {
+	len = (unsigned int) (*cp++);
+
+	if (len == 0) 
+	{
+	    if (persist)
+		ErrorF ("Removing empty element from the valid list of fontpaths\n");
+	    err = BadValue;
+	}
+	else
+	{
+	    /* if it's already in our active list, just reset it */
+	    /*
+	     * note that this can miss FPE's in limbo -- may be worth catching
+	     * them, though it'd muck up refcounting
+	     */
+	    fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+	    if (fpe) 
+	    {
+		err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+		if (err == Successful) 
+		{
+		    UseFPE(fpe);/* since it'll be decref'd later when freed
+				 * from the old list */
+		}
+		else
+		    fpe = 0;
+	    }
+	    /* if error or can't do it, act like it's a new one */
+	    if (!fpe)
+	    {
+		fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+		if (!fpe) 
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->name = (char *) xalloc(len + 1);
+		if (!fpe->name) 
+		{
+		    xfree(fpe);
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->refcount = 1;
+    
+		strncpy(fpe->name, (char *) cp, (int) len);
+		fpe->name[len] = '\0';
+		fpe->name_length = len;
+		fpe->type = DetermineFPEType(fpe->name);
+		if (fpe->type == -1)
+		    err = BadValue;
+		else
+		    err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+		if (err != Successful)
+		{
+		    if (persist)
+		    {
+			ErrorF("Could not init font path element %s, removing from list!\n",
+			       fpe->name);
+		    }
+		    xfree (fpe->name);
+		    xfree (fpe);
+		}
+	    }
+	}
+	if (err != Successful)
+	{
+	    if (!persist)
+		goto bail;
+	}
+	else
+	{
+	    fplist[valid_paths++] = fpe;
+	}
+	cp += len;
+    }
+
+    FreeFontPath(font_path_elements, num_fpes, FALSE);
+    font_path_elements = fplist;
+    if (patternCache)
+	EmptyFontPatternCache(patternCache);
+    num_fpes = valid_paths;
+
+    return Success;
+bail:
+    *bad = i;
+    while (--valid_paths >= 0)
+	FreeFPE(fplist[valid_paths]);
+    xfree(fplist);
+    return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(client, npaths, paths, error)
+    ClientPtr   client;
+    int         npaths;
+    unsigned char *paths;
+    int        *error;
+{
+    int   err = Success;
+
+    if (npaths == 0) {
+	if (SetDefaultFontPath(defaultFontPath) != Success)
+	    return BadValue;
+    } else {
+	err = SetFontPathElements(npaths, paths, error, FALSE);
+    }
+    return err;
+}
+
+int
+SetDefaultFontPath(path)
+    char       *path;
+{
+    unsigned char *cp,
+               *pp,
+               *nump,
+               *newpath;
+    int         num = 1,
+                len,
+                err,
+                size = 0,
+                bad;
+
+    /* get enough for string, plus values -- use up commas */
+#ifdef NX_TRANS_SOCKET
+    len = strlen(_NXGetFontPath(path)) + 1;
+#else
+    len = strlen(path) + 1;
+#endif
+    nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+    if (!newpath)
+	return BadAlloc;
+#ifdef NX_TRANS_SOCKET
+    pp = (unsigned char *) _NXGetFontPath(path);
+#else
+    pp = (unsigned char *) path;
+#endif
+    cp++;
+    while (*pp) {
+	if (*pp == ',') {
+	    *nump = (unsigned char) size;
+	    nump = cp++;
+	    pp++;
+	    num++;
+	    size = 0;
+	} else {
+	    *cp++ = *pp++;
+	    size++;
+	}
+    }
+    *nump = (unsigned char) size;
+
+    err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+    DEALLOCATE_LOCAL(newpath);
+
+    return err;
+}
+
+unsigned char *
+GetFontPath(count, length)
+    int			*count;
+    int			*length;
+{
+    int			i;
+    unsigned char       *c;
+    int			len;
+    FontPathElementPtr	fpe;
+
+    len = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	len += fpe->name_length + 1;
+    }
+    font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+    if (!font_path_string)
+	return NULL;
+
+    c = font_path_string;
+    *length = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	*c = fpe->name_length;
+	*length += *c++;
+	memmove(c, fpe->name, fpe->name_length);
+	c += fpe->name_length;
+    }
+    *count = num_fpes;
+    return font_path_string;
+}
+
+int
+LoadGlyphs(client, pfont, nchars, item_size, data)
+    ClientPtr   client;
+    FontPtr     pfont;
+    unsigned    nchars;
+    int         item_size;
+    unsigned char *data;
+{
+    if (fpe_functions[pfont->fpe->type].load_glyphs)
+	return (*fpe_functions[pfont->fpe->type].load_glyphs)
+	    (client, pfont, 0, nchars, item_size, data);
+    else
+	return Successful;
+}
+
+void
+DeleteClientFontStuff(client)
+    ClientPtr	client;
+{
+    int			i;
+    FontPathElementPtr	fpe;
+
+    for (i = 0; i < num_fpes; i++)
+    {
+	fpe = font_path_elements[i];
+	if (fpe_functions[fpe->type].client_died)
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+    }
+}
+
+void
+InitFonts ()
+{
+    patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+    if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+	PrinterFontRegisterFpeFunctions();
+	FontFileCheckRegisterFpeFunctions();
+	check_fs_register_fpe_functions();
+    } else 
+#endif
+    {
+#ifdef KDRIVESERVER
+	BuiltinRegisterFpeFunctions();
+#endif
+	FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+	fs_register_fpe_functions();
+#endif
+    }
+}
+
+int
+GetDefaultPointSize ()
+{
+    return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (num)
+    int        *num;
+{
+    if (requestingClient && requestingClient->fontResFunc != NULL &&
+	!requestingClient->clientGone)
+    {
+	return (*requestingClient->fontResFunc)(requestingClient, num);
+    }
+    else {
+	static struct _FontResolution res;
+	ScreenPtr   pScreen;
+
+	pScreen = screenInfo.screens[0];
+	res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+	/*
+	 * XXX - we'll want this as long as bitmap instances are prevalent 
+	 so that we can match them from scalable fonts
+	 */
+	if (res.x_resolution < 88)
+	    res.x_resolution = 75;
+	else
+	    res.x_resolution = 100;
+	res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+	if (res.y_resolution < 88)
+	    res.y_resolution = 75;
+	else
+	    res.y_resolution = 100;
+	res.point_size = 120;
+	*num = 1;
+	return &res;
+    }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func, 
+		     InitFpeFunc init_func, 
+		     FreeFpeFunc free_func, 
+		     ResetFpeFunc reset_func, 
+		     OpenFontFunc open_func, 
+		     CloseFontFunc close_func, 
+		     ListFontsFunc list_func, 
+		     StartLfwiFunc start_lfwi_func, 
+		     NextLfwiFunc next_lfwi_func, 
+		     WakeupFpeFunc wakeup_func, 
+		     ClientDiedFunc client_died, 
+		     LoadGlyphsFunc load_glyphs, 
+		     StartLaFunc start_list_alias_func, 
+		     NextLaFunc next_list_alias_func, 
+		     SetPathFunc set_path_func)
+{
+    FPEFunctions *new;
+
+    /* grow the list */
+    new = (FPEFunctions *) xrealloc(fpe_functions,
+				 (num_fpe_types + 1) * sizeof(FPEFunctions));
+    if (!new)
+	return -1;
+    fpe_functions = new;
+
+    fpe_functions[num_fpe_types].name_check = name_func;
+    fpe_functions[num_fpe_types].open_font = open_func;
+    fpe_functions[num_fpe_types].close_font = close_func;
+    fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+    fpe_functions[num_fpe_types].list_fonts = list_func;
+    fpe_functions[num_fpe_types].start_list_fonts_with_info =
+	start_lfwi_func;
+    fpe_functions[num_fpe_types].list_next_font_with_info =
+	next_lfwi_func;
+    fpe_functions[num_fpe_types].init_fpe = init_func;
+    fpe_functions[num_fpe_types].free_fpe = free_func;
+    fpe_functions[num_fpe_types].reset_fpe = reset_func;
+    fpe_functions[num_fpe_types].client_died = client_died;
+    fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+    fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+	start_list_alias_func;
+    fpe_functions[num_fpe_types].list_next_font_or_alias =
+	next_list_alias_func;
+    fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+    return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+    if (patternCache) {
+	FreeFontPatternCache(patternCache);
+	patternCache = 0;
+    }
+    FreeFontPath(font_path_elements, num_fpes, TRUE);
+    font_path_elements = 0;
+    num_fpes = 0;
+    xfree(fpe_functions);
+    num_fpe_types = 0;
+    fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(id)
+    XID         id;
+{
+    return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+					    SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+    return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(pfont, id)
+    FontPtr     pfont;
+    Font        id;
+{
+    return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(id)
+    Font        id;
+{
+    FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(client)
+    ClientPtr client;
+{
+    return 0;
+}
+
+static int  fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(fpe, block_handler)
+    FontPathElementPtr fpe;
+    BlockHandlerProcPtr block_handler;
+{
+    /* if server has reset, make sure the b&w handlers are reinstalled */
+    if (last_server_gen < serverGeneration) {
+	last_server_gen = serverGeneration;
+	fs_handlers_installed = 0;
+    }
+    if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+	if (!RegisterBlockAndWakeupHandlers(block_handler,
+					    FontWakeup, (pointer) 0))
+	    return AllocError;
+	fs_handlers_installed++;
+    }
+    QueueFontWakeup(fpe);
+    return Successful;
+}
+
+void
+remove_fs_handlers(fpe, block_handler, all)
+    FontPathElementPtr fpe;
+    BlockHandlerProcPtr block_handler;
+    Bool        all;
+{
+    if (all) {
+	/* remove the handlers if no one else is using them */
+	if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+	    RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+					 (pointer) 0);
+	}
+    }
+    RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+	((nbytes) == 1 ? (((bits)+7)>>3)        /* pad to 1 byte */ \
+	:(nbytes) == 2 ? ((((bits)+15)>>3)&~1)  /* pad to 2 bytes */ \
+	:(nbytes) == 4 ? ((((bits)+31)>>3)&~3)  /* pad to 4 bytes */ \
+	:(nbytes) == 8 ? ((((bits)+63)>>3)&~7)  /* pad to 8 bytes */ \
+	: 0)
+
+#define GLYPH_SIZE(ch, nbytes)          \
+	GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+			(ch)->metrics.leftSideBearing, (nbytes))
+dump_char_ascii(cip)
+    CharInfoPtr cip;
+{
+    int         r,
+                l;
+    int         bpr;
+    int         byte;
+    static unsigned maskTab[] = {
+	(1 << 7), (1 << 6), (1 << 5), (1 << 4),
+	(1 << 3), (1 << 2), (1 << 1), (1 << 0),
+    };
+
+    bpr = GLYPH_SIZE(cip, 4);
+    for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+	pointer     row = (pointer) cip->bits + r * bpr;
+
+	byte = 0;
+	for (l = 0; l <= (cip->metrics.rightSideBearing -
+			  cip->metrics.leftSideBearing); l++) {
+	    if (maskTab[l & 7] & row[l >> 3])
+		putchar('X');
+	    else
+		putchar('.');
+	}
+	putchar('\n');
+    }
+}
+
+#endif
+
+
+typedef struct
+{
+   LFclosurePtr c;
+   OFclosurePtr oc;
+} nxFs,*nxFsPtr;
+
+static Bool
+#if NeedFunctionPrototypes
+nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
+#else
+nxdoListFontsAndAliases(client, fss)
+    ClientPtr   client;
+    nxFsPtr fss;
+#endif
+{
+    LFclosurePtr c=fss->c;
+    OFclosurePtr oc=fss->oc;
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int         i;
+    int		aliascount = 0;
+    char        tmp[256];
+    tmp[0]=0;
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)nxdoListFontsAndAliases,
+			(pointer) fss);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+                    {
+                        memmove(resolved, tmpname, resolvedlen);
+                        resolved[resolvedlen] = '\0';
+                    }
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+		    {
+		       memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
+		       tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
+		       if (nxagentFontLookUp(tmp))
+		          break;
+			else tmp[0]=0;
+		    }
+		}
+		else
+		{
+		   memcpy(tmp,name,namelen>255?255:namelen);
+		   tmp[namelen>255?256:namelen]=0;
+		   if (nxagentFontLookUp(tmp))
+		      break;
+		   else tmp[0]=0;
+		}
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+                    {
+                        memmove(c->savedName, name, namelen);
+                        c->savedName[namelen] = '\0';
+                    }
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+bail:
+finish:
+    if (strlen(tmp))
+    {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+      fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
+#endif
+      memcpy(oc->fontname, tmp, strlen(tmp));
+      oc->fnamelen = strlen(tmp);
+
+      oc->origFontName = oc->fontname;
+      oc->origFontNameLen = oc->fnamelen;
+
+    }
+    else
+    {
+        for (i = 0; i < c->names->nnames; i++)
+	{
+	  if (c->names->length[i] > 255)
+	     continue;
+	  else
+	  {
+	      memcpy(tmp, c->names->names[i], c->names->length[i]);
+	      tmp[ c->names->length[i] ] = 0;
+	      if (nxagentFontLookUp(tmp) == 0)
+		continue;
+	      memcpy(oc->fontname, tmp, strlen(tmp));
+	      oc->fnamelen = strlen(tmp);
+
+              oc->origFontName = oc->fontname;
+              oc->origFontNameLen = oc->fnamelen;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
+#endif
+	      break;
+	  }
+	}
+    }
+
+    if (c->slept)
+    {
+       ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+       fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(c->names);
+    xfree(c);
+    xfree(fss);
+    if (resolved) xfree(resolved);
+
+    return doOpenFont(client, oc);
+}
+
+int
+nxOpenFont(client, fid, flags, lenfname, pfontname)
+    ClientPtr   client;
+    XID         fid;
+    Mask        flags;
+    unsigned    lenfname;
+    char       *pfontname;
+{
+    nxFsPtr      fss;
+    LFclosurePtr c;
+    OFclosurePtr oc;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
+        return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+    {
+	xfree(fss);
+	return BadAlloc;
+    }
+        c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(100);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = lenfname;
+    c->current.current_fpe = 0;
+    c->current.max_names = nxagentMaxFontNames;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+
+    oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!oc)
+    {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(fss);
+      return BadAlloc;
+    }
+    oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
+    oc->origFontName = pfontname;
+    oc->origFontNameLen = lenfname;
+    if (!oc->fontname) {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(oc);
+      xfree(fss);
+      return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    oc->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!oc->fpe_list) {
+	xfree(oc->fontname);
+	xfree(oc);
+      for (i = 0; i < c->num_fpes; i++)
+         FreeFPE(c->fpe_list[i]);
+       xfree(c->fpe_list);
+       xfree(c);
+       xfree(fss);
+       return BadAlloc;
+    }
+    memmove(oc->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	oc->fpe_list[i] = font_path_elements[i];
+	UseFPE(oc->fpe_list[i]);
+    }
+    oc->client = client;
+    oc->fontid = fid;
+    oc->current_fpe = 0;
+    oc->num_fpes = num_fpes;
+    oc->fnamelen = lenfname;
+    oc->slept = FALSE;
+    oc->flags = flags;
+    oc->non_cachable_font = cached;
+    fss->c=c;
+    fss->oc=oc;
+    nxdoListFontsAndAliases(client, fss);
+    return Success;
+}
+
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.XF86.original
new file mode 100644
index 000000000..5386c908b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.XF86.original
@@ -0,0 +1,2223 @@
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.27 2003/02/15 03:47:05 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+#ifdef DEBUG
+#include	<stdio.h>
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include "xf86bigfont.h"
+#endif
+
+#define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int  num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int  num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int  num_slept_fpes = 0;
+static int  size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+    int         err;
+{
+    switch (err) {
+    case Successful:
+	return Success;
+    case AllocError:
+	return BadAlloc;
+    case BadFontName:
+	return BadName;
+    case BadFontPath:
+    case BadFontFormat:	/* is there something better? */
+    case BadCharRange:
+	return BadValue;
+    default:
+	return err;
+    }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(defaultfontname)
+    char       *defaultfontname;
+{
+    int         err;
+    FontPtr     pf;
+    XID         fid;
+
+    fid = FakeClientID(0);
+    err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+		   (unsigned) strlen(defaultfontname), defaultfontname);
+    if (err != Success)
+	return FALSE;
+    pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+    if (pf == (FontPtr) NULL)
+	return FALSE;
+    defaultFont = pf;
+    return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted.  this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(fpe)
+    FontPathElementPtr fpe;
+{
+    int         i;
+    FontPathElementPtr *new;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+	    return;
+	}
+    }
+    if (num_slept_fpes == size_slept_fpes) {
+	new = (FontPathElementPtr *)
+	    xrealloc(slept_fpes,
+		     sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+	if (!new)
+	    return;
+	slept_fpes = new;
+	size_slept_fpes += 4;
+    }
+    slept_fpes[num_slept_fpes] = fpe;
+    num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(fpe)
+    FontPathElementPtr fpe;
+{
+    int         i,
+                j;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+	    for (j = i; j < num_slept_fpes; j++) {
+		slept_fpes[j] = slept_fpes[j + 1];
+	    }
+	    num_slept_fpes--;
+	    return;
+	}
+    }
+}
+
+/* ARGSUSED */
+void
+FontWakeup(data, count, LastSelectMask)
+    pointer     data;
+    int		count;
+    pointer     LastSelectMask;
+{
+    int         i;
+    FontPathElementPtr fpe;
+
+    if (count < 0)
+	return;
+    /* wake up any fpe's that may be waiting for information */
+    for (i = 0; i < num_slept_fpes; i++) {
+	fpe = slept_fpes[i];
+	(void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+    }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+#if NeedFunctionPrototypes
+UseFPE(FontPathElementPtr fpe)
+#else
+UseFPE(fpe)
+    FontPathElementPtr fpe;
+#endif
+{
+    fpe->refcount++;
+}
+
+static void
+#if NeedFunctionPrototypes
+FreeFPE (FontPathElementPtr fpe)
+#else
+FreeFPE (fpe)
+    FontPathElementPtr	fpe;
+#endif
+{
+    fpe->refcount--;
+    if (fpe->refcount == 0) {
+	(*fpe_functions[fpe->type].free_fpe) (fpe);
+	xfree(fpe->name);
+	xfree(fpe);
+    }
+}
+
+static Bool
+#if NeedFunctionPrototypes
+doOpenFont(ClientPtr client, OFclosurePtr c)
+#else
+doOpenFont(client, c)
+    ClientPtr   client;
+    OFclosurePtr c;
+#endif
+{
+    FontPtr     pfont = NullFont;
+    FontPathElementPtr fpe = NULL;
+    ScreenPtr   pScr;
+    int         err = Successful;
+    int         i;
+    char       *alias,
+               *newname;
+    int         newlen;
+    int		aliascount = 20;
+    /*
+     * Decide at runtime what FontFormat to use.
+     */
+    Mask FontFormat = 
+
+	((screenInfo.imageByteOrder == LSBFirst) ?
+	    BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+	((screenInfo.bitmapBitOrder == LSBFirst) ?
+	    BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+	BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+	BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+	BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+	BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+	BitmapFormatScanlinePad64 |
+#endif
+
+	BitmapFormatScanlineUnit8;
+
+    if (client->clientGone)
+    {
+	if (c->current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    while (c->current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current_fpe];
+	err = (*fpe_functions[fpe->type].open_font)
+	    ((pointer) client, fpe, c->flags,
+	     c->fontname, c->fnamelen, FontFormat,
+	     BitmapFormatMaskByte |
+	     BitmapFormatMaskBit |
+	     BitmapFormatMaskImageRectangle |
+	     BitmapFormatMaskScanLinePad |
+	     BitmapFormatMaskScanLineUnit,
+	     c->fontid, &pfont, &alias,
+	     c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+		 c->non_cachable_font :
+		 (FontPtr)0);
+
+	if (err == FontNameAlias && alias) {
+	    newlen = strlen(alias);
+	    newname = (char *) xrealloc(c->fontname, newlen);
+	    if (!newname) {
+		err = AllocError;
+		break;
+	    }
+	    memmove(newname, alias, newlen);
+	    c->fontname = newname;
+	    c->fnamelen = newlen;
+	    c->current_fpe = 0;
+	    if (--aliascount <= 0)
+		break;
+	    continue;
+	}
+	if (err == BadFontName) {
+	    c->current_fpe++;
+	    continue;
+	}
+	if (err == Suspended) {
+	    if (!c->slept) {
+		c->slept = TRUE;
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+	    }
+	    return TRUE;
+	}
+	break;
+    }
+
+    if (err != Successful)
+	goto bail;
+    if (!pfont) {
+	err = BadFontName;
+	goto bail;
+    }
+    if (!pfont->fpe)
+	pfont->fpe = fpe;
+    pfont->refcnt++;
+    if (pfont->refcnt == 1) {
+	UseFPE(pfont->fpe);
+	for (i = 0; i < screenInfo.numScreens; i++) {
+	    pScr = screenInfo.screens[i];
+	    if (pScr->RealizeFont)
+	    {
+		if (!(*pScr->RealizeFont) (pScr, pfont))
+		{
+		    CloseFont (pfont, (Font) 0);
+		    err = AllocError;
+		    goto bail;
+		}
+	    }
+	}
+    }
+    if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+	err = AllocError;
+	goto bail;
+    }
+    if (patternCache && pfont != c->non_cachable_font)
+	CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
+			 pfont);
+bail:
+    if (err != Successful && c->client != serverClient) {
+	SendErrorToClient(c->client, X_OpenFont, 0,
+			  c->fontid, FontToXError(err));
+    }
+    if (c->slept)
+	ClientWakeup(c->client);
+    for (i = 0; i < c->num_fpes; i++) {
+	FreeFPE(c->fpe_list[i]);
+    }
+    xfree(c->fpe_list);
+    xfree(c->fontname);
+    xfree(c);
+    return TRUE;
+}
+
+int
+OpenFont(client, fid, flags, lenfname, pfontname)
+    ClientPtr   client;
+    XID         fid;
+    Mask        flags;
+    unsigned    lenfname;
+    char       *pfontname;
+{
+    OFclosurePtr c;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!c)
+	return BadAlloc;
+    c->fontname = (char *) xalloc(lenfname);
+    c->origFontName = pfontname;
+    c->origFontNameLen = lenfname;
+    if (!c->fontname) {
+	xfree(c);
+	return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c->fontname);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove(c->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->fontid = fid;
+    c->current_fpe = 0;
+    c->num_fpes = num_fpes;
+    c->fnamelen = lenfname;
+    c->slept = FALSE;
+    c->flags = flags;
+    c->non_cachable_font = cached;
+
+    (void) doOpenFont(client, c);
+    return Success;
+}
+
+/*
+ * Decrement font's ref count, and free storage if ref count equals zero
+ */
+/*ARGSUSED*/
+int
+CloseFont(value, fid)
+    pointer	value;  /* must conform to DeleteType */
+    XID		fid;
+{
+    int         nscr;
+    ScreenPtr   pscr;
+    FontPathElementPtr fpe;
+    FontPtr     pfont = (FontPtr)value;
+
+    if (pfont == NullFont)
+	return (Success);
+    if (--pfont->refcnt == 0) {
+	if (patternCache)
+	    RemoveCachedFontPattern (patternCache, pfont);
+	/*
+	 * since the last reference is gone, ask each screen to free any
+	 * storage it may have allocated locally for it.
+	 */
+	for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+	    pscr = screenInfo.screens[nscr];
+	    if (pscr->UnrealizeFont)
+		(*pscr->UnrealizeFont) (pscr, pfont);
+	}
+	if (pfont == defaultFont)
+	    defaultFont = NULL;
+#ifdef LBX
+	LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+	XF86BigfontFreeFontShm(pfont);
+#endif
+	fpe = pfont->fpe;
+	(*fpe_functions[fpe->type].close_font) (fpe, pfont);
+	FreeFPE(fpe);
+    }
+    return (Success);
+}
+
+
+/***====================================================================***/
+
+ /*
+  * \ Sets up pReply as the correct QueryFontReply for pFont with the first
+  * nProtoCCIStructs char infos. \
+  */
+
+void
+QueryFont(pFont, pReply, nProtoCCIStructs)
+    FontPtr          pFont;
+    xQueryFontReply *pReply;	/* caller must allocate this storage */
+    int              nProtoCCIStructs;
+{
+    FontPropPtr      pFP;
+    int              r,
+                     c,
+                     i;
+    xFontProp       *prFP;
+    xCharInfo       *prCI;
+    xCharInfo       *charInfos[256];
+    unsigned char    chars[512];
+    int              ninfos;
+    unsigned long    ncols;
+    unsigned long    count;
+
+    /* pr->length set in dispatch */
+    pReply->minCharOrByte2 = pFont->info.firstCol;
+    pReply->defaultChar = pFont->info.defaultCh;
+    pReply->maxCharOrByte2 = pFont->info.lastCol;
+    pReply->drawDirection = pFont->info.drawDirection;
+    pReply->allCharsExist = pFont->info.allExist;
+    pReply->minByte1 = pFont->info.firstRow;
+    pReply->maxByte1 = pFont->info.lastRow;
+    pReply->fontAscent = pFont->info.fontAscent;
+    pReply->fontDescent = pFont->info.fontDescent;
+
+    pReply->minBounds = pFont->info.ink_minbounds;
+    pReply->maxBounds = pFont->info.ink_maxbounds;
+
+    pReply->nFontProps = pFont->info.nprops;
+    pReply->nCharInfos = nProtoCCIStructs;
+
+    for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+	    i < pFont->info.nprops;
+	    i++, pFP++, prFP++) {
+	prFP->name = pFP->name;
+	prFP->value = pFP->value;
+    }
+
+    ninfos = 0;
+    ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+    prCI = (xCharInfo *) (prFP);
+    for (r = pFont->info.firstRow;
+	    ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+	    r++) {
+	i = 0;
+	for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+	    chars[i++] = r;
+	    chars[i++] = c;
+	}
+	(*pFont->get_metrics) (pFont, ncols, chars, 
+				TwoD16Bit, &count, charInfos);
+	i = 0;
+	for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+	    *prCI = *charInfos[i];
+	    prCI++;
+	    ninfos++;
+	}
+    }
+    return;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+#else
+doListFontsAndAliases(client, c)
+    ClientPtr   client;
+    LFclosurePtr c;
+#endif
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    FontNamesPtr names = NULL;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int		nnames;
+    int         stringLens;
+    int         i;
+    xListFontsReply reply;
+    char	*bufptr;
+    char	*bufferStart;
+    int		aliascount = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)doListFontsAndAliases,
+			(pointer) c);
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+			memmove(resolved, tmpname, resolvedlen + 1);
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+			(void)AddFontNamesName(c->names, c->savedName,
+					       c->savedNameLen);
+		}
+		else
+		    (void)AddFontNamesName(c->names, name, namelen);
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+			memmove(c->savedName, name, namelen + 1);
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+    if (err != Successful) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+	goto bail;
+    }
+
+finish:
+
+    names = c->names;
+    nnames = names->nnames;
+    client = c->client;
+    stringLens = 0;
+    for (i = 0; i < nnames; i++)
+	stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+    reply.type = X_Reply;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    reply.nFonts = nnames;
+    reply.sequenceNumber = client->sequence;
+
+    bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+    if (!bufptr && reply.length) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+	goto bail;
+    }
+    /*
+     * since WriteToClient long word aligns things, copy to temp buffer and
+     * write all at once
+     */
+    for (i = 0; i < nnames; i++) {
+	if (names->length[i] > 255)
+	    reply.nFonts--;
+	else
+	{
+	    *bufptr++ = names->length[i];
+	    memmove( bufptr, names->names[i], names->length[i]);
+	    bufptr += names->length[i];
+	}
+    }
+    nnames = reply.nFonts;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+    WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+    (void) WriteToClient(client, stringLens + nnames, bufferStart);
+    DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+    if (c->slept)
+	ClientWakeup(client);
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(names);
+    xfree(c);
+    if (resolved) xfree(resolved);
+    return TRUE;
+}
+
+int
+ListFonts(client, pattern, length, max_names)
+    ClientPtr   client;
+    unsigned char *pattern;
+    unsigned int length;
+    unsigned int max_names;
+{
+    int         i;
+    LFclosurePtr c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+	return BadAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsAndAliases(client, c);
+    return Success;
+}
+
+int
+doListFontsWithInfo(client, c)
+    ClientPtr   client;
+    LFWIclosurePtr c;
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name;
+    int         namelen;
+    int         numFonts;
+    FontInfoRec fontInfo,
+               *pFontInfo;
+    xListFontsWithInfoReply *reply;
+    int         length;
+    xFontProp  *pFP;
+    int         i;
+    int		aliascount = 0;
+    xListFontsWithInfoReply finalReply;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+ 	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+    if (!c->current.patlen)
+	goto finish;
+    while (c->current.current_fpe < c->num_fpes)
+    {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+	if (!c->current.list_started)
+ 	{
+	    err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+		(client, fpe, c->current.pattern, c->current.patlen,
+		 c->current.max_names, &c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+		    c->slept = TRUE;
+		}
+		return TRUE;
+	    }
+	    if (err == Successful)
+		c->current.list_started = TRUE;
+	}
+	if (err == Successful)
+ 	{
+	    name = 0;
+	    pFontInfo = &fontInfo;
+	    err = (*fpe_functions[fpe->type].list_next_font_with_info)
+		(client, fpe, &name, &namelen, &pFontInfo,
+		 &numFonts, c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doListFontsWithInfo,
+			     c);
+		    c->slept = TRUE;
+		}
+		return TRUE;
+	    }
+	}
+	/*
+	 * When we get an alias back, save our state and reset back to the
+	 * start of the FPE looking for the specified name.  As soon as a real
+	 * font is found for the alias, pop back to the old state
+	 */
+	if (err == FontNameAlias)
+ 	{
+	    /*
+	     * when an alias recurses, we need to give
+	     * the last FPE a chance to clean up; so we call
+	     * it again, and assume that the error returned
+	     * is BadFontName, indicating the alias resolution
+	     * is complete.
+	     */
+	    if (c->haveSaved)
+	    {
+		char	*tmpname;
+		int	tmpnamelen;
+		FontInfoPtr tmpFontInfo;
+
+	    	tmpname = 0;
+	    	tmpFontInfo = &fontInfo;
+	    	(void) (*fpe_functions[fpe->type].list_next_font_with_info)
+		    (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+		     &numFonts, c->current.private);
+		if (--aliascount <= 0)
+		{
+		    err = BadFontName;
+		    goto ContBadFontName;
+		}
+	    }
+	    else
+	    {
+		c->saved = c->current;
+		c->haveSaved = TRUE;
+		c->savedNumFonts = numFonts;
+		c->savedName = (char *) pFontInfo;
+		aliascount = 20;
+	    }
+	    memmove(c->current.pattern, name, namelen);
+	    c->current.patlen = namelen;
+	    c->current.max_names = 1;
+	    c->current.current_fpe = 0;
+	    c->current.private = 0;
+	    c->current.list_started = FALSE;
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back.  If we've sent enough font
+	 * names, quit.  Always wait for BadFontName to let the FPE
+	 * have a chance to clean up.
+	 */
+	else if (err == BadFontName)
+ 	{
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+ 	    {
+		if (c->current.max_names == 0 ||
+			c->current.current_fpe == c->num_fpes)
+ 		{
+		    c->haveSaved = FALSE;
+		    c->saved.max_names -= (1 - c->current.max_names);
+		    c->current = c->saved;
+		}
+	    }
+	    else if (c->current.max_names == 0)
+		break;
+	}
+ 	else if (err == Successful)
+ 	{
+	    length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+	    reply = c->reply;
+	    if (c->length < length)
+ 	    {
+		reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+		if (!reply)
+ 		{
+		    err = AllocError;
+		    break;
+		}
+		c->reply = reply;
+		c->length = length;
+	    }
+	    if (c->haveSaved)
+ 	    {
+		numFonts = c->savedNumFonts;
+		name = c->savedName;
+		namelen = strlen(name);
+	    }
+	    reply->type = X_Reply;
+	    reply->length = (sizeof *reply - sizeof(xGenericReply) +
+			     pFontInfo->nprops * sizeof(xFontProp) +
+			     namelen + 3) >> 2;
+	    reply->sequenceNumber = client->sequence;
+	    reply->nameLength = namelen;
+	    reply->minBounds = pFontInfo->ink_minbounds;
+	    reply->maxBounds = pFontInfo->ink_maxbounds;
+	    reply->minCharOrByte2 = pFontInfo->firstCol;
+	    reply->maxCharOrByte2 = pFontInfo->lastCol;
+	    reply->defaultChar = pFontInfo->defaultCh;
+	    reply->nFontProps = pFontInfo->nprops;
+	    reply->drawDirection = pFontInfo->drawDirection;
+	    reply->minByte1 = pFontInfo->firstRow;
+	    reply->maxByte1 = pFontInfo->lastRow;
+	    reply->allCharsExist = pFontInfo->allExist;
+	    reply->fontAscent = pFontInfo->fontAscent;
+	    reply->fontDescent = pFontInfo->fontDescent;
+	    reply->nReplies = numFonts;
+	    pFP = (xFontProp *) (reply + 1);
+	    for (i = 0; i < pFontInfo->nprops; i++)
+ 	    {
+		pFP->name = pFontInfo->props[i].name;
+		pFP->value = pFontInfo->props[i].value;
+		pFP++;
+	    }
+	    WriteSwappedDataToClient(client, length, reply);
+	    (void) WriteToClient(client, namelen, name);
+	    if (pFontInfo == &fontInfo)
+ 	    {
+		xfree(fontInfo.props);
+		xfree(fontInfo.isStringProp);
+	    }
+	    --c->current.max_names;
+	}
+    }
+finish:
+    length = sizeof(xListFontsWithInfoReply);
+    bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+    finalReply.type = X_Reply;
+    finalReply.sequenceNumber = client->sequence;
+    finalReply.length = (sizeof(xListFontsWithInfoReply)
+		     - sizeof(xGenericReply)) >> 2;
+    WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+    if (c->slept)
+	ClientWakeup(client);
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->reply);
+    xfree(c->fpe_list);
+    xfree(c);
+    return TRUE;
+}
+
+int
+StartListFontsWithInfo(client, length, pattern, max_names)
+    ClientPtr   client;
+    int         length;
+    unsigned char       *pattern;
+    int         max_names;
+{
+    int		    i;
+    LFWIclosurePtr  c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+	goto badAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list)
+    {
+	xfree(c);
+	goto badAlloc;
+    }
+    memmove(c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++)
+    {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->reply = 0;
+    c->length = 0;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->savedNumFonts = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    doListFontsWithInfo(client, c);
+    return Success;
+badAlloc:
+    return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(client, c)
+    ClientPtr   client;
+    register PTclosurePtr c;
+{
+    register FontPtr pFont = c->pGC->font, oldpFont;
+    Font	fid, oldfid;
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+    FontPathElementPtr fpe;
+    GC *origGC = NULL;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+	if (c->slept)
+	{
+	    /* Client has died, but we cannot bail out right now.  We
+	       need to clean up after the work we did when going to
+	       sleep.  Setting the drawable pointer to 0 makes this
+	       happen without any attempts to render or perform other
+	       unnecessary activities.  */
+	    c->pDraw = (DrawablePtr)0;
+	}
+	else
+	{
+	    err = Success;
+	    goto bail;
+	}
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client and avoid further
+	   rendering while we clean up after ourself.  */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	c->pDraw = (DrawablePtr)0;
+    }
+
+    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+    while (c->endReq - c->pElt > TextEltHeader)
+    {
+	if (*c->pElt == FontChange)
+        {
+	    if (c->endReq - c->pElt < FontShiftSize)
+	    {
+		 err = BadLength;
+		 goto bail;
+	    }
+
+	    oldpFont = pFont;
+	    oldfid = fid;
+
+	    fid =  ((Font)*(c->pElt+4))		/* big-endian */
+		 | ((Font)*(c->pElt+3)) << 8
+		 | ((Font)*(c->pElt+2)) << 16
+		 | ((Font)*(c->pElt+1)) << 24;
+	    pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+						    SecurityReadAccess);
+	    if (!pFont)
+	    {
+		client->errorValue = fid;
+		err = BadFont;
+		/* restore pFont and fid for step 4 (described below) */
+		pFont = oldpFont;
+		fid = oldfid;
+
+		/* If we're in START_SLEEP mode, the following step
+		   shortens the request...  in the unlikely event that
+		   the fid somehow becomes valid before we come through
+		   again to actually execute the polytext, which would
+		   then mess up our refcounting scheme badly.  */
+		c->err = err;
+		c->endReq = c->pElt;
+
+		goto bail;
+	    }
+
+	    /* Step 3 (described below) on our new font */
+	    if (client_state == START_SLEEP)
+		pFont->refcnt++;
+	    else
+	    {
+		if (pFont != c->pGC->font && c->pDraw)
+		{
+		    ChangeGC( c->pGC, GCFont, &fid);
+		    ValidateGC(c->pDraw, c->pGC);
+		    if (c->reqType == X_PolyText8)
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+		    else
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+		}
+
+		/* Undo the refcnt++ we performed when going to sleep */
+		if (client_state == SLEEPING)
+		    (void)CloseFont(c->pGC->font, (Font)0);
+	    }
+	    c->pElt += FontShiftSize;
+	}
+	else	/* print a string */
+	{
+	    unsigned char *pNextElt;
+	    pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+	    if ( pNextElt > c->endReq)
+	    {
+		err = BadLength;
+		goto bail;
+	    }
+	    if (client_state == START_SLEEP)
+	    {
+		c->pElt = pNextElt;
+		continue;
+	    }
+	    if (c->pDraw)
+	    {
+		lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+				   c->pElt + TextEltHeader);
+	    }
+	    else lgerr = Successful;
+
+	    if (lgerr == Suspended)
+	    {
+		if (!c->slept) {
+		    int len;
+		    GC *pGC;
+		    PTclosurePtr new_closure;
+
+    /*  We're putting the client to sleep.  We need to do a few things
+	to ensure successful and atomic-appearing execution of the
+	remainder of the request.  First, copy the remainder of the
+	request into a safe malloc'd area.  Second, create a scratch GC
+	to use for the remainder of the request.  Third, mark all fonts
+	referenced in the remainder of the request to prevent their
+	deallocation.  Fourth, make the original GC look like the
+	request has completed...  set its font to the final font value
+	from this request.  These GC manipulations are for the unlikely
+	(but possible) event that some other client is using the GC.
+	Steps 3 and 4 are performed by running this procedure through
+	the remainder of the request in a special no-render mode
+	indicated by client_state = START_SLEEP.  */
+
+		    /* Step 1 */
+		    /* Allocate a malloc'd closure structure to replace
+		       the local one we were passed */
+		    new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+		    if (!new_closure)
+		    {
+			err = BadAlloc;
+			goto bail;
+		    }
+		    *new_closure = *c;
+		    c = new_closure;
+
+		    len = c->endReq - c->pElt;
+		    c->data = (unsigned char *)xalloc(len);
+		    if (!c->data)
+		    {
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    memmove(c->data, c->pElt, len);
+		    c->pElt = c->data;
+		    c->endReq = c->pElt + len;
+
+		    /* Step 2 */
+
+		    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+		    if (!pGC)
+		    {
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    if ((err = CopyGC(c->pGC, pGC, GCFunction |
+				      GCPlaneMask | GCForeground |
+				      GCBackground | GCFillStyle |
+				      GCTile | GCStipple |
+				      GCTileStipXOrigin |
+				      GCTileStipYOrigin | GCFont |
+				      GCSubwindowMode | GCClipXOrigin |
+				      GCClipYOrigin | GCClipMask)) !=
+				      Success)
+		    {
+			FreeScratchGC(pGC);
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    origGC = c->pGC;
+		    c->pGC = pGC;
+		    ValidateGC(c->pDraw, c->pGC);
+		    
+		    c->slept = TRUE;
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doPolyText,
+			     (pointer) c);
+
+		    /* Set up to perform steps 3 and 4 */
+		    client_state = START_SLEEP;
+		    continue;	/* on to steps 3 and 4 */
+		}
+		return TRUE;
+	    }
+	    else if (lgerr != Successful)
+	    {
+		err = FontToXError(lgerr);
+		goto bail;
+	    }
+	    if (c->pDraw)
+	    {
+		c->xorg += *((INT8 *)(c->pElt + 1));	/* must be signed */
+		c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+		    *c->pElt, c->pElt + TextEltHeader);
+	    }
+	    c->pElt = pNextElt;
+	}
+    }
+
+bail:
+
+    if (client_state == START_SLEEP)
+    {
+	/* Step 4 */
+	if (pFont != origGC->font)
+	{
+	    ChangeGC(origGC, GCFont, &fid);
+	    ValidateGC(c->pDraw, origGC);
+	}
+
+	/* restore pElt pointer for execution of remainder of the request */
+	c->pElt = c->data;
+	return TRUE;
+    }
+
+    if (c->err != Success) err = c->err;
+    if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+        if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+PolyText(client, pDraw, pGC, pElt, endReq, xorg, yorg, reqType, did)
+    ClientPtr client;
+    DrawablePtr pDraw;
+    GC *pGC;
+    unsigned char *pElt;
+    unsigned char *endReq;
+    int xorg;
+    int yorg;
+    int reqType;
+    XID did;
+{
+    PTclosureRec local_closure;
+
+    local_closure.pElt = pElt;
+    local_closure.endReq = endReq;
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_PolyText8)
+    {
+	local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.polyText =  (PolyTextPtr) pGC->ops->PolyText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.pGC = pGC;
+    local_closure.did = did;
+    local_closure.err = Success;
+    local_closure.slept = FALSE;
+
+    (void) doPolyText(client, &local_closure);
+    return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(client, c)
+    ClientPtr   client;
+    register ITclosurePtr c;
+{
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    FontPathElementPtr fpe;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client. */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+    if (lgerr == Suspended)
+    {
+        if (!c->slept) {
+	    GC *pGC;
+	    unsigned char *data;
+	    ITclosurePtr new_closure;
+
+	    /* We're putting the client to sleep.  We need to
+	       save some state.  Similar problem to that handled
+	       in doPolyText, but much simpler because the
+	       request structure is much simpler. */
+
+	    new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+	    if (!new_closure)
+	    {
+		err = BadAlloc;
+		goto bail;
+	    }
+	    *new_closure = *c;
+	    c = new_closure;
+
+	    data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+	    if (!data)
+	    {
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    memmove(data, c->data, c->nChars * c->itemSize);
+	    c->data = data;
+
+	    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+	    if (!pGC)
+	    {
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+			      GCForeground | GCBackground | GCFillStyle |
+			      GCTile | GCStipple | GCTileStipXOrigin |
+			      GCTileStipYOrigin | GCFont |
+			      GCSubwindowMode | GCClipXOrigin |
+			      GCClipYOrigin | GCClipMask)) != Success)
+	    {
+		FreeScratchGC(pGC);
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    c->pGC = pGC;
+	    ValidateGC(c->pDraw, c->pGC);
+
+	    c->slept = TRUE;
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+        }
+        return TRUE;
+    }
+    else if (lgerr != Successful)
+    {
+        err = FontToXError(lgerr);
+        goto bail;
+    }
+    if (c->pDraw)
+    {
+	(* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+	    c->nChars, c->data);
+    }
+
+bail:
+
+    if (err != Success && c->client != serverClient) {
+	SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+ImageText(client, pDraw, pGC, nChars, data, xorg, yorg, reqType, did)
+    ClientPtr client;
+    DrawablePtr pDraw;
+    GC *pGC;
+    int nChars;
+    unsigned char *data;
+    int xorg;
+    int yorg;
+    int reqType;
+    XID did;
+{
+    ITclosureRec local_closure;
+
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.pGC = pGC;
+    local_closure.nChars = nChars;
+    local_closure.data = data;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_ImageText8)
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.did = did;
+    local_closure.slept = FALSE;
+
+    (void) doImageText(client, &local_closure);
+    return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+#if NeedFunctionPrototypes
+DetermineFPEType(char *pathname)
+#else
+DetermineFPEType(pathname)
+    char       *pathname;
+#endif
+{
+    int         i;
+
+    for (i = 0; i < num_fpe_types; i++) {
+	if ((*fpe_functions[i].name_check) (pathname))
+	    return i;
+    }
+    return -1;
+}
+
+
+static void
+#if NeedFunctionPrototypes
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+#else
+FreeFontPath(list, n, force)
+    FontPathElementPtr	*list;
+    Bool		force;
+    int         n;
+#endif
+{
+    int         i;
+
+    for (i = 0; i < n; i++) {
+	if (force) {
+	    /* Sanity check that all refcounts will be 0 by the time
+	       we get to the end of the list. */
+	    int found = 1;	/* the first reference is us */
+	    int j;
+	    for (j = i+1; j < n; j++) {
+		if (list[j] == list[i])
+		    found++;
+	    }
+	    if (list[i]->refcount != found) {
+		ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+		       list[i]->name_length, list[i]->name,
+		       list[i]->refcount, found);
+		list[i]->refcount = found; /* ensure it will get freed */
+	    }
+	}
+	FreeFPE(list[i]);
+    }
+    xfree((char *) list);
+}
+
+static FontPathElementPtr
+#if NeedFunctionPrototypes
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+#else
+find_existing_fpe(list, num, name, len)
+    FontPathElementPtr *list;
+    int         num;
+    unsigned char *name;
+    int         len;
+#endif
+{
+    FontPathElementPtr fpe;
+    int         i;
+
+    for (i = 0; i < num; i++) {
+	fpe = list[i];
+	if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+	    return fpe;
+    }
+    return (FontPathElementPtr) 0;
+}
+
+
+static int
+#if NeedFunctionPrototypes
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+#else
+SetFontPathElements(npaths, paths, bad, persist)
+    int         npaths;
+    unsigned char *paths;
+    int        *bad;
+    Bool	persist;
+#endif
+{
+    int         i, err = 0;
+    int         valid_paths = 0;
+    unsigned int len;
+    unsigned char *cp = paths;
+    FontPathElementPtr fpe = NULL, *fplist;
+
+    fplist = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * npaths);
+    if (!fplist) {
+	*bad = 0;
+	return BadAlloc;
+    }
+    for (i = 0; i < num_fpe_types; i++) {
+	if (fpe_functions[i].set_path_hook)
+	    (*fpe_functions[i].set_path_hook) ();
+    }
+    for (i = 0; i < npaths; i++) 
+    {
+	len = (unsigned int) (*cp++);
+
+	if (len == 0) 
+	{
+	    if (persist)
+		ErrorF ("Removing empty element from the valid list of fontpaths\n");
+	    err = BadValue;
+	}
+	else
+	{
+	    /* if it's already in our active list, just reset it */
+	    /*
+	     * note that this can miss FPE's in limbo -- may be worth catching
+	     * them, though it'd muck up refcounting
+	     */
+	    fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+	    if (fpe) 
+	    {
+		err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+		if (err == Successful) 
+		{
+		    UseFPE(fpe);/* since it'll be decref'd later when freed
+				 * from the old list */
+		}
+		else
+		    fpe = 0;
+	    }
+	    /* if error or can't do it, act like it's a new one */
+	    if (!fpe)
+	    {
+		fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+		if (!fpe) 
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->name = (char *) xalloc(len + 1);
+		if (!fpe->name) 
+		{
+		    xfree(fpe);
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->refcount = 1;
+    
+		strncpy(fpe->name, (char *) cp, (int) len);
+		fpe->name[len] = '\0';
+		fpe->name_length = len;
+		fpe->type = DetermineFPEType(fpe->name);
+		if (fpe->type == -1)
+		    err = BadValue;
+		else
+		    err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+		if (err != Successful)
+		{
+		    if (persist)
+		    {
+			ErrorF("Could not init font path element %s, removing from list!\n",
+			       fpe->name);
+		    }
+		    xfree (fpe->name);
+		    xfree (fpe);
+		}
+	    }
+	}
+	if (err != Successful)
+	{
+	    if (!persist)
+		goto bail;
+	}
+	else
+	{
+	    fplist[valid_paths++] = fpe;
+	}
+	cp += len;
+    }
+
+    FreeFontPath(font_path_elements, num_fpes, FALSE);
+    font_path_elements = fplist;
+    if (patternCache)
+	EmptyFontPatternCache(patternCache);
+    num_fpes = valid_paths;
+
+    return Success;
+bail:
+    *bad = i;
+    while (--valid_paths >= 0)
+	FreeFPE(fplist[valid_paths]);
+    xfree(fplist);
+    return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(client, npaths, paths, error)
+    ClientPtr   client;
+    int         npaths;
+    unsigned char *paths;
+    int        *error;
+{
+    int   err = Success;
+
+    if (npaths == 0) {
+	if (SetDefaultFontPath(defaultFontPath) != Success)
+	    return BadValue;
+    } else {
+	err = SetFontPathElements(npaths, paths, error, FALSE);
+    }
+    return err;
+}
+
+int
+SetDefaultFontPath(path)
+    char       *path;
+{
+    unsigned char *cp,
+               *pp,
+               *nump,
+               *newpath;
+    int         num = 1,
+                len,
+                err,
+                size = 0,
+                bad;
+
+    /* get enough for string, plus values -- use up commas */
+    len = strlen(path) + 1;
+    nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+    if (!newpath)
+	return BadAlloc;
+    pp = (unsigned char *) path;
+    cp++;
+    while (*pp) {
+	if (*pp == ',') {
+	    *nump = (unsigned char) size;
+	    nump = cp++;
+	    pp++;
+	    num++;
+	    size = 0;
+	} else {
+	    *cp++ = *pp++;
+	    size++;
+	}
+    }
+    *nump = (unsigned char) size;
+
+    err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+    DEALLOCATE_LOCAL(newpath);
+
+    return err;
+}
+
+unsigned char *
+GetFontPath(count, length)
+    int			*count;
+    int			*length;
+{
+    int			i;
+    unsigned char       *c;
+    int			len;
+    FontPathElementPtr	fpe;
+
+    len = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	len += fpe->name_length + 1;
+    }
+    font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+    if (!font_path_string)
+	return NULL;
+
+    c = font_path_string;
+    *length = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	*c = fpe->name_length;
+	*length += *c++;
+	memmove(c, fpe->name, fpe->name_length);
+	c += fpe->name_length;
+    }
+    *count = num_fpes;
+    return font_path_string;
+}
+
+int
+LoadGlyphs(client, pfont, nchars, item_size, data)
+    ClientPtr   client;
+    FontPtr     pfont;
+    unsigned    nchars;
+    int         item_size;
+    unsigned char *data;
+{
+    if (fpe_functions[pfont->fpe->type].load_glyphs)
+	return (*fpe_functions[pfont->fpe->type].load_glyphs)
+	    (client, pfont, 0, nchars, item_size, data);
+    else
+	return Successful;
+}
+
+void
+DeleteClientFontStuff(client)
+    ClientPtr	client;
+{
+    int			i;
+    FontPathElementPtr	fpe;
+
+    for (i = 0; i < num_fpes; i++)
+    {
+	fpe = font_path_elements[i];
+	if (fpe_functions[fpe->type].client_died)
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+    }
+}
+
+void
+InitFonts ()
+{
+    patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+    if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+	PrinterFontRegisterFpeFunctions();
+	FontFileCheckRegisterFpeFunctions();
+	check_fs_register_fpe_functions();
+    } else 
+#endif
+    {
+#ifdef KDRIVESERVER
+	BuiltinRegisterFpeFunctions();
+#endif
+	FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+	fs_register_fpe_functions();
+#endif
+    }
+}
+
+int
+GetDefaultPointSize ()
+{
+    return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (num)
+    int        *num;
+{
+    if (requestingClient && requestingClient->fontResFunc != NULL &&
+	!requestingClient->clientGone)
+    {
+	return (*requestingClient->fontResFunc)(requestingClient, num);
+    }
+    else {
+	static struct _FontResolution res;
+	ScreenPtr   pScreen;
+
+	pScreen = screenInfo.screens[0];
+	res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+	/*
+	 * XXX - we'll want this as long as bitmap instances are prevalent 
+	 so that we can match them from scalable fonts
+	 */
+	if (res.x_resolution < 88)
+	    res.x_resolution = 75;
+	else
+	    res.x_resolution = 100;
+	res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+	if (res.y_resolution < 88)
+	    res.y_resolution = 75;
+	else
+	    res.y_resolution = 100;
+	res.point_size = 120;
+	*num = 1;
+	return &res;
+    }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func, 
+		     InitFpeFunc init_func, 
+		     FreeFpeFunc free_func, 
+		     ResetFpeFunc reset_func, 
+		     OpenFontFunc open_func, 
+		     CloseFontFunc close_func, 
+		     ListFontsFunc list_func, 
+		     StartLfwiFunc start_lfwi_func, 
+		     NextLfwiFunc next_lfwi_func, 
+		     WakeupFpeFunc wakeup_func, 
+		     ClientDiedFunc client_died, 
+		     LoadGlyphsFunc load_glyphs, 
+		     StartLaFunc start_list_alias_func, 
+		     NextLaFunc next_list_alias_func, 
+		     SetPathFunc set_path_func)
+{
+    FPEFunctions *new;
+
+    /* grow the list */
+    new = (FPEFunctions *) xrealloc(fpe_functions,
+				 (num_fpe_types + 1) * sizeof(FPEFunctions));
+    if (!new)
+	return -1;
+    fpe_functions = new;
+
+    fpe_functions[num_fpe_types].name_check = name_func;
+    fpe_functions[num_fpe_types].open_font = open_func;
+    fpe_functions[num_fpe_types].close_font = close_func;
+    fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+    fpe_functions[num_fpe_types].list_fonts = list_func;
+    fpe_functions[num_fpe_types].start_list_fonts_with_info =
+	start_lfwi_func;
+    fpe_functions[num_fpe_types].list_next_font_with_info =
+	next_lfwi_func;
+    fpe_functions[num_fpe_types].init_fpe = init_func;
+    fpe_functions[num_fpe_types].free_fpe = free_func;
+    fpe_functions[num_fpe_types].reset_fpe = reset_func;
+    fpe_functions[num_fpe_types].client_died = client_died;
+    fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+    fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+	start_list_alias_func;
+    fpe_functions[num_fpe_types].list_next_font_or_alias =
+	next_list_alias_func;
+    fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+    return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+    if (patternCache) {
+	FreeFontPatternCache(patternCache);
+	patternCache = 0;
+    }
+    FreeFontPath(font_path_elements, num_fpes, TRUE);
+    font_path_elements = 0;
+    num_fpes = 0;
+    xfree(fpe_functions);
+    num_fpe_types = 0;
+    fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(id)
+    XID         id;
+{
+    return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+					    SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+    return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(pfont, id)
+    FontPtr     pfont;
+    Font        id;
+{
+    return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(id)
+    Font        id;
+{
+    FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(client)
+    ClientPtr client;
+{
+    return 0;
+}
+
+static int  fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(fpe, block_handler)
+    FontPathElementPtr fpe;
+    BlockHandlerProcPtr block_handler;
+{
+    /* if server has reset, make sure the b&w handlers are reinstalled */
+    if (last_server_gen < serverGeneration) {
+	last_server_gen = serverGeneration;
+	fs_handlers_installed = 0;
+    }
+    if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+	if (!RegisterBlockAndWakeupHandlers(block_handler,
+					    FontWakeup, (pointer) 0))
+	    return AllocError;
+	fs_handlers_installed++;
+    }
+    QueueFontWakeup(fpe);
+    return Successful;
+}
+
+void
+remove_fs_handlers(fpe, block_handler, all)
+    FontPathElementPtr fpe;
+    BlockHandlerProcPtr block_handler;
+    Bool        all;
+{
+    if (all) {
+	/* remove the handlers if no one else is using them */
+	if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+	    RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+					 (pointer) 0);
+	}
+    }
+    RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+	((nbytes) == 1 ? (((bits)+7)>>3)        /* pad to 1 byte */ \
+	:(nbytes) == 2 ? ((((bits)+15)>>3)&~1)  /* pad to 2 bytes */ \
+	:(nbytes) == 4 ? ((((bits)+31)>>3)&~3)  /* pad to 4 bytes */ \
+	:(nbytes) == 8 ? ((((bits)+63)>>3)&~7)  /* pad to 8 bytes */ \
+	: 0)
+
+#define GLYPH_SIZE(ch, nbytes)          \
+	GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+			(ch)->metrics.leftSideBearing, (nbytes))
+dump_char_ascii(cip)
+    CharInfoPtr cip;
+{
+    int         r,
+                l;
+    int         bpr;
+    int         byte;
+    static unsigned maskTab[] = {
+	(1 << 7), (1 << 6), (1 << 5), (1 << 4),
+	(1 << 3), (1 << 2), (1 << 1), (1 << 0),
+    };
+
+    bpr = GLYPH_SIZE(cip, 4);
+    for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+	pointer     row = (pointer) cip->bits + r * bpr;
+
+	byte = 0;
+	for (l = 0; l <= (cip->metrics.rightSideBearing -
+			  cip->metrics.leftSideBearing); l++) {
+	    if (maskTab[l & 7] & row[l >> 3])
+		putchar('X');
+	    else
+		putchar('.');
+	}
+	putchar('\n');
+    }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
new file mode 100644
index 000000000..dd607e0ca
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -0,0 +1,4797 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXevents.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.46 2002/09/17 01:15:09 dawes Exp $ */
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/****************************************************************
+*                                                               *
+*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#include "Xlib.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include "XKBsrv.h"
+#if NeedFunctionPrototypes
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#else
+extern Bool XkbFilterEvents();
+#endif
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+
+#include "XIproto.h"
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "../../dix/dispatch.h"
+
+#include "NXlib.h"
+
+#include "Events.h"
+#include "Windows.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
+
+#define EXTENSION_EVENT_BASE  64
+
+#define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+	Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+	PointerMotionMask | Button1MotionMask | \
+	Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+	Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+	KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+	MotionMask )
+#define PointerGrabMask ( \
+	ButtonPressMask | ButtonReleaseMask | \
+	EnterWindowMask | LeaveWindowMask | \
+	PointerMotionHintMask | KeymapStateMask | \
+	MotionMask )
+#define AllModifiersMask ( \
+	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+	Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+			      (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+    QdEventPtr		pending, *pendtail;
+    DeviceIntPtr	replayDev;	/* kludgy rock to put flag for */
+    WindowPtr		replayWin;	/*   ComputeFreezes            */
+    Bool		playingEvents;
+    TimeStamp		time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+typedef struct {
+    int		x, y;
+    ScreenPtr	pScreen;
+} HotSpot;
+
+static  struct {
+    CursorPtr	current;
+    BoxRec	hotLimits;	/* logical constraints of hot spot */
+    Bool	confined;	/* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+    RegionPtr	hotShape;	/* additional logical shape constraint */
+#endif
+    BoxRec	physLimits;	/* physical constraints of hot spot */
+    WindowPtr	win;		/* window of logical position */
+    HotSpot	hot;		/* logical pointer position */
+    HotSpot	hotPhys;	/* physical pointer position */
+#ifdef PANORAMIX
+    ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
+    RegionRec   Reg1;	        /* Region 1 for confining motion */
+    RegionRec   Reg2;		/* Region 2 for confining virtual motion */
+    WindowPtr   windows[MAXSCREENS];
+    WindowPtr	confineWin;	/* confine window */ 
+#endif
+} sprite;			/* info about the cursor sprite */
+
+static void DoEnterLeaveEvents(
+#if NeedFunctionPrototypes
+    WindowPtr /*fromWin*/,
+    WindowPtr /*toWin*/,
+    int /*mode*/
+#endif
+);
+
+static WindowPtr XYToWindow(
+#if NeedFunctionPrototypes
+    int /*x*/,
+    int /*y*/
+#endif
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+	NoSuchEvent,		       /* 0 */
+	NoSuchEvent,		       /* 1 */
+	KeyPressMask,		       /* KeyPress */
+	KeyReleaseMask,		       /* KeyRelease */
+	ButtonPressMask,	       /* ButtonPress */
+	ButtonReleaseMask,	       /* ButtonRelease */
+	PointerMotionMask,	       /* MotionNotify (initial state) */
+	EnterWindowMask,	       /* EnterNotify */
+	LeaveWindowMask,	       /* LeaveNotify */
+	FocusChangeMask,	       /* FocusIn */
+	FocusChangeMask,	       /* FocusOut */
+	KeymapStateMask,	       /* KeymapNotify */
+	ExposureMask,		       /* Expose */
+	CantBeFiltered,		       /* GraphicsExpose */
+	CantBeFiltered,		       /* NoExpose */
+	VisibilityChangeMask,	       /* VisibilityNotify */
+	SubstructureNotifyMask,	       /* CreateNotify */
+	StructureAndSubMask,	       /* DestroyNotify */
+	StructureAndSubMask,	       /* UnmapNotify */
+	StructureAndSubMask,	       /* MapNotify */
+	SubstructureRedirectMask,      /* MapRequest */
+	StructureAndSubMask,	       /* ReparentNotify */
+	StructureAndSubMask,	       /* ConfigureNotify */
+	SubstructureRedirectMask,      /* ConfigureRequest */
+	StructureAndSubMask,	       /* GravityNotify */
+	ResizeRedirectMask,	       /* ResizeRequest */
+	StructureAndSubMask,	       /* CirculateNotify */
+	SubstructureRedirectMask,      /* CirculateRequest */
+	PropertyChangeMask,	       /* PropertyNotify */
+	CantBeFiltered,		       /* SelectionClear */
+	CantBeFiltered,		       /* SelectionRequest */
+	CantBeFiltered,		       /* SelectionNotify */
+	ColormapChangeMask,	       /* ColormapNotify */
+	CantBeFiltered,		       /* ClientMessage */
+	CantBeFiltered		       /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+    0x7c				/* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+    int x, 
+    int y, 
+    Bool generateEvent
+){
+    ScreenPtr pScreen;
+    BoxRec box;
+    int i;
+
+    /* x,y are in Screen 0 coordinates.  We need to decide what Screen
+       to send the message too and what the coordinates relative to 
+       that screen are. */
+
+    pScreen = sprite.screen;
+    x += panoramiXdataPtr[0].x;
+    y += panoramiXdataPtr[0].y;
+
+    if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+								x, y, &box)) 
+    {
+	FOR_NSCREENS(i) 
+	{
+	    if(i == pScreen->myNum) 
+		continue;
+	    if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+	    {
+		pScreen = screenInfo.screens[i];
+		break;
+	    }
+	}
+    }
+
+    sprite.screen = pScreen;
+    sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+    sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+    x -= panoramiXdataPtr[pScreen->myNum].x;
+    y -= panoramiXdataPtr[pScreen->myNum].y;
+
+    return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+    ScreenPtr pScreen = sprite.screen;
+    BoxRec newBox = sprite.physLimits;
+
+    /* Translate the constraining box to the screen
+       the sprite is actually on */
+    newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+    newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+    (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents
+){
+    HotSpot new;
+
+    if (!cursor)
+	return;
+ 
+    new = sprite.hotPhys;
+
+    /* I don't care what the DDX has to say about it */
+    sprite.physLimits = sprite.hotLimits;
+
+    /* constrain the pointer to those limits */
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+
+    if (sprite.hotShape)  /* more work if the shape is a mess */
+	ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+    if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	XineramaSetCursorPosition (new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+
+    /* Tell DDX what the limits are */
+    XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+    if(pWin == WindowTable[0]) {
+	    memcpy(sprite.windows, WindowTable, 
+				PanoramiXNumScreens*sizeof(WindowPtr));
+    } else {
+	PanoramiXRes *win;
+	int i;
+
+	win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+	if(!win)
+	    return FALSE;
+
+	for(i = 0; i < PanoramiXNumScreens; i++) {
+	   sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+	   if(!sprite.windows[i])  /* window is being unmapped */
+		return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+   QdEventPtr qe,
+   WindowPtr pWin
+){
+
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;  /* should always be Screen 0 */
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	int x, y, off_x, off_y, i;
+	BoxRec lims;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+        if (sprite.hot.x < lims.x1)
+            sprite.hot.x = lims.x1;
+        else if (sprite.hot.x >= lims.x2)
+            sprite.hot.x = lims.x2 - 1;
+        if (sprite.hot.y < lims.y1)
+            sprite.hot.y = lims.y1;
+        else if (sprite.hot.y >= lims.y2)
+            sprite.hot.y = lims.y2 - 1;
+
+	if (REGION_NUM_RECTS(&sprite.Reg2) > 1) 
+	    ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	/* Motion events entering DIX get translated to Screen 0
+	   coordinates.  Replayed events have already been 
+	   translated since they've entered DIX before */
+	XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			  panoramiXdataPtr[0].x;
+	XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			  panoramiXdataPtr[0].y;
+
+	sprite.hot.x = XE_KBPTR.rootX;
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+
+	if (sprite.hotShape) 
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    XineramaSetCursorPosition(
+			sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+    if (syncEvents.playingEvents)
+    {
+	XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	int x, y, off_x, off_y, i;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+	if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+	   sprite.hotShape = &sprite.Reg1;
+	else
+	   sprite.hotShape = NullRegion;
+	
+	sprite.confined = FALSE;
+	sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+	XineramaCheckPhysLimits(sprite.current, generateEvents);
+    }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    XineramaCheckPhysLimits(cursor, FALSE);
+    	(*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+	sprite.current = cursor;
+    }
+}
+
+
+#endif  /* PANORAMIX */
+
+void
+SetMaskForEvent(mask, event)
+    Mask mask;
+    int event;
+{
+    if ((event < LASTEvent) || (event >= 128))
+	FatalError("SetMaskForEvent: bogus event number");
+    filters[event] = mask;
+}
+
+void
+SetCriticalEvent(event)
+    int event;
+{
+    if (event >= 128)
+	FatalError("SetCriticalEvent: bogus event number");
+    criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+#if NeedFunctionPrototypes
+SyntheticMotion(int x, int y)
+#else
+SyntheticMotion(x, y)
+    int x, y;
+#endif
+{
+    xEvent xE;
+
+#ifdef PANORAMIX
+    /* Translate back to the sprite screen since processInputProc
+       will translate from sprite screen to screen 0 upon reentry
+       to the DIX layer */
+    if(!noPanoramiXExtension) {
+	x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+	y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+    }
+#endif
+    xE.u.keyButtonPointer.rootX = x;
+    xE.u.keyButtonPointer.rootY = y;
+    if (syncEvents.playingEvents)
+	xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+    else
+	xE.u.keyButtonPointer.time = currentTime.milliseconds;
+    xE.u.u.type = MotionNotify;
+    (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+#if NeedFunctionPrototypes
+ConfineToShape(RegionPtr shape, int *px, int *py)
+#else
+ConfineToShape(shape, px, py)
+    RegionPtr shape;
+    int *px, *py;
+#endif
+{
+    BoxRec box;
+    int x = *px, y = *py;
+    int incx = 1, incy = 1;
+
+    if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+	return;
+    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+    /* this is rather crude */
+    do {
+	x += incx;
+	if (x >= box.x2)
+	{
+	    incx = -1;
+	    x = *px - 1;
+	}
+	else if (x < box.x1)
+	{
+	    incx = 1;
+	    x = *px;
+	    y += incy;
+	    if (y >= box.y2)
+	    {
+		incy = -1;
+		y = *py - 1;
+	    }
+	    else if (y < box.y1)
+		return; /* should never get here! */
+	}
+    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+    *px = x;
+    *py = y;
+}
+#endif
+
+static void
+#if NeedFunctionPrototypes
+CheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents,
+    Bool confineToScreen,
+    ScreenPtr pScreen)
+#else
+CheckPhysLimits(cursor, generateEvents, confineToScreen, pScreen)
+    CursorPtr cursor;
+    Bool generateEvents;
+    Bool confineToScreen;
+    ScreenPtr pScreen;
+#endif
+{
+    HotSpot new;
+
+    if (!cursor)
+	return;
+    new = sprite.hotPhys;
+    if (pScreen)
+	new.pScreen = pScreen;
+    else
+	pScreen = new.pScreen;
+    (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+			      &sprite.physLimits);
+    sprite.confined = confineToScreen;
+    (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &new.x, &new.y); 
+#endif
+    if ((pScreen != sprite.hotPhys.pScreen) ||
+	(new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	if (pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys = new;
+	(*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+CheckVirtualMotion(
+    register QdEventPtr qe,
+    register WindowPtr pWin)
+#else
+CheckVirtualMotion(qe, pWin)
+    register QdEventPtr qe;
+    register WindowPtr pWin;
+#endif
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaCheckVirtualMotion(qe, pWin);
+	return;
+    }
+#endif
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	BoxRec lims;
+
+	if (sprite.hot.pScreen != pWin->drawable.pScreen)
+	{
+	    sprite.hot.pScreen = pWin->drawable.pScreen;
+	    sprite.hot.x = sprite.hot.y = 0;
+	}
+	lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+	if (sprite.hot.x < lims.x1)
+	    sprite.hot.x = lims.x1;
+	else if (sprite.hot.x >= lims.x2)
+	    sprite.hot.x = lims.x2 - 1;
+	if (sprite.hot.y < lims.y1)
+	    sprite.hot.y = lims.y1;
+	else if (sprite.hot.y >= lims.y2)
+	    sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+	if (wBoundingShape(pWin))
+	    ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaConfineCursorToWindow(pWin, generateEvents);
+	return;
+    }	
+#endif
+
+    if (syncEvents.playingEvents)
+    {
+	CheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+	sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+					       : NullRegion;
+#endif
+	CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+			pScreen);
+    }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+    return sprite.confined;
+}
+
+static void
+#if NeedFunctionPrototypes
+ChangeToCursor(CursorPtr cursor)
+#else
+ChangeToCursor(cursor)
+    CursorPtr cursor;
+#endif
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaChangeToCursor(cursor);
+	return;
+    }
+#endif
+
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    CheckPhysLimits(cursor, FALSE, sprite.confined,
+			    (ScreenPtr)NULL);
+	(*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+						  cursor);
+	sprite.current = cursor;
+    }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(a, b)
+    register WindowPtr a, b;
+{
+    for (b = b->parent; b; b = b->parent)
+	if (b == a) return TRUE;
+    return FALSE;
+}
+
+static void
+#if NeedFunctionPrototypes
+PostNewCursor(void)
+#else
+PostNewCursor()
+#endif
+{
+    register    WindowPtr win;
+    register    GrabPtr grab = inputInfo.pointer->grab;
+
+    if (syncEvents.playingEvents)
+	return;
+    if (grab)
+    {
+	if (grab->cursor)
+	{
+	    ChangeToCursor(grab->cursor);
+	    return;
+	}
+	if (IsParent(grab->window, sprite.win))
+	    win = sprite.win;
+	else
+	    win = grab->window;
+    }
+    else
+	win = sprite.win;
+    for (; win; win = win->parent)
+	if (win->optional && win->optional->cursor != NullCursor)
+	{
+	    ChangeToCursor(win->optional->cursor);
+	    return;
+	}
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+    return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+    return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+    return sprite.current;
+}
+
+void
+GetSpritePosition(px, py)
+    int *px, *py;
+{
+    *px = sprite.hotPhys.x;
+    *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+    if(!noPanoramiXExtension) {
+	return sprite.screen->myNum;
+    } else {
+	return 0;
+    }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+#if NeedFunctionPrototypes
+MonthChangedOrBadTime(register xEvent *xE)
+#else
+MonthChangedOrBadTime(xE)
+    register xEvent *xE;
+#endif
+{
+    /* If the ddx/OS is careless about not processing timestamped events from
+     * different sources in sorted order, then it's possible for time to go
+     * backwards when it should not.  Here we ensure a decent time.
+     */
+    if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+	currentTime.months++;
+    else
+	XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+    if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+	MonthChangedOrBadTime(xE); \
+    currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+    lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(xE)
+    register xEvent *xE;
+{
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE);
+}
+
+/**************************************************************************
+ *            The following procedures deal with synchronous events       *
+ **************************************************************************/
+
+void
+EnqueueEvent(xE, device, count)
+    xEvent		*xE;
+    DeviceIntPtr	device;
+    int			count;
+{
+    register QdEventPtr tail = *syncEvents.pendtail;
+    register QdEventPtr qe;
+    xEvent		*qxE;
+
+    NoticeTime(xE);
+    if (DeviceEventCallback)
+    {
+	DeviceEventInfoRec eventinfo;
+	/*  The RECORD spec says that the root window field of motion events
+	 *  must be valid.  At this point, it hasn't been filled in yet, so
+	 *  we do it here.  The long expression below is necessary to get
+	 *  the current root window; the apparently reasonable alternative
+	 *  GetCurrentRootWindow()->drawable.id doesn't give you the right
+	 *  answer on the first motion event after a screen change because
+	 *  the data that GetCurrentRootWindow relies on hasn't been
+	 *  updated yet.
+	 */
+	if (xE->u.u.type == MotionNotify)
+	    XE_KBPTR.root =
+		WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	eventinfo.events = xE;
+	eventinfo.count = count;
+	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+    }
+    if (xE->u.u.type == MotionNotify)
+    {
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension) {
+	    XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			      panoramiXdataPtr[0].x;
+	    XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			      panoramiXdataPtr[0].y;
+	}
+#endif
+	sprite.hotPhys.x = XE_KBPTR.rootX;
+	sprite.hotPhys.y = XE_KBPTR.rootY;
+	/* do motion compression */
+	if (tail &&
+	    (tail->event->u.u.type == MotionNotify) &&
+	    (tail->pScreen == sprite.hotPhys.pScreen))
+	{
+	    tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+	    tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+	    tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+	    tail->months = currentTime.months;
+	    return;
+	}
+    }
+    qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+    if (!qe)
+	return;
+    qe->next = (QdEventPtr)NULL;
+    qe->device = device;
+    qe->pScreen = sprite.hotPhys.pScreen;
+    qe->months = currentTime.months;
+    qe->event = (xEvent *)(qe + 1);
+    qe->evcount = count;
+    for (qxE = qe->event; --count >= 0; qxE++, xE++)
+	*qxE = *xE;
+    if (tail)
+	syncEvents.pendtail = &tail->next;
+    *syncEvents.pendtail = qe;
+}
+
+static void
+#if NeedFunctionPrototypes
+PlayReleasedEvents(void)
+#else
+PlayReleasedEvents()
+#endif
+{
+    register QdEventPtr *prev, qe;
+    register DeviceIntPtr dev;
+
+    prev = &syncEvents.pending;
+    while ( (qe = *prev) )
+    {
+	if (!qe->device->sync.frozen)
+	{
+	    *prev = qe->next;
+	    if (*syncEvents.pendtail == *prev)
+		syncEvents.pendtail = prev;
+	    if (qe->event->u.u.type == MotionNotify)
+		CheckVirtualMotion(qe, NullWindow);
+	    syncEvents.time.months = qe->months;
+	    syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+	   /* Translate back to the sprite screen since processInputProc
+	      will translate from sprite screen to screen 0 upon reentry
+	      to the DIX layer */
+	    if(!noPanoramiXExtension) {
+		qe->event->u.keyButtonPointer.rootX += 
+			panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x;
+		qe->event->u.keyButtonPointer.rootY += 
+			panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y;
+	    }
+#endif
+	    (*qe->device->public.processInputProc)(qe->event, qe->device,
+						   qe->evcount);
+	    xfree(qe);
+	    for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+		;
+	    if (!dev)
+		break;
+	    /* Playing the event may have unfrozen another device. */
+	    /* So to play it safe, restart at the head of the queue */
+	    prev = &syncEvents.pending;
+	}
+	else
+	    prev = &qe->next;
+    } 
+}
+
+static void
+#if NeedFunctionPrototypes
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+#else
+FreezeThaw(dev, frozen)
+    register DeviceIntPtr dev;
+    Bool frozen;
+#endif
+{
+    dev->sync.frozen = frozen;
+    if (frozen)
+	dev->public.processInputProc = dev->public.enqueueInputProc;
+    else
+	dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+    register DeviceIntPtr replayDev = syncEvents.replayDev;
+    register int i;
+    WindowPtr w;
+    register xEvent *xE;
+    int count;
+    GrabPtr grab;
+    register DeviceIntPtr dev;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+	FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+    if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+	return;
+    syncEvents.playingEvents = TRUE;
+    if (replayDev)
+    {
+	xE = replayDev->sync.event;
+	count = replayDev->sync.evcount;
+	syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+	for (i = 0; i < spriteTraceGood; i++)
+	{
+	    if (syncEvents.replayWin == spriteTrace[i])
+	    {
+		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+		    if (replayDev->focus)
+			DeliverFocusedEvent(replayDev, xE, w, count);
+		    else
+			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+					        replayDev, count);
+		}
+		goto playmore;
+	    }
+	}
+	/* must not still be in the same stack */
+	if (replayDev->focus)
+	    DeliverFocusedEvent(replayDev, xE, w, count);
+	else
+	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+    }
+playmore:
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (!dev->sync.frozen)
+	{
+	    PlayReleasedEvents();
+	    break;
+	}
+    }
+    syncEvents.playingEvents = FALSE;
+    /* the following may have been skipped during replay, so do it now */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+    PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+    GrabPtr grab;
+
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(thisDev, thisMode, otherMode)
+    register DeviceIntPtr thisDev;
+    Bool thisMode, otherMode;
+{
+    register GrabPtr grab = thisDev->grab;
+    register DeviceIntPtr dev;
+
+    if (thisMode == GrabModeSync)
+	thisDev->sync.state = FROZEN_NO_EVENT;
+    else
+    {	/* free both if same client owns both */
+	thisDev->sync.state = THAWED;
+	if (thisDev->sync.other &&
+	    (CLIENT_BITS(thisDev->sync.other->resource) ==
+	     CLIENT_BITS(grab->resource)))
+	    thisDev->sync.other = NullGrab;
+    }
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev != thisDev)
+	{
+	    if (otherMode == GrabModeSync)
+		dev->sync.other = grab;
+	    else
+	    {	/* free both if same client owns both */
+		if (dev->sync.other &&
+		    (CLIENT_BITS(dev->sync.other->resource) ==
+		     CLIENT_BITS(grab->resource)))
+		    dev->sync.other = NullGrab;
+	    }
+	}
+    }
+    ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(mouse, grab, time, autoGrab)
+    register GrabPtr grab;
+    register DeviceIntPtr mouse;
+    TimeStamp time;
+    Bool autoGrab;
+{
+    WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+				     : sprite.win;
+
+    if (grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+    }
+    DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+    mouse->valuator->motionHintWindow = NullWindow;
+    if (syncEvents.playingEvents)
+	mouse->grabTime = syncEvents.time;
+    else
+	mouse->grabTime = time;
+    if (grab->cursor)
+	grab->cursor->refcnt++;
+    mouse->activeGrab = *grab;
+    mouse->grab = &mouse->activeGrab;
+    mouse->fromPassiveGrab = autoGrab;
+    PostNewCursor();
+    CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * If grab is synchronous, events are delivered to clients only if they send
+     * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the 
+     * delivered event is saved in a queue and replayed later, when grab is released.
+     * We should  export sync grab to X as async in order to avoid events to be 
+     * queued twice, in the agent and in the X server. This solution have a drawback:
+     * replayed events are not delivered to that application that are not clients of
+     * the agent.
+     * A different solution could be to make the grab asynchronous in the agent and 
+     * to export it as synchronous. But this seems to be less safe.
+     *
+     * To make internal grab asynchronous, change previous line as follows.
+     *
+     * if (nxagentOption(Rootless))
+     * {
+     *   CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
+     * }
+     * else
+     * {
+     *   CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+     * }
+     */
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      /*
+       * FIXME: We should use the correct value
+       * for the cursor. Temporarily we set it
+       * to None.
+       */
+
+       int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+                                                 nxagentCollectGrabPointerPredicate);
+
+       NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
+                                1, grab -> eventMask & PointerGrabMask,
+                                    GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
+                                        nxagentWindow(grab -> confineTo) : None,
+                                            None, CurrentTime);
+    }
+
+    #endif
+}
+
+void
+DeactivatePointerGrab(mouse)
+    register DeviceIntPtr mouse;
+{
+    register GrabPtr grab = mouse->grab;
+    register DeviceIntPtr dev;
+
+    mouse->valuator->motionHintWindow = NullWindow;
+    mouse->grab = NullGrab;
+    mouse->sync.state = NOT_GRABBED;
+    mouse->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+    if (grab->confineTo)
+	ConfineCursorToWindow(ROOT, FALSE, FALSE);
+    PostNewCursor();
+    if (grab->cursor)
+	FreeCursor(grab->cursor, (Cursor)0);
+    ComputeFreezes();
+
+    #ifdef NXAGENT_SERVER
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      XUngrabPointer(nxagentDisplay, CurrentTime);
+
+      if (sprite.win == ROOT)
+      {
+        mouse -> button -> state &=
+            ~(Button1Mask | Button2Mask | Button3Mask |
+                  Button4Mask | Button5Mask);
+      }
+    }
+
+    #endif
+}
+
+void
+ActivateKeyboardGrab(keybd, grab, time, passive)
+    register DeviceIntPtr keybd;
+    GrabPtr grab;
+    TimeStamp time;
+    Bool passive;
+{
+    WindowPtr oldWin;
+
+    if (keybd->grab)
+	oldWin = keybd->grab->window;
+    else if (keybd->focus)
+	oldWin = keybd->focus->win;
+    else
+	oldWin = sprite.win;
+    if (oldWin == FollowKeyboardWin)
+	oldWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+    if (syncEvents.playingEvents)
+	keybd->grabTime = syncEvents.time;
+    else
+	keybd->grabTime = time;
+    keybd->activeGrab = *grab;
+    keybd->grab = &keybd->activeGrab;
+    keybd->fromPassiveGrab = passive;
+    CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(keybd)
+    register DeviceIntPtr keybd;
+{
+    register GrabPtr grab = keybd->grab;
+    register DeviceIntPtr dev;
+    register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+					       : sprite.win;
+
+    if (focusWin == FollowKeyboardWin)
+	focusWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    keybd->grab = NullGrab;
+    keybd->sync.state = NOT_GRABBED;
+    keybd->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+    ComputeFreezes();
+}
+
+void
+AllowSome(client, time, thisDev, newState)
+    ClientPtr		client;
+    TimeStamp		time;
+    register DeviceIntPtr thisDev;
+    int			newState;
+{
+    Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+    TimeStamp grabTime;
+    register DeviceIntPtr dev;
+
+    thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+    thisSynced = FALSE;
+    otherGrabbed = FALSE;
+    othersFrozen = TRUE;
+    grabTime = thisDev->grabTime;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev == thisDev)
+	    continue;
+	if (dev->grab && SameClient(dev->grab, client))
+	{
+	    if (!(thisGrabbed || otherGrabbed) ||
+		(CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+		grabTime = dev->grabTime;
+	    otherGrabbed = TRUE;
+	    if (thisDev->sync.other == dev->grab)
+		thisSynced = TRUE;
+	    if (dev->sync.state < FROZEN)
+		othersFrozen = FALSE;
+	}
+	else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+	    othersFrozen = FALSE;
+    }
+    if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+	return;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, grabTime) == EARLIER))
+	return;
+    switch (newState)
+    {
+	case THAWED:	 	       /* Async */
+	    if (thisGrabbed)
+		thisDev->sync.state = THAWED;
+	    if (thisSynced)
+		thisDev->sync.other = NullGrab;
+	    ComputeFreezes();
+	    break;
+	case FREEZE_NEXT_EVENT:		/* Sync */
+	    if (thisGrabbed)
+	    {
+		thisDev->sync.state = FREEZE_NEXT_EVENT;
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		ComputeFreezes();
+	    }
+	    break;
+	case THAWED_BOTH:		/* AsyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case FREEZE_BOTH_NEXT_EVENT:	/* SyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case NOT_GRABBED:		/* Replay */
+	    if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+	    {
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		syncEvents.replayDev = thisDev;
+		syncEvents.replayWin = thisDev->grab->window;
+		(*thisDev->DeactivateGrab)(thisDev);
+		syncEvents.replayDev = (DeviceIntPtr)NULL;
+	    }
+	    break;
+	case THAW_OTHERS:		/* AsyncOthers */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev == thisDev)
+			continue;
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+    }
+}
+
+int
+ProcAllowEvents(client)
+    register ClientPtr client;
+{
+    TimeStamp		time;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    REQUEST(xAllowEventsReq);
+
+    REQUEST_SIZE_MATCH(xAllowEventsReq);
+    time = ClientTimeToServerTime(stuff->time);
+    switch (stuff->mode)
+    {
+	case ReplayPointer:
+	    AllowSome(client, time, mouse, NOT_GRABBED);
+	    break;
+	case SyncPointer: 
+	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncPointer: 
+	    AllowSome(client, time, mouse, THAWED);
+	    break;
+	case ReplayKeyboard: 
+	    AllowSome(client, time, keybd, NOT_GRABBED);
+	    break;
+	case SyncKeyboard: 
+	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncKeyboard: 
+	    AllowSome(client, time, keybd, THAWED);
+	    break;
+	case SyncBoth:
+	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+	    break;
+	case AsyncBoth:
+	    AllowSome(client, time, keybd, THAWED_BOTH);
+	    break;
+	default: 
+	    client->errorValue = stuff->mode;
+	    return BadValue;
+    }
+
+    /*
+     * This is not necessary if we export grab to X as asynchronous.
+     *
+     * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
+     *         stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
+     * {
+     *   XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
+     * }
+     */
+
+    return Success;
+}
+
+void
+ReleaseActiveGrabs(client)
+    ClientPtr client;
+{
+    register DeviceIntPtr dev;
+    Bool    done;
+
+    /* XXX CloseDownClient should remove passive grabs before
+     * releasing active grabs.
+     */
+    do {
+    	done = TRUE;
+    	for (dev = inputInfo.devices; dev; dev = dev->next)
+    	{
+	    if (dev->grab && SameClient(dev->grab, client))
+	    {
+	    	(*dev->DeactivateGrab)(dev);
+	    	done = FALSE;
+	    }
+    	}
+    } while (!done);
+}
+
+/**************************************************************************
+ *            The following procedures deal with delivering events        *
+ **************************************************************************/
+
+int
+TryClientEvents (client, pEvents, count, mask, filter, grab)
+    ClientPtr client;
+    GrabPtr grab;
+    xEvent *pEvents;
+    int count;
+    Mask mask, filter;
+{
+    int i;
+    int type;
+
+#ifdef DEBUG
+    if (debug_events) ErrorF(
+	"Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+	((filter == CantBeFiltered) || (mask & filter)))
+    {
+	if (grab && !SameClient(grab, client))
+	    return -1; /* don't send, but notify caller */
+	type = pEvents->u.u.type;
+	if (type == MotionNotify)
+	{
+	    if (mask & PointerMotionHintMask)
+	    {
+		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+		    pEvents->u.keyButtonPointer.event)
+		{
+#ifdef DEBUG
+		    if (debug_events) ErrorF("\n");
+	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+		    return 1; /* don't send, but pretend we did */
+		}
+		pEvents->u.u.detail = NotifyHint;
+	    }
+	    else
+	    {
+		pEvents->u.u.detail = NotifyNormal;
+	    }
+	}
+#ifdef XINPUT
+	else
+	{
+	    if ((type == DeviceMotionNotify) &&
+		MaybeSendDeviceMotionNotifyHint
+			((deviceKeyButtonPointer*)pEvents, mask) != 0)
+		return 1;
+	}
+#endif
+	type &= 0177;
+	if (type != KeymapNotify)
+	{
+	    /* all extension events must have a sequence number */
+	    for (i = 0; i < count; i++)
+		pEvents[i].u.u.sequenceNumber = client->sequence;
+	}
+
+	if (BitIsOn(criticalEvents, type))
+	{
+#ifdef SMART_SCHEDULE
+	    if (client->smart_priority < SMART_MAX_PRIORITY)
+		client->smart_priority++;
+#endif
+	    SetCriticalOutputPending();
+	}
+
+	WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+	if (debug_events) ErrorF(  " delivered\n");
+#endif
+	return 1;
+    }
+    else
+    {
+#ifdef DEBUG
+	if (debug_events) ErrorF("\n");
+#endif
+	return 0;
+    }
+}
+
+int
+DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
+    register WindowPtr pWin;
+    GrabPtr grab;
+    xEvent *pEvents;
+    int count;
+    Mask filter;
+    int mskidx;
+{
+    int deliveries = 0, nondeliveries = 0;
+    int attempt;
+    register InputClients *other;
+    ClientPtr client = NullClient;
+    Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+		              this mask is the mask of the grab. */
+    int type = pEvents->u.u.type;
+
+    /* CantBeFiltered means only window owner gets the event */
+    if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+    {
+	/* if nobody ever wants to see this event, skip some work */
+	if (filter != CantBeFiltered &&
+	    !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+	    return 0;
+	if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+				      pWin->eventMask, filter, grab)) )
+	{
+	    if (attempt > 0)
+	    {
+		deliveries++;
+		client = wClient(pWin);
+		deliveryMask = pWin->eventMask;
+	    } else
+		nondeliveries--;
+	}
+    }
+    if (filter != CantBeFiltered)
+    {
+	if (type & EXTENSION_EVENT_BASE)
+	{
+	    OtherInputMasks *inputMasks;
+
+	    inputMasks = wOtherInputMasks(pWin);
+	    if (!inputMasks ||
+		!(inputMasks->inputEvents[mskidx] & filter))
+		return 0;
+	    other = inputMasks->inputClients;
+	}
+	else
+	    other = (InputClients *)wOtherClients(pWin);
+	for (; other; other = other->next)
+	{
+	    if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+					  other->mask[mskidx], filter, grab)) )
+	    {
+		if (attempt > 0)
+		{
+		    deliveries++;
+		    client = rClient(other);
+		    deliveryMask = other->mask[mskidx];
+		} else
+		    nondeliveries--;
+	    }
+	}
+    }
+    if ((type == ButtonPress) && deliveries && (!grab))
+    {
+	GrabRec tempGrab;
+
+	tempGrab.device = inputInfo.pointer;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.window = pWin;
+	tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+	tempGrab.eventMask = deliveryMask;
+	tempGrab.keyboardMode = GrabModeAsync;
+	tempGrab.pointerMode = GrabModeAsync;
+	tempGrab.confineTo = NullWindow;
+	tempGrab.cursor = NullCursor;
+	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+					   currentTime, TRUE);
+    }
+    else if ((type == MotionNotify) && deliveries)
+	inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+    else
+    {
+	if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
+	    deliveries)
+	    CheckDeviceGrabAndHintWindow (pWin, type,
+					  (deviceKeyButtonPointer*) pEvents,
+					  grab, client, deliveryMask);
+    }
+#endif
+    if (deliveries)
+	return deliveries;
+    return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0.  if
+   send works,  return 1 or if send didn't work, return 2.
+   Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int 
+XineramaTryClientEventsResult(
+    ClientPtr client,
+    GrabPtr grab,
+    Mask mask, 
+    Mask filter
+){
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+        ((filter == CantBeFiltered) || (mask & filter)))
+    {
+        if (grab && !SameClient(grab, client)) return -1;
+	else return 1;
+    }
+    return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
+    register WindowPtr pWin;
+    xEvent *pEvents;
+    int count;
+    Mask filter;
+    ClientPtr dontClient;
+{
+    register OtherClients *other;
+
+
+    if (pWin->eventMask & filter)
+    {
+        if (wClient(pWin) == dontClient)
+	    return 0;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	    return XineramaTryClientEventsResult(
+			wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+	return TryClientEvents(wClient(pWin), pEvents, count,
+			       pWin->eventMask, filter, NullGrab);
+    }
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->mask & filter)
+	{
+            if (SameClient(other, dontClient))
+		return 0;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	      return XineramaTryClientEventsResult(
+			rClient(other), NullGrab, other->mask, filter);
+#endif
+	    return TryClientEvents(rClient(other), pEvents, count,
+				   other->mask, filter, NullGrab);
+	}
+    }
+    return 2;
+}
+
+static void
+#if NeedFunctionPrototypes
+FixUpEventFromWindow(
+    xEvent *xE,
+    WindowPtr pWin,
+    Window child,
+    Bool calcChild)
+#else
+FixUpEventFromWindow(xE, pWin, child, calcChild)
+    xEvent *xE;
+    WindowPtr pWin;
+    Window child;
+    Bool calcChild;
+#endif
+{
+    if (calcChild)
+    {
+        WindowPtr w=spriteTrace[spriteTraceGood-1];
+	/* If the search ends up past the root should the child field be 
+	 	set to none or should the value in the argument be passed 
+		through. It probably doesn't matter since everyone calls 
+		this function with child == None anyway. */
+
+        while (w) 
+        {
+            /* If the source window is same as event window, child should be
+		none.  Don't bother going all all the way back to the root. */
+
+ 	    if (w == pWin)
+	    { 
+   		child = None;
+ 		break;
+	    }
+	    
+	    if (w->parent == pWin)
+	    {
+		child = w->drawable.id;
+		break;
+            }
+ 	    w = w->parent;
+        } 	    
+    }
+    XE_KBPTR.root = ROOT->drawable.id;
+    XE_KBPTR.event = pWin->drawable.id;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	XE_KBPTR.sameScreen = xTrue;
+	XE_KBPTR.child = child;
+	XE_KBPTR.eventX =
+	XE_KBPTR.rootX - pWin->drawable.x;
+	XE_KBPTR.eventY =
+	XE_KBPTR.rootY - pWin->drawable.y;
+    }
+    else
+    {
+	XE_KBPTR.sameScreen = xFalse;
+	XE_KBPTR.child = None;
+	XE_KBPTR.eventX = 0;
+	XE_KBPTR.eventY = 0;
+    }
+}
+
+int
+DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
+    register WindowPtr pWin, stopAt;
+    register xEvent *xE;
+    GrabPtr grab;
+    DeviceIntPtr dev;
+    int count;
+{
+    Window child = None;
+    int type = xE->u.u.type;
+    Mask filter = filters[type];
+    int deliveries = 0;
+
+    if (type & EXTENSION_EVENT_BASE)
+    {
+	register OtherInputMasks *inputMasks;
+	int mskidx = dev->id;
+
+	inputMasks = wOtherInputMasks(pWin);
+	if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+	    return 0;
+	while (pWin)
+	{
+	    if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, mskidx);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(inputMasks &&
+		 (filter & inputMasks->dontPropagateMask[mskidx])))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	    if (pWin)
+		inputMasks = wOtherInputMasks(pWin);
+	}
+    }
+    else
+    {
+	if (!(filter & pWin->deliverableEvents))
+	    return 0;
+	while (pWin)
+	{
+	    if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, 0);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(filter & wDontPropagateMask(pWin)))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	}
+    }
+    return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(pWin, xE, count, otherParent)
+    register WindowPtr pWin, otherParent;
+    register xEvent *xE;
+    int count;
+{
+    Mask filter;
+    int     deliveries;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+	return count;
+#endif
+
+    if (!count)
+	return 0;
+    filter = filters[xE->u.u.type];
+    if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+	xE->u.destroyNotify.event = pWin->drawable.id;
+    if (filter != StructureAndSubMask)
+	return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+    deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+				       NullGrab, 0);
+    if (pWin->parent)
+    {
+	xE->u.destroyNotify.event = pWin->parent->drawable.id;
+	deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+					    SubstructureNotifyMask, NullGrab,
+					    0);
+	if (xE->u.u.type == ReparentNotify)
+	{
+	    xE->u.destroyNotify.event = otherParent->drawable.id;
+	    deliveries += DeliverEventsToWindow(otherParent, xE, count,
+						SubstructureNotifyMask,
+						NullGrab, 0);
+	}
+    }
+    return deliveries;
+}
+
+
+static Bool 
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+	return TRUE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	   if(POINT_IN_REGION(sprite.screen, 
+			&sprite.windows[i]->borderSize, 
+			x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, 
+			y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, 
+			&box))
+		return TRUE;
+	}
+    }
+#endif
+    return FALSE;
+}
+
+static WindowPtr 
+#if NeedFunctionPrototypes
+XYToWindow(int x, int y)
+#else
+XYToWindow(x, y)
+	int x, y;
+#endif
+{
+    register WindowPtr  pWin;
+
+    spriteTraceGood = 1;	/* root window still there */
+
+    if (nxagentOption(Rootless))
+    {
+      if (nxagentLastEnteredWindow == NULL)
+      {
+        return ROOT;
+      }
+
+      pWin = ROOT->lastChild;
+
+      while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
+      {
+        pWin = pWin->prevSib;
+      }
+    }
+    else
+    {
+      pWin = ROOT->firstChild;
+    }
+
+    while (pWin)
+    {
+	if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		    wBorderWidth(pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		    wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+#endif
+		)
+	{
+	    if (spriteTraceGood >= spriteTraceSize)
+	    {
+		spriteTraceSize += 10;
+		Must_have_memory = TRUE; /* XXX */
+		spriteTrace = (WindowPtr *)xrealloc(
+		    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    spriteTrace[spriteTraceGood++] = pWin;
+	    pWin = pWin->firstChild;
+	}
+	else
+	    pWin = pWin->nextSib;
+    }
+    return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+#if NeedFunctionPrototypes
+CheckMotion(xEvent *xE)
+#else
+CheckMotion(xE)
+    xEvent *xE;
+#endif
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaCheckMotion(xE);
+#endif
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+	{
+	    sprite.hot.pScreen = sprite.hotPhys.pScreen;
+	    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+	}
+	sprite.hot.x = XE_KBPTR.rootX;
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+	sprite.hotPhys = sprite.hot;
+
+        /*
+         * This code force cursor position to be inside the
+         * root window of the agent. We can't view a reason
+         * to do this and it interacts in an undesirable way
+         * with toggling fullscreen.
+         *
+         * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+         *          (sprite.hotPhys.y != XE_KBPTR.rootY))
+         * {
+         *   (*sprite.hotPhys.pScreen->SetCursorPosition)(
+         *       sprite.hotPhys.pScreen,
+         *           sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+         * }
+         */
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+    if (!(sprite.win->deliverableEvents &
+	  Motion_Filter(inputInfo.pointer->button))
+	!syncEvents.playingEvents)
+    {
+	/* XXX Do PointerNonInterestBox here */
+    }
+#endif
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+    (void) CheckMotion((xEvent *)NULL);
+}
+
+void
+DefineInitialRootWindow(win)
+    register WindowPtr win;
+{
+    register ScreenPtr pScreen = win->drawable.pScreen;
+    extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+    extern int nxagentShadowInit(ScreenPtr, WindowPtr);
+
+    sprite.hotPhys.pScreen = pScreen;
+    sprite.hotPhys.x = pScreen->width / 2;
+    sprite.hotPhys.y = pScreen->height / 2;
+    sprite.hot = sprite.hotPhys;
+    sprite.hotLimits.x2 = pScreen->width;
+    sprite.hotLimits.y2 = pScreen->height;
+    sprite.win = win;
+    sprite.current = wCursor (win);
+    spriteTraceGood = 1;
+    ROOT = win;
+    (*pScreen->CursorLimits) (
+	pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+    sprite.confined = FALSE;
+    (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+    (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+    (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+	sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+	sprite.hotLimits.x2 = PanoramiXPixWidth  - panoramiXdataPtr[0].x;
+	sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+	sprite.physLimits = sprite.hotLimits;
+	sprite.confineWin = NullWindow;
+	sprite.screen = pScreen;
+	/* gotta UNINIT these someplace */
+	REGION_INIT(pScreen, &sprite.Reg1, NullBox, 1);
+	REGION_INIT(pScreen, &sprite.Reg2, NullBox, 1);
+    }
+#endif
+
+    nxagentInitViewportFrame(pScreen, win);
+
+    if (nxagentOption(Shadow))
+    {
+      if (nxagentShadowInit(pScreen, win) == -1)
+      {
+        GiveUp(0);
+      }
+    }
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+/*ARGSUSED*/
+void
+WindowHasNewCursor(pWin)
+    WindowPtr pWin;
+{
+    PostNewCursor();
+}
+
+void
+NewCurrentScreen(newScreen, x, y)
+    ScreenPtr newScreen;
+    int x,y;
+{
+    sprite.hotPhys.x = x;
+    sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - 
+			    panoramiXdataPtr[0].x;
+	sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - 
+			    panoramiXdataPtr[0].y;
+	if (newScreen != sprite.screen) {
+	    sprite.screen = newScreen;
+	    /* Make sure we tell the DDX to update its copy of the screen */
+	    if(sprite.confineWin)
+		XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+	    else
+		XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+	    /* if the pointer wasn't confined, the DDX won't get 
+	       told of the pointer warp so we reposition it here */
+	    if(!syncEvents.playingEvents)
+		(*sprite.screen->SetCursorPosition)(sprite.screen,
+		    sprite.hotPhys.x + panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x,
+		    sprite.hotPhys.y + panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+	}
+    } else 
+#endif
+    if (newScreen != sprite.hotPhys.pScreen)
+	ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+    WindowPtr pWin,
+    int x,
+    int y
+)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    BoxRec box;
+    int i, xoff, yoff;
+
+    if (!pWin->realized) return FALSE;
+
+    if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+        return TRUE;
+    
+    if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+    xoff = x + panoramiXdataPtr[0].x;  
+    yoff = y + panoramiXdataPtr[0].y;  
+
+    for(i = 1; i < PanoramiXNumScreens; i++) {
+	pWin = sprite.windows[i];
+	pScreen = pWin->drawable.pScreen;
+	x = xoff - panoramiXdataPtr[i].x;
+	y = yoff - panoramiXdataPtr[i].y;
+
+	if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+            return TRUE;
+
+    }
+
+    return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+
+    REQUEST(xWarpPointerReq);
+
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if(source == WindowTable[0]) {
+	    winX -= panoramiXdataPtr[0].x;
+	    winY -= panoramiXdataPtr[0].y;
+	}
+	if (x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !XineramaPointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	if(dest == WindowTable[0]) {
+	    x -= panoramiXdataPtr[0].x;
+	    y -= panoramiXdataPtr[0].y;
+	}
+    } 
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < sprite.physLimits.x1)
+	x = sprite.physLimits.x1;
+    else if (x >= sprite.physLimits.x2)
+	x = sprite.physLimits.x2 - 1;
+    if (y < sprite.physLimits.y1)
+	y = sprite.physLimits.y1;
+    else if (y >= sprite.physLimits.y2)
+	y = sprite.physLimits.y2 - 1;
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &x, &y);
+
+    XineramaSetCursorPosition(x, y, TRUE);
+
+    return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(client)
+    ClientPtr client;
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+    ScreenPtr	newScreen;
+
+    REQUEST(xWarpPointerReq);
+
+    REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaWarpPointer(client);
+#endif
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+	    x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !PointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) 
+    {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	newScreen = dest->drawable.pScreen;
+    } else 
+	newScreen = sprite.hotPhys.pScreen;
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < 0)
+	x = 0;
+    else if (x >= newScreen->width)
+	x = newScreen->width - 1;
+    if (y < 0)
+	y = 0;
+    else if (y >= newScreen->height)
+	y = newScreen->height - 1;
+
+    if (newScreen == sprite.hotPhys.pScreen)
+    {
+	if (x < sprite.physLimits.x1)
+	    x = sprite.physLimits.x1;
+	else if (x >= sprite.physLimits.x2)
+	    x = sprite.physLimits.x2 - 1;
+	if (y < sprite.physLimits.y1)
+	    y = sprite.physLimits.y1;
+	else if (y >= sprite.physLimits.y2)
+	    y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+	(*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+    }
+    else if (!PointerConfinedToScreen())
+    {
+	NewCurrentScreen(newScreen, x, y);
+    }
+    return Success;
+}
+
+static Bool 
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+     if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+	return TRUE;
+
+#ifdef PANORAMIX
+     if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	    if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+		return TRUE;
+	}
+     }
+#endif
+     return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+	passive grab set on the window to be activated. */
+
+static Bool
+#if NeedFunctionPrototypes
+CheckPassiveGrabsOnWindow(
+    WindowPtr pWin,
+    register DeviceIntPtr device,
+    register xEvent *xE,
+    int count)
+#else
+CheckPassiveGrabsOnWindow(pWin, device, xE, count)
+    WindowPtr pWin;
+    register DeviceIntPtr device;
+    register xEvent *xE;
+    int count;
+#endif
+{
+    register GrabPtr grab = wPassiveGrabs(pWin);
+    GrabRec tempGrab;
+    register xEvent *dxE;
+
+    if (!grab)
+	return FALSE;
+    tempGrab.window = pWin;
+    tempGrab.device = device;
+    tempGrab.type = xE->u.u.type;
+    tempGrab.detail.exact = xE->u.u.detail;
+    tempGrab.detail.pMask = NULL;
+    tempGrab.modifiersDetail.pMask = NULL;
+    for (; grab; grab = grab->next)
+    {
+#ifdef XKB
+	DeviceIntPtr	gdev;
+	XkbSrvInfoPtr	xkbi;
+
+	gdev= grab->modifierDevice;
+	xkbi= gdev->key->xkbInfo;
+#endif
+	tempGrab.modifierDevice = grab->modifierDevice;
+	if (device == grab->modifierDevice &&
+	    (xE->u.u.type == KeyPress
+#ifdef XINPUT
+	     || xE->u.u.type == DeviceKeyPress
+#endif
+	     ))
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->prev_state;
+#endif
+	else
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->state;
+#endif
+	if (GrabMatchesSecond(&tempGrab, grab) &&
+	    (!grab->confineTo ||
+	     (grab->confineTo->realized && 
+				BorderSizeNotEmpty(grab->confineTo))))
+	{
+#ifdef XCSECURITY
+	    if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+		return FALSE;
+#endif
+#ifdef XKB
+	    if (!noXkbExtension) {
+		XE_KBPTR.state &= 0x1f00;
+		XE_KBPTR.state |=
+				tempGrab.modifiersDetail.exact&(~0x1f00);
+	    }
+#endif
+	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+ 
+	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+	    (void) TryClientEvents(rClient(grab), xE, count,
+				   filters[xE->u.u.type],
+				   filters[xE->u.u.type],  grab);
+
+	    if (device->sync.state == FROZEN_NO_EVENT)
+	    {
+		if (device->sync.evcount < count)
+		{
+		    Must_have_memory = TRUE; /* XXX */
+		    device->sync.event = (xEvent *)xrealloc(device->sync.event,
+							    count*
+							    sizeof(xEvent));
+		    Must_have_memory = FALSE; /* XXX */
+		}
+		device->sync.evcount = count;
+		for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+		    *dxE = *xE;
+	    	device->sync.state = FROZEN_WITH_EVENT;
+            }	
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated.  If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated.  If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated.  If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(device, xE, checkFirst, count)
+    register DeviceIntPtr device;
+    register xEvent *xE;
+    int checkFirst;
+    int count;
+{
+    register int i;
+    register WindowPtr pWin = NULL;
+    register FocusClassPtr focus = device->focus;
+
+    if ((xE->u.u.type == ButtonPress
+#ifdef XINPUT
+	 || xE->u.u.type == DeviceButtonPress
+#endif
+	 ) && device->button->buttonsDown != 1)
+	return FALSE;
+
+    i = checkFirst;
+
+    if (focus)
+    {
+	for (; i < focus->traceGood; i++)
+	{
+	    pWin = focus->trace[i];
+	    if (pWin->optional &&
+		CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+		return TRUE;
+	}
+  
+	if ((focus->win == NoneWin) ||
+	    (i >= spriteTraceGood) ||
+	    ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+	    return FALSE;
+    }
+
+    for (; i < spriteTraceGood; i++)
+    {
+	pWin = spriteTrace[i];
+	if (pWin->optional &&
+	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+DeliverFocusedEvent(keybd, xE, window, count)
+    xEvent *xE;
+    DeviceIntPtr keybd;
+    WindowPtr window;
+    int count;
+{
+    WindowPtr focus = keybd->focus->win;
+    int mskidx = 0;
+
+    if (focus == FollowKeyboardWin)
+	focus = inputInfo.keyboard->focus->win;
+    if (!focus)
+	return;
+    if (focus == PointerRootWin)
+    {
+	DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+	return;
+    }
+    if ((focus == window) || IsParent(focus, window))
+    {
+	if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+	    return;
+    }
+    /* just deliver it to the focus window */
+    FixUpEventFromWindow(xE, focus, None, FALSE);
+    if (xE->u.u.type & EXTENSION_EVENT_BASE)
+	mskidx = keybd->id;
+    (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+				NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
+    register xEvent *xE;
+    register DeviceIntPtr thisDev;
+    Bool deactivateGrab;
+    int count;
+{
+    register GrabPtr grab = thisDev->grab;
+    int deliveries = 0;
+    register DeviceIntPtr dev;
+    register xEvent *dxE;
+
+    if (grab->ownerEvents)
+    {
+	WindowPtr focus;
+
+	if (thisDev->focus)
+	{
+	    focus = thisDev->focus->win;
+	    if (focus == FollowKeyboardWin)
+		focus = inputInfo.keyboard->focus->win;
+	}
+	else
+	    focus = PointerRootWin;
+	if (focus == PointerRootWin)
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+					     thisDev, count);
+	else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+					     thisDev, count);
+	else if (focus)
+	    deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+					     thisDev, count);
+    }
+    if (!deliveries)
+    {
+	FixUpEventFromWindow(xE, grab->window, None, TRUE);
+	deliveries = TryClientEvents(rClient(grab), xE, count,
+				     (Mask)grab->eventMask,
+				     filters[xE->u.u.type], grab);
+	if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+			   || xE->u.u.type == DeviceMotionNotify
+#endif
+			   ))
+	    thisDev->valuator->motionHintWindow = grab->window;
+    }
+    if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+					  && xE->u.u.type != DeviceMotionNotify
+#endif
+					  ))
+	switch (thisDev->sync.state)
+	{
+	case FREEZE_BOTH_NEXT_EVENT:
+	    for (dev = inputInfo.devices; dev; dev = dev->next)
+	    {
+		if (dev == thisDev)
+		    continue;
+		FreezeThaw(dev, TRUE);
+		if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+		    (CLIENT_BITS(dev->grab->resource) ==
+		     CLIENT_BITS(thisDev->grab->resource)))
+		    dev->sync.state = FROZEN_NO_EVENT;
+		else
+		    dev->sync.other = thisDev->grab;
+	    }
+	    /* fall through */
+	case FREEZE_NEXT_EVENT:
+	    thisDev->sync.state = FROZEN_WITH_EVENT;
+	    FreezeThaw(thisDev, TRUE);
+	    if (thisDev->sync.evcount < count)
+	    {
+		Must_have_memory = TRUE; /* XXX */
+		thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+							 count*sizeof(xEvent));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    thisDev->sync.evcount = count;
+	    for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+		*dxE = *xE;
+	    break;
+	}
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (xE, keybd, count)
+#else
+ProcessKeyboardEvent (xE, keybd, count)
+#endif
+    register xEvent *xE;
+    register DeviceIntPtr keybd;
+    int count;
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register int    i;
+    register CARD8  modifiers;
+    register CARD16 mask;
+    GrabPtr         grab = keybd->grab;
+    Bool            deactivateGrab = FALSE;
+    register KeyClassPtr keyc = keybd->key;
+
+    if (!syncEvents.playingEvents)
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+    XE_KBPTR.rootX = sprite.hot.x;
+    XE_KBPTR.rootY = sprite.hot.y;
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+    modifiers = keyc->modifierMap[key];
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    if (*kptr & bit) /* allow ddx to generate multiple downs */
+	    {   
+		if (!modifiers)
+		{
+		    xE->u.u.type = KeyRelease;
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		    xE->u.u.type = KeyPress;
+		    /* release can have side effects, don't fall through */
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		}
+		return;
+	    }
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr |= bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers)
+		{
+		    /* This key affects modifier "i" */
+		    keyc->modifierKeyCount[i]++;
+		    keyc->state |= mask;
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+	    {
+		keybd->activatingKey = key;
+		return;
+	    }
+	    break;
+	case KeyRelease: 
+	    if (!(*kptr & bit)) /* guard against duplicates */
+		return;
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr &= ~bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers) {
+		    /* This key affects modifier "i" */
+		    if (--keyc->modifierKeyCount[i] <= 0) {
+			keyc->state &= ~mask;
+			keyc->modifierKeyCount[i] = 0;
+		    }
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+    if (grab)
+	DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+    else
+	DeliverFocusedEvent(keybd, xE, sprite.win, count);
+    if (deactivateGrab)
+        (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+   this is only used when the pressing of keys does not cause 
+   CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (xE, keybd)
+    register xEvent *xE;
+    register DeviceIntPtr keybd;
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register KeyClassPtr keyc = keybd->key;
+
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("FixKeyState: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    *kptr |= bit;
+	    break;
+	case KeyRelease: 
+	    *kptr &= ~bit;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (xE, mouse, count)
+#else
+ProcessPointerEvent (xE, mouse, count)
+#endif
+    register xEvent 		*xE;
+    register DeviceIntPtr 	mouse;
+    int				count;
+{
+    register GrabPtr	grab = mouse->grab;
+    Bool                deactivateGrab = FALSE;
+    register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+    XkbSrvInfoPtr xkbi;
+
+    xkbi = inputInfo.keyboard->key->xkbInfo;
+#endif
+
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE)
+    XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+			(noXkbExtension ?
+				inputInfo.keyboard->key->state :
+				xkbi->state.grab_mods)
+#else
+			inputInfo.keyboard->key->state
+#endif
+				    ));
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    /* see comment in EnqueueEvents regarding the next three lines */
+	    if (xE->u.u.type == MotionNotify)
+		XE_KBPTR.root =
+		    WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    if (xE->u.u.type != MotionNotify)
+    {
+	register int  key;
+	register BYTE *kptr;
+	int           bit;
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+
+	key = xE->u.u.detail;
+	kptr = &butc->down[key >> 3];
+	bit = 1 << (key & 7);
+	switch (xE->u.u.type)
+	{
+	case ButtonPress: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (!(*kptr & bit))
+		butc->buttonsDown++;
+	    butc->motionMask = ButtonMotionMask;
+	    *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!grab)
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		    return;
+	    break;
+	case ButtonRelease: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (*kptr & bit)
+		--butc->buttonsDown;
+	    if (!butc->buttonsDown)
+		butc->motionMask = 0;
+	    *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!butc->state && mouse->fromPassiveGrab)
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("bogus pointer event from ddx");
+	}
+    }
+    else if (!CheckMotion(xE))
+	return;
+    if (grab)
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    else
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    if (deactivateGrab)
+        (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+	(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+    register WindowPtr pWin;
+{
+    register OtherClients *others;
+    register WindowPtr pChild;
+
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->optional)
+	{
+	    pChild->optional->otherEventMasks = 0;
+	    for (others = wOtherClients(pChild); others; others = others->next)
+	    {
+		pChild->optional->otherEventMasks |= others->mask;
+	    }
+	}
+	pChild->deliverableEvents = pChild->eventMask|
+				    wOtherEventMasks(pChild);
+	if (pChild->parent)
+	    pChild->deliverableEvents |=
+		(pChild->parent->deliverableEvents &
+		 ~wDontPropagateMask(pChild) & PropagateMask);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+int
+OtherClientGone(value, id)
+    pointer value; /* must conform to DeleteType */
+    XID   id;
+{
+    register OtherClientsPtr other, prev;
+    register WindowPtr pWin = (WindowPtr)value;
+
+    prev = 0;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->resource == id)
+	{
+	    if (prev)
+		prev->next = other->next;
+	    else
+	    {
+		if (!(pWin->optional->otherClients = other->next))
+		    CheckWindowOptionalNeed (pWin);
+	    }
+	    xfree(other);
+	    RecalculateDeliverableEvents(pWin);
+	    return(Success);
+	}
+	prev = other;
+    }
+    FatalError("client not on event list");
+    /*NOTREACHED*/
+    return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(pWin, client, mask)
+    register WindowPtr pWin;
+    register ClientPtr client;
+    Mask mask;
+{
+    Mask check;
+    OtherClients * others;
+
+    if (mask & ~AllEventMasks)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    check = (mask & AtMostOneClient);
+    if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+    {				       /* It is illegal for two different
+				          clients to select on any of the
+				          events for AtMostOneClient. However,
+				          it is OK, for some client to
+				          continue selecting on one of those
+				          events.  */
+	if ((wClient(pWin) != client) && (check & pWin->eventMask))
+	    return BadAccess;
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (!SameClient(others, client) && (check & others->mask))
+		return BadAccess;
+	}
+    }
+    if (wClient (pWin) == client)
+    {
+	check = pWin->eventMask;
+#ifdef SGIMISC
+	pWin->eventMask =
+	    (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+	pWin->eventMask = mask;
+#endif
+    }
+    else
+    {
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (SameClient(others, client))
+	    {
+		check = others->mask;
+#ifdef SGIMISC
+		mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+		if (mask == 0)
+		{
+		    FreeResource(others->resource, RT_NONE);
+		    return Success;
+		}
+		else
+		    others->mask = mask;
+		goto maskSet;
+	    }
+	}
+	check = 0;
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return BadAlloc;
+	others = (OtherClients *) xalloc(sizeof(OtherClients));
+	if (!others)
+	    return BadAlloc;
+	others->mask = mask;
+	others->resource = FakeClientID(client->index);
+	others->next = pWin->optional->otherClients;
+	pWin->optional->otherClients = others;
+	if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+	    return BadAlloc;
+    }
+maskSet: 
+    if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+	(mask & PointerMotionHintMask) &&
+	!(check & PointerMotionHintMask) &&
+	!inputInfo.pointer->grab)
+	inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+/*ARGSUSED*/
+int
+EventSuppressForWindow(pWin, client, mask, checkOptional)
+    register WindowPtr pWin;
+    register ClientPtr client;
+    Mask mask;
+    Bool *checkOptional;
+{
+    register int i, free;
+
+    if ((mask & ~PropagateMask) && !permitOldBugs)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    if (pWin->dontPropagate)
+	DontPropagateRefCnts[pWin->dontPropagate]--;
+    if (!mask)
+	i = 0;
+    else
+    {
+	for (i = DNPMCOUNT, free = 0; --i > 0; )
+	{
+	    if (!DontPropagateRefCnts[i])
+		free = i;
+	    else if (mask == DontPropagateMasks[i])
+		break;
+	}
+	if (!i && free)
+	{
+	    i = free;
+	    DontPropagateMasks[i] = mask;
+	}
+    }
+    if (i || !mask)
+    {
+	pWin->dontPropagate = i;
+	if (i)
+	    DontPropagateRefCnts[i]++;
+	if (pWin->optional)
+	{
+	    pWin->optional->dontPropagateMask = mask;
+	    *checkOptional = TRUE;
+	}
+    }
+    else
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	{
+	    if (pWin->dontPropagate)
+		DontPropagateRefCnts[pWin->dontPropagate]++;
+	    return BadAlloc;
+	}
+	pWin->dontPropagate = 0;
+        pWin->optional->dontPropagateMask = mask;
+    }
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+static WindowPtr 
+#if NeedFunctionPrototypes
+CommonAncestor(
+    register WindowPtr a,
+    register WindowPtr b)
+#else
+CommonAncestor(a, b)
+    register WindowPtr a, b;
+#endif
+{
+    for (b = b->parent; b; b = b->parent)
+	if (IsParent(b, a)) return b;
+    return NullWindow;
+}
+
+static void
+#if NeedFunctionPrototypes
+EnterLeaveEvent(
+    int type,
+    int mode,
+    int detail,
+    register WindowPtr pWin,
+    Window child)
+#else
+EnterLeaveEvent(type, mode, detail, pWin, child)
+    int type, mode, detail;
+    register WindowPtr pWin;
+    Window child;
+#endif
+{
+    xEvent		event;
+    register DeviceIntPtr keybd = inputInfo.keyboard;
+    WindowPtr		focus;
+    register DeviceIntPtr mouse = inputInfo.pointer;
+    register GrabPtr	grab = mouse->grab;
+    Mask		mask;
+
+    if ((pWin == mouse->valuator->motionHintWindow) &&
+	(detail != NotifyInferior))
+	mouse->valuator->motionHintWindow = NullWindow;
+    if (grab)
+    {
+	mask = (pWin == grab->window) ? grab->eventMask : 0;
+	if (grab->ownerEvents)
+	    mask |= EventMaskForClient(pWin, rClient(grab));
+    }
+    else
+    {
+	mask = pWin->eventMask | wOtherEventMasks(pWin);
+    }
+    if (mask & filters[type])
+    {
+	event.u.u.type = type;
+	event.u.u.detail = detail;
+	event.u.enterLeave.time = currentTime.milliseconds;
+	event.u.enterLeave.rootX = sprite.hot.x;
+	event.u.enterLeave.rootY = sprite.hot.y;
+	/* Counts on the same initial structure of crossing & button events! */
+	FixUpEventFromWindow(&event, pWin, None, FALSE);
+	/* Enter/Leave events always set child */
+	event.u.enterLeave.child = child;
+	event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+					    ELFlagSameScreen : 0;
+#ifdef XKB
+	if (!noXkbExtension) {
+	    event.u.enterLeave.state = mouse->button->state & 0x1f00;
+	    event.u.enterLeave.state |= 
+			XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+	} else
+#endif
+	event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+	event.u.enterLeave.mode = mode;
+	focus = keybd->focus->win;
+	if ((focus != NoneWin) &&
+	    ((pWin == focus) || (focus == PointerRootWin) ||
+	     IsParent(focus, pWin)))
+	    event.u.enterLeave.flags |= ELFlagFocus;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), &event, 1, mask,
+				  filters[type], grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+					NullGrab, 0);
+    }
+    if ((type == EnterNotify) && (mask & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+
+#ifdef XCSECURITY
+	ClientPtr client = grab ? rClient(grab)
+				: clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+	ke.type = KeymapNotify;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+				  KeymapStateMask, grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+					KeymapStateMask, NullGrab, 0);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+#else
+EnterNotifies(ancestor, child, mode, detail)
+    WindowPtr ancestor, child;
+    int mode, detail;
+#endif
+{
+    WindowPtr	parent = child->parent;
+
+    if (ancestor == parent)
+	return;
+    EnterNotifies(ancestor, parent, mode, detail);
+    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+#if NeedFunctionPrototypes
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+#else
+LeaveNotifies(child, ancestor, mode, detail)
+    WindowPtr child, ancestor;
+    int detail, mode;
+#endif
+{
+    register WindowPtr  pWin;
+
+    if (ancestor == child)
+	return;
+    for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+    {
+	EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+	child = pWin;
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+#else
+DoEnterLeaveEvents(fromWin, toWin, mode)
+    WindowPtr fromWin, toWin;
+    int mode;
+#endif
+{
+    if (fromWin == toWin)
+	return;
+    if (IsParent(fromWin, toWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+	EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+    }
+    else if (IsParent(toWin, fromWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+	LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+    }
+    else
+    { /* neither fromWin nor toWin is descendent of the other */
+	WindowPtr common = CommonAncestor(toWin, fromWin);
+	/* common == NullWindow ==> different screens */
+	EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+	LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+	EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+#else
+FocusEvent(dev, type, mode, detail, pWin)
+    DeviceIntPtr dev;
+    int type, mode, detail;
+    register WindowPtr pWin;
+#endif
+{
+    xEvent event;
+
+#ifdef XINPUT
+    if (dev != inputInfo.keyboard)
+    {
+	DeviceFocusEvent(dev, type, mode, detail, pWin);
+	return;
+    }
+#endif
+    event.u.focus.mode = mode;
+    event.u.u.type = type;
+    event.u.u.detail = detail;
+    event.u.focus.window = pWin->drawable.id;
+    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+				0);
+    if ((type == FocusIn) &&
+	((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+#ifdef XCSECURITY
+	ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+	ke.type = KeymapNotify;
+	(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+				    KeymapStateMask, NullGrab, 0);
+    }
+}
+
+ /*
+  * recursive because it is easier
+  * no-op if child not descended from ancestor
+  */
+static Bool
+#if NeedFunctionPrototypes
+FocusInEvents(
+    DeviceIntPtr dev,
+    WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+    int mode, int detail,
+    Bool doAncestor)
+#else
+FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
+    DeviceIntPtr dev;
+    WindowPtr ancestor, child, skipChild;
+    int mode, detail;
+    Bool doAncestor;
+#endif
+{
+    if (child == NullWindow)
+	return ancestor == NullWindow;
+    if (ancestor == child)
+    {
+	if (doAncestor)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+		      doAncestor))
+    {
+	if (child != skipChild)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+#if NeedFunctionPrototypes
+FocusOutEvents(
+    DeviceIntPtr dev,
+    WindowPtr child, WindowPtr ancestor,
+    int mode, int detail,
+    Bool doAncestor)
+#else
+FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
+    DeviceIntPtr dev;
+    WindowPtr child, ancestor;
+    int mode;
+    int detail;
+    Bool doAncestor;
+#endif
+{
+    register WindowPtr  pWin;
+
+    for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+	FocusEvent(dev, FocusOut, mode, detail, pWin);
+    if (doAncestor)
+	FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(dev, fromWin, toWin, mode)
+    DeviceIntPtr dev;
+    WindowPtr fromWin, toWin;
+    int mode;
+{
+    int     out, in;		       /* for holding details for to/from
+				          PointerRoot/None */
+    int     i;
+
+    if (fromWin == toWin)
+	return;
+    out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+    in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+    if ((toWin == NullWindow) || (toWin == PointerRootWin))
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+   	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+	    /* Notify all the roots */
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	}
+	else
+	{
+	    if (IsParent(fromWin, sprite.win))
+	      FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+			     FALSE);
+	    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+	    /* next call catches the root too, if the screen changed */
+	    FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+			   NotifyNonlinearVirtual, FALSE);
+	}
+	/* Notify all the roots */
+#ifdef PANORAMIX
+	if ( !noPanoramiXExtension )
+	    FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+	else 
+#endif
+	    for (i=0; i<screenInfo.numScreens; i++)
+	        FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+	if (toWin == PointerRootWin)
+	    (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+				NotifyPointer, TRUE);
+    }
+    else
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	    if (toWin->parent != NullWindow)
+	      (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+				  NotifyNonlinearVirtual, TRUE);
+	    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+	    if (IsParent(toWin, sprite.win))
+    	       (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+				   NotifyPointer, FALSE);
+	}
+	else
+	{
+	    if (IsParent(toWin, fromWin))
+	    {
+		FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+		FocusOutEvents(dev, fromWin->parent, toWin, mode,
+			       NotifyVirtual, FALSE);
+		FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+		if ((IsParent(toWin, sprite.win)) &&
+			(sprite.win != fromWin) &&
+			(!IsParent(fromWin, sprite.win)) &&
+			(!IsParent(sprite.win, fromWin)))
+		    (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					mode, NotifyPointer, FALSE);
+	    }
+	    else
+		if (IsParent(fromWin, toWin))
+		{
+		    if ((IsParent(fromWin, sprite.win)) &&
+			    (sprite.win != fromWin) &&
+			    (!IsParent(toWin, sprite.win)) &&
+			    (!IsParent(sprite.win, toWin)))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+		    (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+					NotifyVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+		}
+		else
+		{
+		/* neither fromWin or toWin is child of other */
+		    WindowPtr common = CommonAncestor(toWin, fromWin);
+		/* common == NullWindow ==> different screens */
+		    if (IsParent(fromWin, sprite.win))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+		    if (fromWin->parent != NullWindow)
+		      FocusOutEvents(dev, fromWin->parent, common, mode,
+				     NotifyNonlinearVirtual, FALSE);
+		    if (toWin->parent != NullWindow)
+		      (void)FocusInEvents(dev, common, toWin, toWin, mode,
+					  NotifyNonlinearVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+		    if (IsParent(toWin, sprite.win))
+			(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					    mode, NotifyPointer, FALSE);
+		}
+	}
+    }
+}
+
+int
+#if NeedFunctionPrototypes
+SetInputFocus(
+    ClientPtr client,
+    DeviceIntPtr dev,
+    Window focusID,
+    CARD8 revertTo,
+    Time ctime,
+    Bool followOK)
+#else
+SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
+    ClientPtr client;
+    DeviceIntPtr dev;
+    Window focusID;
+    CARD8 revertTo;
+    Time ctime;
+    Bool followOK;
+#endif
+{
+    register FocusClassPtr focus;
+    register WindowPtr focusWin;
+    int mode;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((revertTo != RevertToParent) &&
+	(revertTo != RevertToPointerRoot) &&
+	(revertTo != RevertToNone) &&
+	((revertTo != RevertToFollowKeyboard) || !followOK))
+    {
+	client->errorValue = revertTo;
+	return BadValue;
+    }
+    time = ClientTimeToServerTime(ctime);
+    if ((focusID == None) || (focusID == PointerRoot))
+	focusWin = (WindowPtr)(long)focusID;
+    else if ((focusID == FollowKeyboard) && followOK)
+	focusWin = inputInfo.keyboard->focus->win;
+    else if (!(focusWin = SecurityLookupWindow(focusID, client,
+					       SecurityReadAccess)))
+	return BadWindow;
+    else
+    {
+ 	/* It is a match error to try to set the input focus to an 
+	unviewable window. */
+
+	if(!focusWin->realized)
+	    return(BadMatch);
+    }
+    focus = dev->focus;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, focus->time) == EARLIER))
+	return Success;
+    mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+    if (focus->win == FollowKeyboardWin)
+	DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+    else
+	DoFocusEvents(dev, focus->win, focusWin, mode);
+    focus->time = time;
+    focus->revert = revertTo;
+    if (focusID == FollowKeyboard)
+	focus->win = FollowKeyboardWin;
+    else
+	focus->win = focusWin;
+    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+	focus->traceGood = 0;
+    else
+    {
+        int depth = 0;
+	register WindowPtr pWin;
+
+        for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+        if (depth > focus->traceSize)
+        {
+	    focus->traceSize = depth+1;
+	    Must_have_memory = TRUE; /* XXX */
+	    focus->trace = (WindowPtr *)xrealloc(focus->trace,
+						 focus->traceSize *
+						 sizeof(WindowPtr));
+	    Must_have_memory = FALSE; /* XXX */
+	}
+	focus->traceGood = depth;
+        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
+	    focus->trace[depth] = pWin;
+    }
+    return Success;
+}
+
+int
+ProcSetInputFocus(client)
+    ClientPtr client;
+{
+    REQUEST(xSetInputFocusReq);
+
+    REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+	return Success;
+#endif
+    return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+			 stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(client)
+    ClientPtr client;
+{
+    xGetInputFocusReply rep;
+    /* REQUEST(xReq); */
+    FocusClassPtr focus = inputInfo.keyboard->focus;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (focus->win == NoneWin)
+	rep.focus = None;
+    else if (focus->win == PointerRootWin)
+	rep.focus = PointerRoot;
+    else rep.focus = focus->win->drawable.id;
+    rep.revertTo = focus->revert;
+    WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+    return Success;
+}
+
+int
+ProcGrabPointer(client)
+    ClientPtr client;
+{
+    xGrabPointerReply rep;
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    WindowPtr pWin, confineTo;
+    CursorPtr cursor, oldCursor;
+    REQUEST(xGrabPointerReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xGrabPointerReq);
+    UpdateCurrentTime();
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+        return BadValue;
+    }
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+	confineTo = NullWindow;
+    else 
+    {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+	/* at this point, some sort of reply is guaranteed. */
+    time = ClientTimeToServerTime(stuff->time);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    grab = device->grab;
+    if ((grab) && !SameClient(grab, client))
+	rep.status = AlreadyGrabbed;
+    else if ((!pWin->realized) ||
+             (confineTo &&
+                !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+	rep.status = GrabNotViewable;
+    else if (device->sync.frozen &&
+	     device->sync.other && !SameClient(device->sync.other, client))
+	rep.status = GrabFrozen;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	rep.status = GrabInvalidTime;
+    else
+    {
+	GrabRec tempGrab;
+
+	oldCursor = NullCursor;
+	if (grab)
+ 	{
+	    if (grab->confineTo && !confineTo)
+		ConfineCursorToWindow(ROOT, FALSE, FALSE);
+	    oldCursor = grab->cursor;
+	}
+	tempGrab.cursor = cursor;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = stuff->ownerEvents;
+	tempGrab.eventMask = stuff->eventMask;
+	tempGrab.confineTo = confineTo;
+	tempGrab.window = pWin;
+	tempGrab.keyboardMode = stuff->keyboardMode;
+	tempGrab.pointerMode = stuff->pointerMode;
+	tempGrab.device = device;
+	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+	if (oldCursor)
+	    FreeCursor (oldCursor, (Cursor)0);
+	rep.status = GrabSuccess;
+    }
+    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+    return Success;
+}
+
+int
+ProcChangeActivePointerGrab(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    register GrabPtr grab = device->grab;
+    CursorPtr newCursor, oldCursor;
+    REQUEST(xChangeActivePointerGrabReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    if (stuff->cursor == None)
+	newCursor = NullCursor;
+    else
+    {
+	newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!newCursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+    if (!grab)
+	return Success;
+    if (!SameClient(grab, client))
+	return Success;
+    time = ClientTimeToServerTime(stuff->time);
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	return Success;
+    oldCursor = grab->cursor;
+    grab->cursor = newCursor;
+    if (newCursor)
+	newCursor->refcnt++;
+    PostNewCursor();
+    if (oldCursor)
+	FreeCursor(oldCursor, (Cursor)0);
+    grab->eventMask = stuff->eventMask;
+    return Success;
+}
+
+int
+ProcUngrabPointer(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	    (grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
+	   mask, status)
+    register ClientPtr client;
+    register DeviceIntPtr dev;
+    unsigned this_mode;
+    unsigned other_mode;
+    Window grabWindow;
+    unsigned ownerEvents;
+    Time ctime;
+    Mask mask;
+    CARD8 *status;
+{
+    register WindowPtr pWin;
+    register GrabPtr grab;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+    {
+	client->errorValue = this_mode;
+        return BadValue;
+    }
+    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+    {
+	client->errorValue = other_mode;
+        return BadValue;
+    }
+    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+    {
+	client->errorValue = ownerEvents;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    time = ClientTimeToServerTime(ctime);
+    grab = dev->grab;
+    if (grab && !SameClient(grab, client))
+	*status = AlreadyGrabbed;
+    else if (!pWin->realized)
+	*status = GrabNotViewable;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+	*status = GrabInvalidTime;
+    else if (dev->sync.frozen &&
+	     dev->sync.other && !SameClient(dev->sync.other, client))
+	*status = GrabFrozen;
+    else
+    {
+	GrabRec tempGrab;
+
+	tempGrab.window = pWin;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = ownerEvents;
+	tempGrab.keyboardMode = this_mode;
+	tempGrab.pointerMode = other_mode;
+	tempGrab.eventMask = mask;
+	tempGrab.device = dev;
+	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+	*status = GrabSuccess;
+    }
+    return Success;
+}
+
+int
+ProcGrabKeyboard(client)
+    ClientPtr client;
+{
+    xGrabKeyboardReply rep;
+    REQUEST(xGrabKeyboardReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+    {
+	result = Success;
+	rep.status = AlreadyGrabbed;
+    }
+    else
+#endif
+    result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+			stuff->pointerMode, stuff->grabWindow,
+			stuff->ownerEvents, stuff->time,
+			KeyPressMask | KeyReleaseMask, &rep.status);
+    if (result != Success)
+	return result;
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+    return Success;
+}
+
+int
+ProcUngrabKeyboard(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.keyboard;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	(grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+ProcQueryPointer(client)
+    ClientPtr client;
+{
+    xQueryPointerReply rep;
+    WindowPtr pWin, t;
+    REQUEST(xResourceReq);
+    DeviceIntPtr mouse = inputInfo.pointer;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (mouse->valuator->motionHintWindow)
+	MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+    rep.length = 0;
+    rep.root = (ROOT)->drawable.id;
+    rep.rootX = sprite.hot.x;
+    rep.rootY = sprite.hot.y;
+    rep.child = None;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	rep.sameScreen = xTrue;
+	rep.winX = sprite.hot.x - pWin->drawable.x;
+	rep.winY = sprite.hot.y - pWin->drawable.y;
+	for (t = sprite.win; t; t = t->parent)
+	    if (t->parent == pWin)
+	    {
+		rep.child = t->drawable.id;
+		break;
+	    }
+    }
+    else
+    {
+	rep.sameScreen = xFalse;
+	rep.winX = 0;
+	rep.winY = 0;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	rep.rootX += panoramiXdataPtr[0].x;
+	rep.rootY += panoramiXdataPtr[0].y;
+	if(stuff->id == rep.root) {
+	    rep.winX += panoramiXdataPtr[0].x;
+	    rep.winY += panoramiXdataPtr[0].y;
+	}
+    }
+#endif
+
+    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+    return(Success);    
+}
+
+void
+InitEvents()
+{
+    int i;
+
+    sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+    inputInfo.numDevices = 0;
+    inputInfo.devices = (DeviceIntPtr)NULL;
+    inputInfo.off_devices = (DeviceIntPtr)NULL;
+    inputInfo.keyboard = (DeviceIntPtr)NULL;
+    inputInfo.pointer = (DeviceIntPtr)NULL;
+    if (spriteTraceSize == 0)
+    {
+	spriteTraceSize = 32;
+	spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+	if (!spriteTrace)
+	    FatalError("failed to allocate spriteTrace");
+    }
+    spriteTraceGood = 0;
+    lastEventMask = OwnerGrabButtonMask;
+    filters[MotionNotify] = PointerMotionMask;
+    sprite.win = NullWindow;
+    sprite.current = NullCursor;
+    sprite.hotLimits.x1 = 0;
+    sprite.hotLimits.y1 = 0;
+    sprite.hotLimits.x2 = 0;
+    sprite.hotLimits.y2 = 0;
+    sprite.confined = FALSE;
+    syncEvents.replayDev = (DeviceIntPtr)NULL;
+    syncEvents.replayWin = NullWindow;
+    while (syncEvents.pending)
+    {
+	QdEventPtr next = syncEvents.pending->next;
+	xfree(syncEvents.pending);
+	syncEvents.pending = next;
+    }
+    syncEvents.pendtail = &syncEvents.pending;
+    syncEvents.playingEvents = FALSE;
+    syncEvents.time.months = 0;
+    syncEvents.time.milliseconds = 0;	/* hardly matters */
+    currentTime.months = 0;
+    currentTime.milliseconds = GetTimeInMillis();
+    lastDeviceEventTime = currentTime;
+    for (i = 0; i < DNPMCOUNT; i++)
+    {
+	DontPropagateMasks[i] = 0;
+	DontPropagateRefCnts[i] = 0;
+    }
+}
+
+void
+CloseDownEvents(void)
+{
+  xfree(spriteTrace);
+  spriteTrace = NULL;
+  spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(client)
+    ClientPtr client;
+{
+    WindowPtr pWin;
+    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+    REQUEST(xSendEventReq);
+
+    REQUEST_SIZE_MATCH(xSendEventReq);
+
+    /* The client's event type must be a core event type or one defined by an
+	extension. */
+
+
+#ifdef NXAGENT_CLIPBOARD
+
+    if (stuff -> event.u.u.type == SelectionNotify)
+    {
+    	extern int nxagentSendNotify(xEvent*);
+	if (nxagentSendNotify(&stuff->event) == 1)
+	  return Success;
+    }
+#endif
+
+    if ( ! ((stuff->event.u.u.type > X_Reply &&
+	     stuff->event.u.u.type < LASTEvent) || 
+	    (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+	     stuff->event.u.u.type < (unsigned)lastEvent)))
+    {
+	client->errorValue = stuff->event.u.u.type;
+	return BadValue;
+    }
+    if (stuff->event.u.u.type == ClientMessage &&
+	stuff->event.u.u.detail != 8 &&
+	stuff->event.u.u.detail != 16 &&
+	stuff->event.u.u.detail != 32 &&
+	!permitOldBugs)
+    {
+	client->errorValue = stuff->event.u.u.detail;
+	return BadValue;
+    }
+    if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+	return BadValue;
+    }
+
+    if (stuff->destination == PointerWindow)
+	pWin = sprite.win;
+    else if (stuff->destination == InputFocus)
+    {
+	WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+	if (inputFocus == NoneWin)
+	    return Success;
+
+	/* If the input focus is PointerRootWin, send the event to where
+	the pointer is if possible, then perhaps propogate up to root. */
+   	if (inputFocus == PointerRootWin)
+	    inputFocus = ROOT;
+
+	if (IsParent(inputFocus, sprite.win))
+	{
+	    effectiveFocus = inputFocus;
+	    pWin = sprite.win;
+	}
+	else
+	    effectiveFocus = pWin = inputFocus;
+    }
+    else
+	pWin = SecurityLookupWindow(stuff->destination, client,
+				    SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+    {
+	client->errorValue = stuff->propagate;
+	return BadValue;
+    }
+    stuff->event.u.u.type |= 0x80;
+    if (stuff->propagate)
+    {
+	for (;pWin; pWin = pWin->parent)
+	{
+	    if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				      NullGrab, 0))
+		return Success;
+	    if (pWin == effectiveFocus)
+		return Success;
+	    stuff->eventMask &= ~wDontPropagateMask(pWin);
+	    if (!stuff->eventMask)
+		break;
+	}
+    }
+    else
+	(void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				    NullGrab, 0);
+    return Success;
+}
+
+int
+ProcUngrabKey(client)
+    ClientPtr client;
+{
+    REQUEST(xUngrabKeyReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xUngrabKeyReq);
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = keybd;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = KeyPress;
+    tempGrab.detail.exact = stuff->key;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+int
+ProcGrabKey(client)
+    ClientPtr client;
+{
+    WindowPtr pWin;
+    REQUEST(xGrabKeyReq);
+    GrabPtr grab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xGrabKeyReq);
+    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return(BadValue);
+    }
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    grab = CreateGrab(client->index, keybd, pWin, 
+	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+	keybd, stuff->modifiers, KeyPress, stuff->key, 
+	NullWindow, NullCursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(client)
+    ClientPtr client;
+{
+    WindowPtr pWin, confineTo;
+    REQUEST(xGrabButtonReq);
+    CursorPtr cursor;
+    GrabPtr grab;
+
+    REQUEST_SIZE_MATCH(xGrabButtonReq);
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return BadValue;
+    }
+    if (stuff->eventMask & ~PointerGrabMask)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+       confineTo = NullWindow;
+    else {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+
+
+    grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
+    permitOldBugs ? (Mask)(stuff->eventMask |
+			       ButtonPressMask | ButtonReleaseMask) :
+			(Mask)stuff->eventMask,
+	(Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+	(Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+	ButtonPress, stuff->button, confineTo, cursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(client)
+    ClientPtr client;
+{
+    REQUEST(xUngrabButtonReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+
+    REQUEST_SIZE_MATCH(xUngrabButtonReq);
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = inputInfo.pointer;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = ButtonPress;
+    tempGrab.detail.exact = stuff->button;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(pWin, freeResources)
+    WindowPtr		pWin;
+    Bool		freeResources;
+{
+    WindowPtr		parent;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    FocusClassPtr	focus = keybd->focus;
+    OtherClientsPtr	oc;
+    GrabPtr		passive;
+
+
+    /* Deactivate any grabs performed on this window, before making any
+	input focus changes. */
+
+    if (mouse->grab &&
+	((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+	(*mouse->DeactivateGrab)(mouse);
+
+    /* Deactivating a keyboard grab should cause focus events. */
+
+    if (keybd->grab && (keybd->grab->window == pWin))
+	(*keybd->DeactivateGrab)(keybd);
+
+    /* If the focus window is a root window (ie. has no parent) then don't 
+	delete the focus from it. */
+    
+    if ((pWin == focus->win) && (pWin->parent != NullWindow))
+    {
+	int focusEventMode = NotifyNormal;
+
+ 	/* If a grab is in progress, then alter the mode of focus events. */
+
+	if (keybd->grab)
+	    focusEventMode = NotifyWhileGrabbed;
+
+	switch (focus->revert)
+	{
+	case RevertToNone:
+	    DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+	    focus->win = NoneWin;
+	    focus->traceGood = 0;
+	    break;
+	case RevertToParent:
+	    parent = pWin;
+	    do
+	    {
+		parent = parent->parent;
+		focus->traceGood--;
+	    } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+   during SaveSet processing would cause the focus to revert to the
+   nearest enclosing window which will survive the death of the exiting
+   client, instead of ending up reverting to a dying window and thence
+   to None
+ */
+#ifdef NOTDEF
+ 	      || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+		);
+	    DoFocusEvents(keybd, pWin, parent, focusEventMode);
+	    focus->win = parent;
+	    focus->revert = RevertToNone;
+	    break;
+	case RevertToPointerRoot:
+	    DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+	    focus->win = PointerRootWin;
+	    focus->traceGood = 0;
+	    break;
+	}
+    }
+
+    if (mouse->valuator->motionHintWindow == pWin)
+	mouse->valuator->motionHintWindow = NullWindow;
+
+    if (freeResources)
+    {
+	if (pWin->dontPropagate)
+	    DontPropagateRefCnts[pWin->dontPropagate]--;
+	while ( (oc = wOtherClients(pWin)) )
+	    FreeResource(oc->resource, RT_NONE);
+	while ( (passive = wPassiveGrabs(pWin)) )
+	    FreeResource(passive->resource, RT_NONE);
+     }
+#ifdef XINPUT
+    DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/* Call this whenever some window at or below pWin has changed geometry */
+
+/*ARGSUSED*/
+void
+CheckCursorConfinement(pWin)
+    WindowPtr pWin;
+{
+    GrabPtr grab = inputInfo.pointer->grab;
+    WindowPtr confineTo;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+    if (grab && (confineTo = grab->confineTo))
+    {
+	if (!BorderSizeNotEmpty(confineTo))
+	    (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+	else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+	    ConfineCursorToWindow(confineTo, TRUE, TRUE);
+    }
+}
+
+Mask
+EventMaskForClient(pWin, client)
+    WindowPtr		pWin;
+    ClientPtr		client;
+{
+    register OtherClientsPtr	other;
+
+    if (wClient (pWin) == client)
+	return pWin->eventMask;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (SameClient(other, client))
+	    return other->mask;
+    }
+    return 0;
+}
+
+int
+ProcRecolorCursor(client)
+    ClientPtr client;
+{
+    CursorPtr pCursor;
+    int		nscr;
+    ScreenPtr	pscr;
+    Bool 	displayed;
+    REQUEST(xRecolorCursorReq);
+
+    REQUEST_SIZE_MATCH(xRecolorCursorReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+					RT_CURSOR, SecurityWriteAccess);
+    if ( !pCursor) 
+    {
+	client->errorValue = stuff->cursor;
+	return (BadCursor);
+    }
+
+    pCursor->foreRed = stuff->foreRed;
+    pCursor->foreGreen = stuff->foreGreen;
+    pCursor->foreBlue = stuff->foreBlue;
+
+    pCursor->backRed = stuff->backRed;
+    pCursor->backGreen = stuff->backGreen;
+    pCursor->backBlue = stuff->backBlue;
+
+    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+    {
+	pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension)
+	    displayed = (pscr == sprite.screen);
+	else
+#endif
+	    displayed = (pscr == sprite.hotPhys.pScreen);
+	( *pscr->RecolorCursor)(pscr, pCursor,
+				(pCursor == sprite.current) && displayed);
+    }
+    return (Success);
+}
+
+void
+WriteEventsToClient(pClient, count, events)
+    ClientPtr	pClient;
+    int		count;
+    xEvent	*events;
+{
+#ifdef PANORAMIX
+    xEvent    eventCopy;
+#endif
+    xEvent    eventTo, *eventFrom;
+    int       i;
+
+#ifdef XKB
+    if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+	return;
+#endif
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && 
+       (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 
+    {
+	switch(events->u.u.type) {
+	case MotionNotify:
+	case ButtonPress:
+	case ButtonRelease:
+	case KeyPress:
+	case KeyRelease:
+	case EnterNotify:
+	case LeaveNotify:
+	/* 
+	   When multiple clients want the same event DeliverEventsToWindow
+	   passes the same event structure multiple times so we can't 
+	   modify the one passed to us 
+        */
+	    count = 1;  /* should always be 1 */
+	    memcpy(&eventCopy, events, sizeof(xEvent));
+	    eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+	    eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+	    if(eventCopy.u.keyButtonPointer.event == 
+	       eventCopy.u.keyButtonPointer.root) 
+	    {
+		eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+		eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+	    }
+	    events = &eventCopy;
+	    break;
+	default: break;
+	}
+    }
+#endif
+
+    if (EventCallback)
+    {
+	EventInfoRec eventinfo;
+	eventinfo.client = pClient;
+	eventinfo.events = events;
+	eventinfo.count = count;
+	CallCallbacks(&EventCallback, (pointer)&eventinfo);
+    }
+    if(pClient->swapped)
+    {
+	for(i = 0; i < count; i++)
+	{
+	    eventFrom = &events[i];
+	    /* Remember to strip off the leading bit of type in case
+	       this event was sent with "SendEvent." */
+	    (*EventSwapVector[eventFrom->u.u.type & 0177])
+		(eventFrom, &eventTo);
+	    (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+	}
+    }
+    else
+    {
+	(void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+    }
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
new file mode 100644
index 000000000..dd607e0ca
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
@@ -0,0 +1,4797 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXevents.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.46 2002/09/17 01:15:09 dawes Exp $ */
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/****************************************************************
+*                                                               *
+*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#include "Xlib.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include "XKBsrv.h"
+#if NeedFunctionPrototypes
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#else
+extern Bool XkbFilterEvents();
+#endif
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+
+#include "XIproto.h"
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "../../dix/dispatch.h"
+
+#include "NXlib.h"
+
+#include "Events.h"
+#include "Windows.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
+
+#define EXTENSION_EVENT_BASE  64
+
+#define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+	Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+	PointerMotionMask | Button1MotionMask | \
+	Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+	Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+	KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+	MotionMask )
+#define PointerGrabMask ( \
+	ButtonPressMask | ButtonReleaseMask | \
+	EnterWindowMask | LeaveWindowMask | \
+	PointerMotionHintMask | KeymapStateMask | \
+	MotionMask )
+#define AllModifiersMask ( \
+	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+	Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+			      (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+    QdEventPtr		pending, *pendtail;
+    DeviceIntPtr	replayDev;	/* kludgy rock to put flag for */
+    WindowPtr		replayWin;	/*   ComputeFreezes            */
+    Bool		playingEvents;
+    TimeStamp		time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+typedef struct {
+    int		x, y;
+    ScreenPtr	pScreen;
+} HotSpot;
+
+static  struct {
+    CursorPtr	current;
+    BoxRec	hotLimits;	/* logical constraints of hot spot */
+    Bool	confined;	/* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+    RegionPtr	hotShape;	/* additional logical shape constraint */
+#endif
+    BoxRec	physLimits;	/* physical constraints of hot spot */
+    WindowPtr	win;		/* window of logical position */
+    HotSpot	hot;		/* logical pointer position */
+    HotSpot	hotPhys;	/* physical pointer position */
+#ifdef PANORAMIX
+    ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
+    RegionRec   Reg1;	        /* Region 1 for confining motion */
+    RegionRec   Reg2;		/* Region 2 for confining virtual motion */
+    WindowPtr   windows[MAXSCREENS];
+    WindowPtr	confineWin;	/* confine window */ 
+#endif
+} sprite;			/* info about the cursor sprite */
+
+static void DoEnterLeaveEvents(
+#if NeedFunctionPrototypes
+    WindowPtr /*fromWin*/,
+    WindowPtr /*toWin*/,
+    int /*mode*/
+#endif
+);
+
+static WindowPtr XYToWindow(
+#if NeedFunctionPrototypes
+    int /*x*/,
+    int /*y*/
+#endif
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+	NoSuchEvent,		       /* 0 */
+	NoSuchEvent,		       /* 1 */
+	KeyPressMask,		       /* KeyPress */
+	KeyReleaseMask,		       /* KeyRelease */
+	ButtonPressMask,	       /* ButtonPress */
+	ButtonReleaseMask,	       /* ButtonRelease */
+	PointerMotionMask,	       /* MotionNotify (initial state) */
+	EnterWindowMask,	       /* EnterNotify */
+	LeaveWindowMask,	       /* LeaveNotify */
+	FocusChangeMask,	       /* FocusIn */
+	FocusChangeMask,	       /* FocusOut */
+	KeymapStateMask,	       /* KeymapNotify */
+	ExposureMask,		       /* Expose */
+	CantBeFiltered,		       /* GraphicsExpose */
+	CantBeFiltered,		       /* NoExpose */
+	VisibilityChangeMask,	       /* VisibilityNotify */
+	SubstructureNotifyMask,	       /* CreateNotify */
+	StructureAndSubMask,	       /* DestroyNotify */
+	StructureAndSubMask,	       /* UnmapNotify */
+	StructureAndSubMask,	       /* MapNotify */
+	SubstructureRedirectMask,      /* MapRequest */
+	StructureAndSubMask,	       /* ReparentNotify */
+	StructureAndSubMask,	       /* ConfigureNotify */
+	SubstructureRedirectMask,      /* ConfigureRequest */
+	StructureAndSubMask,	       /* GravityNotify */
+	ResizeRedirectMask,	       /* ResizeRequest */
+	StructureAndSubMask,	       /* CirculateNotify */
+	SubstructureRedirectMask,      /* CirculateRequest */
+	PropertyChangeMask,	       /* PropertyNotify */
+	CantBeFiltered,		       /* SelectionClear */
+	CantBeFiltered,		       /* SelectionRequest */
+	CantBeFiltered,		       /* SelectionNotify */
+	ColormapChangeMask,	       /* ColormapNotify */
+	CantBeFiltered,		       /* ClientMessage */
+	CantBeFiltered		       /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+    0x7c				/* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+    int x, 
+    int y, 
+    Bool generateEvent
+){
+    ScreenPtr pScreen;
+    BoxRec box;
+    int i;
+
+    /* x,y are in Screen 0 coordinates.  We need to decide what Screen
+       to send the message too and what the coordinates relative to 
+       that screen are. */
+
+    pScreen = sprite.screen;
+    x += panoramiXdataPtr[0].x;
+    y += panoramiXdataPtr[0].y;
+
+    if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+								x, y, &box)) 
+    {
+	FOR_NSCREENS(i) 
+	{
+	    if(i == pScreen->myNum) 
+		continue;
+	    if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+	    {
+		pScreen = screenInfo.screens[i];
+		break;
+	    }
+	}
+    }
+
+    sprite.screen = pScreen;
+    sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+    sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+    x -= panoramiXdataPtr[pScreen->myNum].x;
+    y -= panoramiXdataPtr[pScreen->myNum].y;
+
+    return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+    ScreenPtr pScreen = sprite.screen;
+    BoxRec newBox = sprite.physLimits;
+
+    /* Translate the constraining box to the screen
+       the sprite is actually on */
+    newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+    newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+    (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents
+){
+    HotSpot new;
+
+    if (!cursor)
+	return;
+ 
+    new = sprite.hotPhys;
+
+    /* I don't care what the DDX has to say about it */
+    sprite.physLimits = sprite.hotLimits;
+
+    /* constrain the pointer to those limits */
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+
+    if (sprite.hotShape)  /* more work if the shape is a mess */
+	ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+    if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	XineramaSetCursorPosition (new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+
+    /* Tell DDX what the limits are */
+    XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+    if(pWin == WindowTable[0]) {
+	    memcpy(sprite.windows, WindowTable, 
+				PanoramiXNumScreens*sizeof(WindowPtr));
+    } else {
+	PanoramiXRes *win;
+	int i;
+
+	win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+	if(!win)
+	    return FALSE;
+
+	for(i = 0; i < PanoramiXNumScreens; i++) {
+	   sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+	   if(!sprite.windows[i])  /* window is being unmapped */
+		return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+   QdEventPtr qe,
+   WindowPtr pWin
+){
+
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;  /* should always be Screen 0 */
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	int x, y, off_x, off_y, i;
+	BoxRec lims;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+        if (sprite.hot.x < lims.x1)
+            sprite.hot.x = lims.x1;
+        else if (sprite.hot.x >= lims.x2)
+            sprite.hot.x = lims.x2 - 1;
+        if (sprite.hot.y < lims.y1)
+            sprite.hot.y = lims.y1;
+        else if (sprite.hot.y >= lims.y2)
+            sprite.hot.y = lims.y2 - 1;
+
+	if (REGION_NUM_RECTS(&sprite.Reg2) > 1) 
+	    ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	/* Motion events entering DIX get translated to Screen 0
+	   coordinates.  Replayed events have already been 
+	   translated since they've entered DIX before */
+	XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			  panoramiXdataPtr[0].x;
+	XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			  panoramiXdataPtr[0].y;
+
+	sprite.hot.x = XE_KBPTR.rootX;
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+
+	if (sprite.hotShape) 
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    XineramaSetCursorPosition(
+			sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+    if (syncEvents.playingEvents)
+    {
+	XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	int x, y, off_x, off_y, i;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+	if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+	   sprite.hotShape = &sprite.Reg1;
+	else
+	   sprite.hotShape = NullRegion;
+	
+	sprite.confined = FALSE;
+	sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+	XineramaCheckPhysLimits(sprite.current, generateEvents);
+    }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    XineramaCheckPhysLimits(cursor, FALSE);
+    	(*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+	sprite.current = cursor;
+    }
+}
+
+
+#endif  /* PANORAMIX */
+
+void
+SetMaskForEvent(mask, event)
+    Mask mask;
+    int event;
+{
+    if ((event < LASTEvent) || (event >= 128))
+	FatalError("SetMaskForEvent: bogus event number");
+    filters[event] = mask;
+}
+
+void
+SetCriticalEvent(event)
+    int event;
+{
+    if (event >= 128)
+	FatalError("SetCriticalEvent: bogus event number");
+    criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+#if NeedFunctionPrototypes
+SyntheticMotion(int x, int y)
+#else
+SyntheticMotion(x, y)
+    int x, y;
+#endif
+{
+    xEvent xE;
+
+#ifdef PANORAMIX
+    /* Translate back to the sprite screen since processInputProc
+       will translate from sprite screen to screen 0 upon reentry
+       to the DIX layer */
+    if(!noPanoramiXExtension) {
+	x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+	y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+    }
+#endif
+    xE.u.keyButtonPointer.rootX = x;
+    xE.u.keyButtonPointer.rootY = y;
+    if (syncEvents.playingEvents)
+	xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+    else
+	xE.u.keyButtonPointer.time = currentTime.milliseconds;
+    xE.u.u.type = MotionNotify;
+    (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+#if NeedFunctionPrototypes
+ConfineToShape(RegionPtr shape, int *px, int *py)
+#else
+ConfineToShape(shape, px, py)
+    RegionPtr shape;
+    int *px, *py;
+#endif
+{
+    BoxRec box;
+    int x = *px, y = *py;
+    int incx = 1, incy = 1;
+
+    if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+	return;
+    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+    /* this is rather crude */
+    do {
+	x += incx;
+	if (x >= box.x2)
+	{
+	    incx = -1;
+	    x = *px - 1;
+	}
+	else if (x < box.x1)
+	{
+	    incx = 1;
+	    x = *px;
+	    y += incy;
+	    if (y >= box.y2)
+	    {
+		incy = -1;
+		y = *py - 1;
+	    }
+	    else if (y < box.y1)
+		return; /* should never get here! */
+	}
+    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+    *px = x;
+    *py = y;
+}
+#endif
+
+static void
+#if NeedFunctionPrototypes
+CheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents,
+    Bool confineToScreen,
+    ScreenPtr pScreen)
+#else
+CheckPhysLimits(cursor, generateEvents, confineToScreen, pScreen)
+    CursorPtr cursor;
+    Bool generateEvents;
+    Bool confineToScreen;
+    ScreenPtr pScreen;
+#endif
+{
+    HotSpot new;
+
+    if (!cursor)
+	return;
+    new = sprite.hotPhys;
+    if (pScreen)
+	new.pScreen = pScreen;
+    else
+	pScreen = new.pScreen;
+    (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+			      &sprite.physLimits);
+    sprite.confined = confineToScreen;
+    (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &new.x, &new.y); 
+#endif
+    if ((pScreen != sprite.hotPhys.pScreen) ||
+	(new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	if (pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys = new;
+	(*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+CheckVirtualMotion(
+    register QdEventPtr qe,
+    register WindowPtr pWin)
+#else
+CheckVirtualMotion(qe, pWin)
+    register QdEventPtr qe;
+    register WindowPtr pWin;
+#endif
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaCheckVirtualMotion(qe, pWin);
+	return;
+    }
+#endif
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	BoxRec lims;
+
+	if (sprite.hot.pScreen != pWin->drawable.pScreen)
+	{
+	    sprite.hot.pScreen = pWin->drawable.pScreen;
+	    sprite.hot.x = sprite.hot.y = 0;
+	}
+	lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+	if (sprite.hot.x < lims.x1)
+	    sprite.hot.x = lims.x1;
+	else if (sprite.hot.x >= lims.x2)
+	    sprite.hot.x = lims.x2 - 1;
+	if (sprite.hot.y < lims.y1)
+	    sprite.hot.y = lims.y1;
+	else if (sprite.hot.y >= lims.y2)
+	    sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+	if (wBoundingShape(pWin))
+	    ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaConfineCursorToWindow(pWin, generateEvents);
+	return;
+    }	
+#endif
+
+    if (syncEvents.playingEvents)
+    {
+	CheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+	sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+					       : NullRegion;
+#endif
+	CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+			pScreen);
+    }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+    return sprite.confined;
+}
+
+static void
+#if NeedFunctionPrototypes
+ChangeToCursor(CursorPtr cursor)
+#else
+ChangeToCursor(cursor)
+    CursorPtr cursor;
+#endif
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaChangeToCursor(cursor);
+	return;
+    }
+#endif
+
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    CheckPhysLimits(cursor, FALSE, sprite.confined,
+			    (ScreenPtr)NULL);
+	(*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+						  cursor);
+	sprite.current = cursor;
+    }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(a, b)
+    register WindowPtr a, b;
+{
+    for (b = b->parent; b; b = b->parent)
+	if (b == a) return TRUE;
+    return FALSE;
+}
+
+static void
+#if NeedFunctionPrototypes
+PostNewCursor(void)
+#else
+PostNewCursor()
+#endif
+{
+    register    WindowPtr win;
+    register    GrabPtr grab = inputInfo.pointer->grab;
+
+    if (syncEvents.playingEvents)
+	return;
+    if (grab)
+    {
+	if (grab->cursor)
+	{
+	    ChangeToCursor(grab->cursor);
+	    return;
+	}
+	if (IsParent(grab->window, sprite.win))
+	    win = sprite.win;
+	else
+	    win = grab->window;
+    }
+    else
+	win = sprite.win;
+    for (; win; win = win->parent)
+	if (win->optional && win->optional->cursor != NullCursor)
+	{
+	    ChangeToCursor(win->optional->cursor);
+	    return;
+	}
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+    return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+    return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+    return sprite.current;
+}
+
+void
+GetSpritePosition(px, py)
+    int *px, *py;
+{
+    *px = sprite.hotPhys.x;
+    *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+    if(!noPanoramiXExtension) {
+	return sprite.screen->myNum;
+    } else {
+	return 0;
+    }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+#if NeedFunctionPrototypes
+MonthChangedOrBadTime(register xEvent *xE)
+#else
+MonthChangedOrBadTime(xE)
+    register xEvent *xE;
+#endif
+{
+    /* If the ddx/OS is careless about not processing timestamped events from
+     * different sources in sorted order, then it's possible for time to go
+     * backwards when it should not.  Here we ensure a decent time.
+     */
+    if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+	currentTime.months++;
+    else
+	XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+    if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+	MonthChangedOrBadTime(xE); \
+    currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+    lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(xE)
+    register xEvent *xE;
+{
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE);
+}
+
+/**************************************************************************
+ *            The following procedures deal with synchronous events       *
+ **************************************************************************/
+
+void
+EnqueueEvent(xE, device, count)
+    xEvent		*xE;
+    DeviceIntPtr	device;
+    int			count;
+{
+    register QdEventPtr tail = *syncEvents.pendtail;
+    register QdEventPtr qe;
+    xEvent		*qxE;
+
+    NoticeTime(xE);
+    if (DeviceEventCallback)
+    {
+	DeviceEventInfoRec eventinfo;
+	/*  The RECORD spec says that the root window field of motion events
+	 *  must be valid.  At this point, it hasn't been filled in yet, so
+	 *  we do it here.  The long expression below is necessary to get
+	 *  the current root window; the apparently reasonable alternative
+	 *  GetCurrentRootWindow()->drawable.id doesn't give you the right
+	 *  answer on the first motion event after a screen change because
+	 *  the data that GetCurrentRootWindow relies on hasn't been
+	 *  updated yet.
+	 */
+	if (xE->u.u.type == MotionNotify)
+	    XE_KBPTR.root =
+		WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	eventinfo.events = xE;
+	eventinfo.count = count;
+	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+    }
+    if (xE->u.u.type == MotionNotify)
+    {
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension) {
+	    XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			      panoramiXdataPtr[0].x;
+	    XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			      panoramiXdataPtr[0].y;
+	}
+#endif
+	sprite.hotPhys.x = XE_KBPTR.rootX;
+	sprite.hotPhys.y = XE_KBPTR.rootY;
+	/* do motion compression */
+	if (tail &&
+	    (tail->event->u.u.type == MotionNotify) &&
+	    (tail->pScreen == sprite.hotPhys.pScreen))
+	{
+	    tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+	    tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+	    tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+	    tail->months = currentTime.months;
+	    return;
+	}
+    }
+    qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+    if (!qe)
+	return;
+    qe->next = (QdEventPtr)NULL;
+    qe->device = device;
+    qe->pScreen = sprite.hotPhys.pScreen;
+    qe->months = currentTime.months;
+    qe->event = (xEvent *)(qe + 1);
+    qe->evcount = count;
+    for (qxE = qe->event; --count >= 0; qxE++, xE++)
+	*qxE = *xE;
+    if (tail)
+	syncEvents.pendtail = &tail->next;
+    *syncEvents.pendtail = qe;
+}
+
+static void
+#if NeedFunctionPrototypes
+PlayReleasedEvents(void)
+#else
+PlayReleasedEvents()
+#endif
+{
+    register QdEventPtr *prev, qe;
+    register DeviceIntPtr dev;
+
+    prev = &syncEvents.pending;
+    while ( (qe = *prev) )
+    {
+	if (!qe->device->sync.frozen)
+	{
+	    *prev = qe->next;
+	    if (*syncEvents.pendtail == *prev)
+		syncEvents.pendtail = prev;
+	    if (qe->event->u.u.type == MotionNotify)
+		CheckVirtualMotion(qe, NullWindow);
+	    syncEvents.time.months = qe->months;
+	    syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+	   /* Translate back to the sprite screen since processInputProc
+	      will translate from sprite screen to screen 0 upon reentry
+	      to the DIX layer */
+	    if(!noPanoramiXExtension) {
+		qe->event->u.keyButtonPointer.rootX += 
+			panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x;
+		qe->event->u.keyButtonPointer.rootY += 
+			panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y;
+	    }
+#endif
+	    (*qe->device->public.processInputProc)(qe->event, qe->device,
+						   qe->evcount);
+	    xfree(qe);
+	    for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+		;
+	    if (!dev)
+		break;
+	    /* Playing the event may have unfrozen another device. */
+	    /* So to play it safe, restart at the head of the queue */
+	    prev = &syncEvents.pending;
+	}
+	else
+	    prev = &qe->next;
+    } 
+}
+
+static void
+#if NeedFunctionPrototypes
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+#else
+FreezeThaw(dev, frozen)
+    register DeviceIntPtr dev;
+    Bool frozen;
+#endif
+{
+    dev->sync.frozen = frozen;
+    if (frozen)
+	dev->public.processInputProc = dev->public.enqueueInputProc;
+    else
+	dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+    register DeviceIntPtr replayDev = syncEvents.replayDev;
+    register int i;
+    WindowPtr w;
+    register xEvent *xE;
+    int count;
+    GrabPtr grab;
+    register DeviceIntPtr dev;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+	FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+    if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+	return;
+    syncEvents.playingEvents = TRUE;
+    if (replayDev)
+    {
+	xE = replayDev->sync.event;
+	count = replayDev->sync.evcount;
+	syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+	for (i = 0; i < spriteTraceGood; i++)
+	{
+	    if (syncEvents.replayWin == spriteTrace[i])
+	    {
+		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+		    if (replayDev->focus)
+			DeliverFocusedEvent(replayDev, xE, w, count);
+		    else
+			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+					        replayDev, count);
+		}
+		goto playmore;
+	    }
+	}
+	/* must not still be in the same stack */
+	if (replayDev->focus)
+	    DeliverFocusedEvent(replayDev, xE, w, count);
+	else
+	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+    }
+playmore:
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (!dev->sync.frozen)
+	{
+	    PlayReleasedEvents();
+	    break;
+	}
+    }
+    syncEvents.playingEvents = FALSE;
+    /* the following may have been skipped during replay, so do it now */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+    PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+    GrabPtr grab;
+
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(thisDev, thisMode, otherMode)
+    register DeviceIntPtr thisDev;
+    Bool thisMode, otherMode;
+{
+    register GrabPtr grab = thisDev->grab;
+    register DeviceIntPtr dev;
+
+    if (thisMode == GrabModeSync)
+	thisDev->sync.state = FROZEN_NO_EVENT;
+    else
+    {	/* free both if same client owns both */
+	thisDev->sync.state = THAWED;
+	if (thisDev->sync.other &&
+	    (CLIENT_BITS(thisDev->sync.other->resource) ==
+	     CLIENT_BITS(grab->resource)))
+	    thisDev->sync.other = NullGrab;
+    }
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev != thisDev)
+	{
+	    if (otherMode == GrabModeSync)
+		dev->sync.other = grab;
+	    else
+	    {	/* free both if same client owns both */
+		if (dev->sync.other &&
+		    (CLIENT_BITS(dev->sync.other->resource) ==
+		     CLIENT_BITS(grab->resource)))
+		    dev->sync.other = NullGrab;
+	    }
+	}
+    }
+    ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(mouse, grab, time, autoGrab)
+    register GrabPtr grab;
+    register DeviceIntPtr mouse;
+    TimeStamp time;
+    Bool autoGrab;
+{
+    WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+				     : sprite.win;
+
+    if (grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+    }
+    DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+    mouse->valuator->motionHintWindow = NullWindow;
+    if (syncEvents.playingEvents)
+	mouse->grabTime = syncEvents.time;
+    else
+	mouse->grabTime = time;
+    if (grab->cursor)
+	grab->cursor->refcnt++;
+    mouse->activeGrab = *grab;
+    mouse->grab = &mouse->activeGrab;
+    mouse->fromPassiveGrab = autoGrab;
+    PostNewCursor();
+    CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * If grab is synchronous, events are delivered to clients only if they send
+     * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the 
+     * delivered event is saved in a queue and replayed later, when grab is released.
+     * We should  export sync grab to X as async in order to avoid events to be 
+     * queued twice, in the agent and in the X server. This solution have a drawback:
+     * replayed events are not delivered to that application that are not clients of
+     * the agent.
+     * A different solution could be to make the grab asynchronous in the agent and 
+     * to export it as synchronous. But this seems to be less safe.
+     *
+     * To make internal grab asynchronous, change previous line as follows.
+     *
+     * if (nxagentOption(Rootless))
+     * {
+     *   CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
+     * }
+     * else
+     * {
+     *   CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+     * }
+     */
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      /*
+       * FIXME: We should use the correct value
+       * for the cursor. Temporarily we set it
+       * to None.
+       */
+
+       int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+                                                 nxagentCollectGrabPointerPredicate);
+
+       NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
+                                1, grab -> eventMask & PointerGrabMask,
+                                    GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
+                                        nxagentWindow(grab -> confineTo) : None,
+                                            None, CurrentTime);
+    }
+
+    #endif
+}
+
+void
+DeactivatePointerGrab(mouse)
+    register DeviceIntPtr mouse;
+{
+    register GrabPtr grab = mouse->grab;
+    register DeviceIntPtr dev;
+
+    mouse->valuator->motionHintWindow = NullWindow;
+    mouse->grab = NullGrab;
+    mouse->sync.state = NOT_GRABBED;
+    mouse->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+    if (grab->confineTo)
+	ConfineCursorToWindow(ROOT, FALSE, FALSE);
+    PostNewCursor();
+    if (grab->cursor)
+	FreeCursor(grab->cursor, (Cursor)0);
+    ComputeFreezes();
+
+    #ifdef NXAGENT_SERVER
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      XUngrabPointer(nxagentDisplay, CurrentTime);
+
+      if (sprite.win == ROOT)
+      {
+        mouse -> button -> state &=
+            ~(Button1Mask | Button2Mask | Button3Mask |
+                  Button4Mask | Button5Mask);
+      }
+    }
+
+    #endif
+}
+
+void
+ActivateKeyboardGrab(keybd, grab, time, passive)
+    register DeviceIntPtr keybd;
+    GrabPtr grab;
+    TimeStamp time;
+    Bool passive;
+{
+    WindowPtr oldWin;
+
+    if (keybd->grab)
+	oldWin = keybd->grab->window;
+    else if (keybd->focus)
+	oldWin = keybd->focus->win;
+    else
+	oldWin = sprite.win;
+    if (oldWin == FollowKeyboardWin)
+	oldWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+    if (syncEvents.playingEvents)
+	keybd->grabTime = syncEvents.time;
+    else
+	keybd->grabTime = time;
+    keybd->activeGrab = *grab;
+    keybd->grab = &keybd->activeGrab;
+    keybd->fromPassiveGrab = passive;
+    CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(keybd)
+    register DeviceIntPtr keybd;
+{
+    register GrabPtr grab = keybd->grab;
+    register DeviceIntPtr dev;
+    register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+					       : sprite.win;
+
+    if (focusWin == FollowKeyboardWin)
+	focusWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    keybd->grab = NullGrab;
+    keybd->sync.state = NOT_GRABBED;
+    keybd->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+    ComputeFreezes();
+}
+
+void
+AllowSome(client, time, thisDev, newState)
+    ClientPtr		client;
+    TimeStamp		time;
+    register DeviceIntPtr thisDev;
+    int			newState;
+{
+    Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+    TimeStamp grabTime;
+    register DeviceIntPtr dev;
+
+    thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+    thisSynced = FALSE;
+    otherGrabbed = FALSE;
+    othersFrozen = TRUE;
+    grabTime = thisDev->grabTime;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev == thisDev)
+	    continue;
+	if (dev->grab && SameClient(dev->grab, client))
+	{
+	    if (!(thisGrabbed || otherGrabbed) ||
+		(CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+		grabTime = dev->grabTime;
+	    otherGrabbed = TRUE;
+	    if (thisDev->sync.other == dev->grab)
+		thisSynced = TRUE;
+	    if (dev->sync.state < FROZEN)
+		othersFrozen = FALSE;
+	}
+	else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+	    othersFrozen = FALSE;
+    }
+    if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+	return;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, grabTime) == EARLIER))
+	return;
+    switch (newState)
+    {
+	case THAWED:	 	       /* Async */
+	    if (thisGrabbed)
+		thisDev->sync.state = THAWED;
+	    if (thisSynced)
+		thisDev->sync.other = NullGrab;
+	    ComputeFreezes();
+	    break;
+	case FREEZE_NEXT_EVENT:		/* Sync */
+	    if (thisGrabbed)
+	    {
+		thisDev->sync.state = FREEZE_NEXT_EVENT;
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		ComputeFreezes();
+	    }
+	    break;
+	case THAWED_BOTH:		/* AsyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case FREEZE_BOTH_NEXT_EVENT:	/* SyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case NOT_GRABBED:		/* Replay */
+	    if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+	    {
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		syncEvents.replayDev = thisDev;
+		syncEvents.replayWin = thisDev->grab->window;
+		(*thisDev->DeactivateGrab)(thisDev);
+		syncEvents.replayDev = (DeviceIntPtr)NULL;
+	    }
+	    break;
+	case THAW_OTHERS:		/* AsyncOthers */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev == thisDev)
+			continue;
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+    }
+}
+
+int
+ProcAllowEvents(client)
+    register ClientPtr client;
+{
+    TimeStamp		time;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    REQUEST(xAllowEventsReq);
+
+    REQUEST_SIZE_MATCH(xAllowEventsReq);
+    time = ClientTimeToServerTime(stuff->time);
+    switch (stuff->mode)
+    {
+	case ReplayPointer:
+	    AllowSome(client, time, mouse, NOT_GRABBED);
+	    break;
+	case SyncPointer: 
+	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncPointer: 
+	    AllowSome(client, time, mouse, THAWED);
+	    break;
+	case ReplayKeyboard: 
+	    AllowSome(client, time, keybd, NOT_GRABBED);
+	    break;
+	case SyncKeyboard: 
+	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncKeyboard: 
+	    AllowSome(client, time, keybd, THAWED);
+	    break;
+	case SyncBoth:
+	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+	    break;
+	case AsyncBoth:
+	    AllowSome(client, time, keybd, THAWED_BOTH);
+	    break;
+	default: 
+	    client->errorValue = stuff->mode;
+	    return BadValue;
+    }
+
+    /*
+     * This is not necessary if we export grab to X as asynchronous.
+     *
+     * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
+     *         stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
+     * {
+     *   XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
+     * }
+     */
+
+    return Success;
+}
+
+void
+ReleaseActiveGrabs(client)
+    ClientPtr client;
+{
+    register DeviceIntPtr dev;
+    Bool    done;
+
+    /* XXX CloseDownClient should remove passive grabs before
+     * releasing active grabs.
+     */
+    do {
+    	done = TRUE;
+    	for (dev = inputInfo.devices; dev; dev = dev->next)
+    	{
+	    if (dev->grab && SameClient(dev->grab, client))
+	    {
+	    	(*dev->DeactivateGrab)(dev);
+	    	done = FALSE;
+	    }
+    	}
+    } while (!done);
+}
+
+/**************************************************************************
+ *            The following procedures deal with delivering events        *
+ **************************************************************************/
+
+int
+TryClientEvents (client, pEvents, count, mask, filter, grab)
+    ClientPtr client;
+    GrabPtr grab;
+    xEvent *pEvents;
+    int count;
+    Mask mask, filter;
+{
+    int i;
+    int type;
+
+#ifdef DEBUG
+    if (debug_events) ErrorF(
+	"Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+	((filter == CantBeFiltered) || (mask & filter)))
+    {
+	if (grab && !SameClient(grab, client))
+	    return -1; /* don't send, but notify caller */
+	type = pEvents->u.u.type;
+	if (type == MotionNotify)
+	{
+	    if (mask & PointerMotionHintMask)
+	    {
+		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+		    pEvents->u.keyButtonPointer.event)
+		{
+#ifdef DEBUG
+		    if (debug_events) ErrorF("\n");
+	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+		    return 1; /* don't send, but pretend we did */
+		}
+		pEvents->u.u.detail = NotifyHint;
+	    }
+	    else
+	    {
+		pEvents->u.u.detail = NotifyNormal;
+	    }
+	}
+#ifdef XINPUT
+	else
+	{
+	    if ((type == DeviceMotionNotify) &&
+		MaybeSendDeviceMotionNotifyHint
+			((deviceKeyButtonPointer*)pEvents, mask) != 0)
+		return 1;
+	}
+#endif
+	type &= 0177;
+	if (type != KeymapNotify)
+	{
+	    /* all extension events must have a sequence number */
+	    for (i = 0; i < count; i++)
+		pEvents[i].u.u.sequenceNumber = client->sequence;
+	}
+
+	if (BitIsOn(criticalEvents, type))
+	{
+#ifdef SMART_SCHEDULE
+	    if (client->smart_priority < SMART_MAX_PRIORITY)
+		client->smart_priority++;
+#endif
+	    SetCriticalOutputPending();
+	}
+
+	WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+	if (debug_events) ErrorF(  " delivered\n");
+#endif
+	return 1;
+    }
+    else
+    {
+#ifdef DEBUG
+	if (debug_events) ErrorF("\n");
+#endif
+	return 0;
+    }
+}
+
+int
+DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
+    register WindowPtr pWin;
+    GrabPtr grab;
+    xEvent *pEvents;
+    int count;
+    Mask filter;
+    int mskidx;
+{
+    int deliveries = 0, nondeliveries = 0;
+    int attempt;
+    register InputClients *other;
+    ClientPtr client = NullClient;
+    Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+		              this mask is the mask of the grab. */
+    int type = pEvents->u.u.type;
+
+    /* CantBeFiltered means only window owner gets the event */
+    if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+    {
+	/* if nobody ever wants to see this event, skip some work */
+	if (filter != CantBeFiltered &&
+	    !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+	    return 0;
+	if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+				      pWin->eventMask, filter, grab)) )
+	{
+	    if (attempt > 0)
+	    {
+		deliveries++;
+		client = wClient(pWin);
+		deliveryMask = pWin->eventMask;
+	    } else
+		nondeliveries--;
+	}
+    }
+    if (filter != CantBeFiltered)
+    {
+	if (type & EXTENSION_EVENT_BASE)
+	{
+	    OtherInputMasks *inputMasks;
+
+	    inputMasks = wOtherInputMasks(pWin);
+	    if (!inputMasks ||
+		!(inputMasks->inputEvents[mskidx] & filter))
+		return 0;
+	    other = inputMasks->inputClients;
+	}
+	else
+	    other = (InputClients *)wOtherClients(pWin);
+	for (; other; other = other->next)
+	{
+	    if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+					  other->mask[mskidx], filter, grab)) )
+	    {
+		if (attempt > 0)
+		{
+		    deliveries++;
+		    client = rClient(other);
+		    deliveryMask = other->mask[mskidx];
+		} else
+		    nondeliveries--;
+	    }
+	}
+    }
+    if ((type == ButtonPress) && deliveries && (!grab))
+    {
+	GrabRec tempGrab;
+
+	tempGrab.device = inputInfo.pointer;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.window = pWin;
+	tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+	tempGrab.eventMask = deliveryMask;
+	tempGrab.keyboardMode = GrabModeAsync;
+	tempGrab.pointerMode = GrabModeAsync;
+	tempGrab.confineTo = NullWindow;
+	tempGrab.cursor = NullCursor;
+	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+					   currentTime, TRUE);
+    }
+    else if ((type == MotionNotify) && deliveries)
+	inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+    else
+    {
+	if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
+	    deliveries)
+	    CheckDeviceGrabAndHintWindow (pWin, type,
+					  (deviceKeyButtonPointer*) pEvents,
+					  grab, client, deliveryMask);
+    }
+#endif
+    if (deliveries)
+	return deliveries;
+    return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0.  if
+   send works,  return 1 or if send didn't work, return 2.
+   Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int 
+XineramaTryClientEventsResult(
+    ClientPtr client,
+    GrabPtr grab,
+    Mask mask, 
+    Mask filter
+){
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+        ((filter == CantBeFiltered) || (mask & filter)))
+    {
+        if (grab && !SameClient(grab, client)) return -1;
+	else return 1;
+    }
+    return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
+    register WindowPtr pWin;
+    xEvent *pEvents;
+    int count;
+    Mask filter;
+    ClientPtr dontClient;
+{
+    register OtherClients *other;
+
+
+    if (pWin->eventMask & filter)
+    {
+        if (wClient(pWin) == dontClient)
+	    return 0;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	    return XineramaTryClientEventsResult(
+			wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+	return TryClientEvents(wClient(pWin), pEvents, count,
+			       pWin->eventMask, filter, NullGrab);
+    }
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->mask & filter)
+	{
+            if (SameClient(other, dontClient))
+		return 0;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	      return XineramaTryClientEventsResult(
+			rClient(other), NullGrab, other->mask, filter);
+#endif
+	    return TryClientEvents(rClient(other), pEvents, count,
+				   other->mask, filter, NullGrab);
+	}
+    }
+    return 2;
+}
+
+static void
+#if NeedFunctionPrototypes
+FixUpEventFromWindow(
+    xEvent *xE,
+    WindowPtr pWin,
+    Window child,
+    Bool calcChild)
+#else
+FixUpEventFromWindow(xE, pWin, child, calcChild)
+    xEvent *xE;
+    WindowPtr pWin;
+    Window child;
+    Bool calcChild;
+#endif
+{
+    if (calcChild)
+    {
+        WindowPtr w=spriteTrace[spriteTraceGood-1];
+	/* If the search ends up past the root should the child field be 
+	 	set to none or should the value in the argument be passed 
+		through. It probably doesn't matter since everyone calls 
+		this function with child == None anyway. */
+
+        while (w) 
+        {
+            /* If the source window is same as event window, child should be
+		none.  Don't bother going all all the way back to the root. */
+
+ 	    if (w == pWin)
+	    { 
+   		child = None;
+ 		break;
+	    }
+	    
+	    if (w->parent == pWin)
+	    {
+		child = w->drawable.id;
+		break;
+            }
+ 	    w = w->parent;
+        } 	    
+    }
+    XE_KBPTR.root = ROOT->drawable.id;
+    XE_KBPTR.event = pWin->drawable.id;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	XE_KBPTR.sameScreen = xTrue;
+	XE_KBPTR.child = child;
+	XE_KBPTR.eventX =
+	XE_KBPTR.rootX - pWin->drawable.x;
+	XE_KBPTR.eventY =
+	XE_KBPTR.rootY - pWin->drawable.y;
+    }
+    else
+    {
+	XE_KBPTR.sameScreen = xFalse;
+	XE_KBPTR.child = None;
+	XE_KBPTR.eventX = 0;
+	XE_KBPTR.eventY = 0;
+    }
+}
+
+int
+DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
+    register WindowPtr pWin, stopAt;
+    register xEvent *xE;
+    GrabPtr grab;
+    DeviceIntPtr dev;
+    int count;
+{
+    Window child = None;
+    int type = xE->u.u.type;
+    Mask filter = filters[type];
+    int deliveries = 0;
+
+    if (type & EXTENSION_EVENT_BASE)
+    {
+	register OtherInputMasks *inputMasks;
+	int mskidx = dev->id;
+
+	inputMasks = wOtherInputMasks(pWin);
+	if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+	    return 0;
+	while (pWin)
+	{
+	    if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, mskidx);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(inputMasks &&
+		 (filter & inputMasks->dontPropagateMask[mskidx])))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	    if (pWin)
+		inputMasks = wOtherInputMasks(pWin);
+	}
+    }
+    else
+    {
+	if (!(filter & pWin->deliverableEvents))
+	    return 0;
+	while (pWin)
+	{
+	    if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, 0);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(filter & wDontPropagateMask(pWin)))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	}
+    }
+    return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(pWin, xE, count, otherParent)
+    register WindowPtr pWin, otherParent;
+    register xEvent *xE;
+    int count;
+{
+    Mask filter;
+    int     deliveries;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+	return count;
+#endif
+
+    if (!count)
+	return 0;
+    filter = filters[xE->u.u.type];
+    if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+	xE->u.destroyNotify.event = pWin->drawable.id;
+    if (filter != StructureAndSubMask)
+	return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+    deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+				       NullGrab, 0);
+    if (pWin->parent)
+    {
+	xE->u.destroyNotify.event = pWin->parent->drawable.id;
+	deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+					    SubstructureNotifyMask, NullGrab,
+					    0);
+	if (xE->u.u.type == ReparentNotify)
+	{
+	    xE->u.destroyNotify.event = otherParent->drawable.id;
+	    deliveries += DeliverEventsToWindow(otherParent, xE, count,
+						SubstructureNotifyMask,
+						NullGrab, 0);
+	}
+    }
+    return deliveries;
+}
+
+
+static Bool 
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+	return TRUE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	   if(POINT_IN_REGION(sprite.screen, 
+			&sprite.windows[i]->borderSize, 
+			x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, 
+			y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, 
+			&box))
+		return TRUE;
+	}
+    }
+#endif
+    return FALSE;
+}
+
+static WindowPtr 
+#if NeedFunctionPrototypes
+XYToWindow(int x, int y)
+#else
+XYToWindow(x, y)
+	int x, y;
+#endif
+{
+    register WindowPtr  pWin;
+
+    spriteTraceGood = 1;	/* root window still there */
+
+    if (nxagentOption(Rootless))
+    {
+      if (nxagentLastEnteredWindow == NULL)
+      {
+        return ROOT;
+      }
+
+      pWin = ROOT->lastChild;
+
+      while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
+      {
+        pWin = pWin->prevSib;
+      }
+    }
+    else
+    {
+      pWin = ROOT->firstChild;
+    }
+
+    while (pWin)
+    {
+	if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		    wBorderWidth(pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		    wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+#endif
+		)
+	{
+	    if (spriteTraceGood >= spriteTraceSize)
+	    {
+		spriteTraceSize += 10;
+		Must_have_memory = TRUE; /* XXX */
+		spriteTrace = (WindowPtr *)xrealloc(
+		    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    spriteTrace[spriteTraceGood++] = pWin;
+	    pWin = pWin->firstChild;
+	}
+	else
+	    pWin = pWin->nextSib;
+    }
+    return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+#if NeedFunctionPrototypes
+CheckMotion(xEvent *xE)
+#else
+CheckMotion(xE)
+    xEvent *xE;
+#endif
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaCheckMotion(xE);
+#endif
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+	{
+	    sprite.hot.pScreen = sprite.hotPhys.pScreen;
+	    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+	}
+	sprite.hot.x = XE_KBPTR.rootX;
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+	sprite.hotPhys = sprite.hot;
+
+        /*
+         * This code force cursor position to be inside the
+         * root window of the agent. We can't view a reason
+         * to do this and it interacts in an undesirable way
+         * with toggling fullscreen.
+         *
+         * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+         *          (sprite.hotPhys.y != XE_KBPTR.rootY))
+         * {
+         *   (*sprite.hotPhys.pScreen->SetCursorPosition)(
+         *       sprite.hotPhys.pScreen,
+         *           sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+         * }
+         */
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+    if (!(sprite.win->deliverableEvents &
+	  Motion_Filter(inputInfo.pointer->button))
+	!syncEvents.playingEvents)
+    {
+	/* XXX Do PointerNonInterestBox here */
+    }
+#endif
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+    (void) CheckMotion((xEvent *)NULL);
+}
+
+void
+DefineInitialRootWindow(win)
+    register WindowPtr win;
+{
+    register ScreenPtr pScreen = win->drawable.pScreen;
+    extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+    extern int nxagentShadowInit(ScreenPtr, WindowPtr);
+
+    sprite.hotPhys.pScreen = pScreen;
+    sprite.hotPhys.x = pScreen->width / 2;
+    sprite.hotPhys.y = pScreen->height / 2;
+    sprite.hot = sprite.hotPhys;
+    sprite.hotLimits.x2 = pScreen->width;
+    sprite.hotLimits.y2 = pScreen->height;
+    sprite.win = win;
+    sprite.current = wCursor (win);
+    spriteTraceGood = 1;
+    ROOT = win;
+    (*pScreen->CursorLimits) (
+	pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+    sprite.confined = FALSE;
+    (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+    (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+    (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+	sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+	sprite.hotLimits.x2 = PanoramiXPixWidth  - panoramiXdataPtr[0].x;
+	sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+	sprite.physLimits = sprite.hotLimits;
+	sprite.confineWin = NullWindow;
+	sprite.screen = pScreen;
+	/* gotta UNINIT these someplace */
+	REGION_INIT(pScreen, &sprite.Reg1, NullBox, 1);
+	REGION_INIT(pScreen, &sprite.Reg2, NullBox, 1);
+    }
+#endif
+
+    nxagentInitViewportFrame(pScreen, win);
+
+    if (nxagentOption(Shadow))
+    {
+      if (nxagentShadowInit(pScreen, win) == -1)
+      {
+        GiveUp(0);
+      }
+    }
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+/*ARGSUSED*/
+void
+WindowHasNewCursor(pWin)
+    WindowPtr pWin;
+{
+    PostNewCursor();
+}
+
+void
+NewCurrentScreen(newScreen, x, y)
+    ScreenPtr newScreen;
+    int x,y;
+{
+    sprite.hotPhys.x = x;
+    sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - 
+			    panoramiXdataPtr[0].x;
+	sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - 
+			    panoramiXdataPtr[0].y;
+	if (newScreen != sprite.screen) {
+	    sprite.screen = newScreen;
+	    /* Make sure we tell the DDX to update its copy of the screen */
+	    if(sprite.confineWin)
+		XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+	    else
+		XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+	    /* if the pointer wasn't confined, the DDX won't get 
+	       told of the pointer warp so we reposition it here */
+	    if(!syncEvents.playingEvents)
+		(*sprite.screen->SetCursorPosition)(sprite.screen,
+		    sprite.hotPhys.x + panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x,
+		    sprite.hotPhys.y + panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+	}
+    } else 
+#endif
+    if (newScreen != sprite.hotPhys.pScreen)
+	ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+    WindowPtr pWin,
+    int x,
+    int y
+)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    BoxRec box;
+    int i, xoff, yoff;
+
+    if (!pWin->realized) return FALSE;
+
+    if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+        return TRUE;
+    
+    if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+    xoff = x + panoramiXdataPtr[0].x;  
+    yoff = y + panoramiXdataPtr[0].y;  
+
+    for(i = 1; i < PanoramiXNumScreens; i++) {
+	pWin = sprite.windows[i];
+	pScreen = pWin->drawable.pScreen;
+	x = xoff - panoramiXdataPtr[i].x;
+	y = yoff - panoramiXdataPtr[i].y;
+
+	if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+            return TRUE;
+
+    }
+
+    return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+
+    REQUEST(xWarpPointerReq);
+
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if(source == WindowTable[0]) {
+	    winX -= panoramiXdataPtr[0].x;
+	    winY -= panoramiXdataPtr[0].y;
+	}
+	if (x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !XineramaPointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	if(dest == WindowTable[0]) {
+	    x -= panoramiXdataPtr[0].x;
+	    y -= panoramiXdataPtr[0].y;
+	}
+    } 
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < sprite.physLimits.x1)
+	x = sprite.physLimits.x1;
+    else if (x >= sprite.physLimits.x2)
+	x = sprite.physLimits.x2 - 1;
+    if (y < sprite.physLimits.y1)
+	y = sprite.physLimits.y1;
+    else if (y >= sprite.physLimits.y2)
+	y = sprite.physLimits.y2 - 1;
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &x, &y);
+
+    XineramaSetCursorPosition(x, y, TRUE);
+
+    return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(client)
+    ClientPtr client;
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+    ScreenPtr	newScreen;
+
+    REQUEST(xWarpPointerReq);
+
+    REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaWarpPointer(client);
+#endif
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+	    x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !PointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) 
+    {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	newScreen = dest->drawable.pScreen;
+    } else 
+	newScreen = sprite.hotPhys.pScreen;
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < 0)
+	x = 0;
+    else if (x >= newScreen->width)
+	x = newScreen->width - 1;
+    if (y < 0)
+	y = 0;
+    else if (y >= newScreen->height)
+	y = newScreen->height - 1;
+
+    if (newScreen == sprite.hotPhys.pScreen)
+    {
+	if (x < sprite.physLimits.x1)
+	    x = sprite.physLimits.x1;
+	else if (x >= sprite.physLimits.x2)
+	    x = sprite.physLimits.x2 - 1;
+	if (y < sprite.physLimits.y1)
+	    y = sprite.physLimits.y1;
+	else if (y >= sprite.physLimits.y2)
+	    y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+	(*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+    }
+    else if (!PointerConfinedToScreen())
+    {
+	NewCurrentScreen(newScreen, x, y);
+    }
+    return Success;
+}
+
+static Bool 
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+     if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+	return TRUE;
+
+#ifdef PANORAMIX
+     if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	    if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+		return TRUE;
+	}
+     }
+#endif
+     return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+	passive grab set on the window to be activated. */
+
+static Bool
+#if NeedFunctionPrototypes
+CheckPassiveGrabsOnWindow(
+    WindowPtr pWin,
+    register DeviceIntPtr device,
+    register xEvent *xE,
+    int count)
+#else
+CheckPassiveGrabsOnWindow(pWin, device, xE, count)
+    WindowPtr pWin;
+    register DeviceIntPtr device;
+    register xEvent *xE;
+    int count;
+#endif
+{
+    register GrabPtr grab = wPassiveGrabs(pWin);
+    GrabRec tempGrab;
+    register xEvent *dxE;
+
+    if (!grab)
+	return FALSE;
+    tempGrab.window = pWin;
+    tempGrab.device = device;
+    tempGrab.type = xE->u.u.type;
+    tempGrab.detail.exact = xE->u.u.detail;
+    tempGrab.detail.pMask = NULL;
+    tempGrab.modifiersDetail.pMask = NULL;
+    for (; grab; grab = grab->next)
+    {
+#ifdef XKB
+	DeviceIntPtr	gdev;
+	XkbSrvInfoPtr	xkbi;
+
+	gdev= grab->modifierDevice;
+	xkbi= gdev->key->xkbInfo;
+#endif
+	tempGrab.modifierDevice = grab->modifierDevice;
+	if (device == grab->modifierDevice &&
+	    (xE->u.u.type == KeyPress
+#ifdef XINPUT
+	     || xE->u.u.type == DeviceKeyPress
+#endif
+	     ))
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->prev_state;
+#endif
+	else
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->state;
+#endif
+	if (GrabMatchesSecond(&tempGrab, grab) &&
+	    (!grab->confineTo ||
+	     (grab->confineTo->realized && 
+				BorderSizeNotEmpty(grab->confineTo))))
+	{
+#ifdef XCSECURITY
+	    if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+		return FALSE;
+#endif
+#ifdef XKB
+	    if (!noXkbExtension) {
+		XE_KBPTR.state &= 0x1f00;
+		XE_KBPTR.state |=
+				tempGrab.modifiersDetail.exact&(~0x1f00);
+	    }
+#endif
+	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+ 
+	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+	    (void) TryClientEvents(rClient(grab), xE, count,
+				   filters[xE->u.u.type],
+				   filters[xE->u.u.type],  grab);
+
+	    if (device->sync.state == FROZEN_NO_EVENT)
+	    {
+		if (device->sync.evcount < count)
+		{
+		    Must_have_memory = TRUE; /* XXX */
+		    device->sync.event = (xEvent *)xrealloc(device->sync.event,
+							    count*
+							    sizeof(xEvent));
+		    Must_have_memory = FALSE; /* XXX */
+		}
+		device->sync.evcount = count;
+		for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+		    *dxE = *xE;
+	    	device->sync.state = FROZEN_WITH_EVENT;
+            }	
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated.  If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated.  If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated.  If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(device, xE, checkFirst, count)
+    register DeviceIntPtr device;
+    register xEvent *xE;
+    int checkFirst;
+    int count;
+{
+    register int i;
+    register WindowPtr pWin = NULL;
+    register FocusClassPtr focus = device->focus;
+
+    if ((xE->u.u.type == ButtonPress
+#ifdef XINPUT
+	 || xE->u.u.type == DeviceButtonPress
+#endif
+	 ) && device->button->buttonsDown != 1)
+	return FALSE;
+
+    i = checkFirst;
+
+    if (focus)
+    {
+	for (; i < focus->traceGood; i++)
+	{
+	    pWin = focus->trace[i];
+	    if (pWin->optional &&
+		CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+		return TRUE;
+	}
+  
+	if ((focus->win == NoneWin) ||
+	    (i >= spriteTraceGood) ||
+	    ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+	    return FALSE;
+    }
+
+    for (; i < spriteTraceGood; i++)
+    {
+	pWin = spriteTrace[i];
+	if (pWin->optional &&
+	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+DeliverFocusedEvent(keybd, xE, window, count)
+    xEvent *xE;
+    DeviceIntPtr keybd;
+    WindowPtr window;
+    int count;
+{
+    WindowPtr focus = keybd->focus->win;
+    int mskidx = 0;
+
+    if (focus == FollowKeyboardWin)
+	focus = inputInfo.keyboard->focus->win;
+    if (!focus)
+	return;
+    if (focus == PointerRootWin)
+    {
+	DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+	return;
+    }
+    if ((focus == window) || IsParent(focus, window))
+    {
+	if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+	    return;
+    }
+    /* just deliver it to the focus window */
+    FixUpEventFromWindow(xE, focus, None, FALSE);
+    if (xE->u.u.type & EXTENSION_EVENT_BASE)
+	mskidx = keybd->id;
+    (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+				NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
+    register xEvent *xE;
+    register DeviceIntPtr thisDev;
+    Bool deactivateGrab;
+    int count;
+{
+    register GrabPtr grab = thisDev->grab;
+    int deliveries = 0;
+    register DeviceIntPtr dev;
+    register xEvent *dxE;
+
+    if (grab->ownerEvents)
+    {
+	WindowPtr focus;
+
+	if (thisDev->focus)
+	{
+	    focus = thisDev->focus->win;
+	    if (focus == FollowKeyboardWin)
+		focus = inputInfo.keyboard->focus->win;
+	}
+	else
+	    focus = PointerRootWin;
+	if (focus == PointerRootWin)
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+					     thisDev, count);
+	else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+					     thisDev, count);
+	else if (focus)
+	    deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+					     thisDev, count);
+    }
+    if (!deliveries)
+    {
+	FixUpEventFromWindow(xE, grab->window, None, TRUE);
+	deliveries = TryClientEvents(rClient(grab), xE, count,
+				     (Mask)grab->eventMask,
+				     filters[xE->u.u.type], grab);
+	if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+			   || xE->u.u.type == DeviceMotionNotify
+#endif
+			   ))
+	    thisDev->valuator->motionHintWindow = grab->window;
+    }
+    if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+					  && xE->u.u.type != DeviceMotionNotify
+#endif
+					  ))
+	switch (thisDev->sync.state)
+	{
+	case FREEZE_BOTH_NEXT_EVENT:
+	    for (dev = inputInfo.devices; dev; dev = dev->next)
+	    {
+		if (dev == thisDev)
+		    continue;
+		FreezeThaw(dev, TRUE);
+		if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+		    (CLIENT_BITS(dev->grab->resource) ==
+		     CLIENT_BITS(thisDev->grab->resource)))
+		    dev->sync.state = FROZEN_NO_EVENT;
+		else
+		    dev->sync.other = thisDev->grab;
+	    }
+	    /* fall through */
+	case FREEZE_NEXT_EVENT:
+	    thisDev->sync.state = FROZEN_WITH_EVENT;
+	    FreezeThaw(thisDev, TRUE);
+	    if (thisDev->sync.evcount < count)
+	    {
+		Must_have_memory = TRUE; /* XXX */
+		thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+							 count*sizeof(xEvent));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    thisDev->sync.evcount = count;
+	    for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+		*dxE = *xE;
+	    break;
+	}
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (xE, keybd, count)
+#else
+ProcessKeyboardEvent (xE, keybd, count)
+#endif
+    register xEvent *xE;
+    register DeviceIntPtr keybd;
+    int count;
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register int    i;
+    register CARD8  modifiers;
+    register CARD16 mask;
+    GrabPtr         grab = keybd->grab;
+    Bool            deactivateGrab = FALSE;
+    register KeyClassPtr keyc = keybd->key;
+
+    if (!syncEvents.playingEvents)
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+    XE_KBPTR.rootX = sprite.hot.x;
+    XE_KBPTR.rootY = sprite.hot.y;
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+    modifiers = keyc->modifierMap[key];
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    if (*kptr & bit) /* allow ddx to generate multiple downs */
+	    {   
+		if (!modifiers)
+		{
+		    xE->u.u.type = KeyRelease;
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		    xE->u.u.type = KeyPress;
+		    /* release can have side effects, don't fall through */
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		}
+		return;
+	    }
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr |= bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers)
+		{
+		    /* This key affects modifier "i" */
+		    keyc->modifierKeyCount[i]++;
+		    keyc->state |= mask;
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+	    {
+		keybd->activatingKey = key;
+		return;
+	    }
+	    break;
+	case KeyRelease: 
+	    if (!(*kptr & bit)) /* guard against duplicates */
+		return;
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr &= ~bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers) {
+		    /* This key affects modifier "i" */
+		    if (--keyc->modifierKeyCount[i] <= 0) {
+			keyc->state &= ~mask;
+			keyc->modifierKeyCount[i] = 0;
+		    }
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+    if (grab)
+	DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+    else
+	DeliverFocusedEvent(keybd, xE, sprite.win, count);
+    if (deactivateGrab)
+        (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+   this is only used when the pressing of keys does not cause 
+   CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (xE, keybd)
+    register xEvent *xE;
+    register DeviceIntPtr keybd;
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register KeyClassPtr keyc = keybd->key;
+
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("FixKeyState: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    *kptr |= bit;
+	    break;
+	case KeyRelease: 
+	    *kptr &= ~bit;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (xE, mouse, count)
+#else
+ProcessPointerEvent (xE, mouse, count)
+#endif
+    register xEvent 		*xE;
+    register DeviceIntPtr 	mouse;
+    int				count;
+{
+    register GrabPtr	grab = mouse->grab;
+    Bool                deactivateGrab = FALSE;
+    register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+    XkbSrvInfoPtr xkbi;
+
+    xkbi = inputInfo.keyboard->key->xkbInfo;
+#endif
+
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE)
+    XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+			(noXkbExtension ?
+				inputInfo.keyboard->key->state :
+				xkbi->state.grab_mods)
+#else
+			inputInfo.keyboard->key->state
+#endif
+				    ));
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    /* see comment in EnqueueEvents regarding the next three lines */
+	    if (xE->u.u.type == MotionNotify)
+		XE_KBPTR.root =
+		    WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    if (xE->u.u.type != MotionNotify)
+    {
+	register int  key;
+	register BYTE *kptr;
+	int           bit;
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+
+	key = xE->u.u.detail;
+	kptr = &butc->down[key >> 3];
+	bit = 1 << (key & 7);
+	switch (xE->u.u.type)
+	{
+	case ButtonPress: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (!(*kptr & bit))
+		butc->buttonsDown++;
+	    butc->motionMask = ButtonMotionMask;
+	    *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!grab)
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		    return;
+	    break;
+	case ButtonRelease: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (*kptr & bit)
+		--butc->buttonsDown;
+	    if (!butc->buttonsDown)
+		butc->motionMask = 0;
+	    *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!butc->state && mouse->fromPassiveGrab)
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("bogus pointer event from ddx");
+	}
+    }
+    else if (!CheckMotion(xE))
+	return;
+    if (grab)
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    else
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    if (deactivateGrab)
+        (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+	(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+    register WindowPtr pWin;
+{
+    register OtherClients *others;
+    register WindowPtr pChild;
+
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->optional)
+	{
+	    pChild->optional->otherEventMasks = 0;
+	    for (others = wOtherClients(pChild); others; others = others->next)
+	    {
+		pChild->optional->otherEventMasks |= others->mask;
+	    }
+	}
+	pChild->deliverableEvents = pChild->eventMask|
+				    wOtherEventMasks(pChild);
+	if (pChild->parent)
+	    pChild->deliverableEvents |=
+		(pChild->parent->deliverableEvents &
+		 ~wDontPropagateMask(pChild) & PropagateMask);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+int
+OtherClientGone(value, id)
+    pointer value; /* must conform to DeleteType */
+    XID   id;
+{
+    register OtherClientsPtr other, prev;
+    register WindowPtr pWin = (WindowPtr)value;
+
+    prev = 0;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->resource == id)
+	{
+	    if (prev)
+		prev->next = other->next;
+	    else
+	    {
+		if (!(pWin->optional->otherClients = other->next))
+		    CheckWindowOptionalNeed (pWin);
+	    }
+	    xfree(other);
+	    RecalculateDeliverableEvents(pWin);
+	    return(Success);
+	}
+	prev = other;
+    }
+    FatalError("client not on event list");
+    /*NOTREACHED*/
+    return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(pWin, client, mask)
+    register WindowPtr pWin;
+    register ClientPtr client;
+    Mask mask;
+{
+    Mask check;
+    OtherClients * others;
+
+    if (mask & ~AllEventMasks)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    check = (mask & AtMostOneClient);
+    if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+    {				       /* It is illegal for two different
+				          clients to select on any of the
+				          events for AtMostOneClient. However,
+				          it is OK, for some client to
+				          continue selecting on one of those
+				          events.  */
+	if ((wClient(pWin) != client) && (check & pWin->eventMask))
+	    return BadAccess;
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (!SameClient(others, client) && (check & others->mask))
+		return BadAccess;
+	}
+    }
+    if (wClient (pWin) == client)
+    {
+	check = pWin->eventMask;
+#ifdef SGIMISC
+	pWin->eventMask =
+	    (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+	pWin->eventMask = mask;
+#endif
+    }
+    else
+    {
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (SameClient(others, client))
+	    {
+		check = others->mask;
+#ifdef SGIMISC
+		mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+		if (mask == 0)
+		{
+		    FreeResource(others->resource, RT_NONE);
+		    return Success;
+		}
+		else
+		    others->mask = mask;
+		goto maskSet;
+	    }
+	}
+	check = 0;
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return BadAlloc;
+	others = (OtherClients *) xalloc(sizeof(OtherClients));
+	if (!others)
+	    return BadAlloc;
+	others->mask = mask;
+	others->resource = FakeClientID(client->index);
+	others->next = pWin->optional->otherClients;
+	pWin->optional->otherClients = others;
+	if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+	    return BadAlloc;
+    }
+maskSet: 
+    if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+	(mask & PointerMotionHintMask) &&
+	!(check & PointerMotionHintMask) &&
+	!inputInfo.pointer->grab)
+	inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+/*ARGSUSED*/
+int
+EventSuppressForWindow(pWin, client, mask, checkOptional)
+    register WindowPtr pWin;
+    register ClientPtr client;
+    Mask mask;
+    Bool *checkOptional;
+{
+    register int i, free;
+
+    if ((mask & ~PropagateMask) && !permitOldBugs)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    if (pWin->dontPropagate)
+	DontPropagateRefCnts[pWin->dontPropagate]--;
+    if (!mask)
+	i = 0;
+    else
+    {
+	for (i = DNPMCOUNT, free = 0; --i > 0; )
+	{
+	    if (!DontPropagateRefCnts[i])
+		free = i;
+	    else if (mask == DontPropagateMasks[i])
+		break;
+	}
+	if (!i && free)
+	{
+	    i = free;
+	    DontPropagateMasks[i] = mask;
+	}
+    }
+    if (i || !mask)
+    {
+	pWin->dontPropagate = i;
+	if (i)
+	    DontPropagateRefCnts[i]++;
+	if (pWin->optional)
+	{
+	    pWin->optional->dontPropagateMask = mask;
+	    *checkOptional = TRUE;
+	}
+    }
+    else
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	{
+	    if (pWin->dontPropagate)
+		DontPropagateRefCnts[pWin->dontPropagate]++;
+	    return BadAlloc;
+	}
+	pWin->dontPropagate = 0;
+        pWin->optional->dontPropagateMask = mask;
+    }
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+static WindowPtr 
+#if NeedFunctionPrototypes
+CommonAncestor(
+    register WindowPtr a,
+    register WindowPtr b)
+#else
+CommonAncestor(a, b)
+    register WindowPtr a, b;
+#endif
+{
+    for (b = b->parent; b; b = b->parent)
+	if (IsParent(b, a)) return b;
+    return NullWindow;
+}
+
+static void
+#if NeedFunctionPrototypes
+EnterLeaveEvent(
+    int type,
+    int mode,
+    int detail,
+    register WindowPtr pWin,
+    Window child)
+#else
+EnterLeaveEvent(type, mode, detail, pWin, child)
+    int type, mode, detail;
+    register WindowPtr pWin;
+    Window child;
+#endif
+{
+    xEvent		event;
+    register DeviceIntPtr keybd = inputInfo.keyboard;
+    WindowPtr		focus;
+    register DeviceIntPtr mouse = inputInfo.pointer;
+    register GrabPtr	grab = mouse->grab;
+    Mask		mask;
+
+    if ((pWin == mouse->valuator->motionHintWindow) &&
+	(detail != NotifyInferior))
+	mouse->valuator->motionHintWindow = NullWindow;
+    if (grab)
+    {
+	mask = (pWin == grab->window) ? grab->eventMask : 0;
+	if (grab->ownerEvents)
+	    mask |= EventMaskForClient(pWin, rClient(grab));
+    }
+    else
+    {
+	mask = pWin->eventMask | wOtherEventMasks(pWin);
+    }
+    if (mask & filters[type])
+    {
+	event.u.u.type = type;
+	event.u.u.detail = detail;
+	event.u.enterLeave.time = currentTime.milliseconds;
+	event.u.enterLeave.rootX = sprite.hot.x;
+	event.u.enterLeave.rootY = sprite.hot.y;
+	/* Counts on the same initial structure of crossing & button events! */
+	FixUpEventFromWindow(&event, pWin, None, FALSE);
+	/* Enter/Leave events always set child */
+	event.u.enterLeave.child = child;
+	event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+					    ELFlagSameScreen : 0;
+#ifdef XKB
+	if (!noXkbExtension) {
+	    event.u.enterLeave.state = mouse->button->state & 0x1f00;
+	    event.u.enterLeave.state |= 
+			XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+	} else
+#endif
+	event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+	event.u.enterLeave.mode = mode;
+	focus = keybd->focus->win;
+	if ((focus != NoneWin) &&
+	    ((pWin == focus) || (focus == PointerRootWin) ||
+	     IsParent(focus, pWin)))
+	    event.u.enterLeave.flags |= ELFlagFocus;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), &event, 1, mask,
+				  filters[type], grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+					NullGrab, 0);
+    }
+    if ((type == EnterNotify) && (mask & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+
+#ifdef XCSECURITY
+	ClientPtr client = grab ? rClient(grab)
+				: clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+	ke.type = KeymapNotify;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+				  KeymapStateMask, grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+					KeymapStateMask, NullGrab, 0);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+#else
+EnterNotifies(ancestor, child, mode, detail)
+    WindowPtr ancestor, child;
+    int mode, detail;
+#endif
+{
+    WindowPtr	parent = child->parent;
+
+    if (ancestor == parent)
+	return;
+    EnterNotifies(ancestor, parent, mode, detail);
+    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+#if NeedFunctionPrototypes
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+#else
+LeaveNotifies(child, ancestor, mode, detail)
+    WindowPtr child, ancestor;
+    int detail, mode;
+#endif
+{
+    register WindowPtr  pWin;
+
+    if (ancestor == child)
+	return;
+    for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+    {
+	EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+	child = pWin;
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+#else
+DoEnterLeaveEvents(fromWin, toWin, mode)
+    WindowPtr fromWin, toWin;
+    int mode;
+#endif
+{
+    if (fromWin == toWin)
+	return;
+    if (IsParent(fromWin, toWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+	EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+    }
+    else if (IsParent(toWin, fromWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+	LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+    }
+    else
+    { /* neither fromWin nor toWin is descendent of the other */
+	WindowPtr common = CommonAncestor(toWin, fromWin);
+	/* common == NullWindow ==> different screens */
+	EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+	LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+	EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+#else
+FocusEvent(dev, type, mode, detail, pWin)
+    DeviceIntPtr dev;
+    int type, mode, detail;
+    register WindowPtr pWin;
+#endif
+{
+    xEvent event;
+
+#ifdef XINPUT
+    if (dev != inputInfo.keyboard)
+    {
+	DeviceFocusEvent(dev, type, mode, detail, pWin);
+	return;
+    }
+#endif
+    event.u.focus.mode = mode;
+    event.u.u.type = type;
+    event.u.u.detail = detail;
+    event.u.focus.window = pWin->drawable.id;
+    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+				0);
+    if ((type == FocusIn) &&
+	((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+#ifdef XCSECURITY
+	ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+	ke.type = KeymapNotify;
+	(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+				    KeymapStateMask, NullGrab, 0);
+    }
+}
+
+ /*
+  * recursive because it is easier
+  * no-op if child not descended from ancestor
+  */
+static Bool
+#if NeedFunctionPrototypes
+FocusInEvents(
+    DeviceIntPtr dev,
+    WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+    int mode, int detail,
+    Bool doAncestor)
+#else
+FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
+    DeviceIntPtr dev;
+    WindowPtr ancestor, child, skipChild;
+    int mode, detail;
+    Bool doAncestor;
+#endif
+{
+    if (child == NullWindow)
+	return ancestor == NullWindow;
+    if (ancestor == child)
+    {
+	if (doAncestor)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+		      doAncestor))
+    {
+	if (child != skipChild)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+#if NeedFunctionPrototypes
+FocusOutEvents(
+    DeviceIntPtr dev,
+    WindowPtr child, WindowPtr ancestor,
+    int mode, int detail,
+    Bool doAncestor)
+#else
+FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
+    DeviceIntPtr dev;
+    WindowPtr child, ancestor;
+    int mode;
+    int detail;
+    Bool doAncestor;
+#endif
+{
+    register WindowPtr  pWin;
+
+    for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+	FocusEvent(dev, FocusOut, mode, detail, pWin);
+    if (doAncestor)
+	FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(dev, fromWin, toWin, mode)
+    DeviceIntPtr dev;
+    WindowPtr fromWin, toWin;
+    int mode;
+{
+    int     out, in;		       /* for holding details for to/from
+				          PointerRoot/None */
+    int     i;
+
+    if (fromWin == toWin)
+	return;
+    out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+    in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+    if ((toWin == NullWindow) || (toWin == PointerRootWin))
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+   	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+	    /* Notify all the roots */
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	}
+	else
+	{
+	    if (IsParent(fromWin, sprite.win))
+	      FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+			     FALSE);
+	    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+	    /* next call catches the root too, if the screen changed */
+	    FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+			   NotifyNonlinearVirtual, FALSE);
+	}
+	/* Notify all the roots */
+#ifdef PANORAMIX
+	if ( !noPanoramiXExtension )
+	    FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+	else 
+#endif
+	    for (i=0; i<screenInfo.numScreens; i++)
+	        FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+	if (toWin == PointerRootWin)
+	    (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+				NotifyPointer, TRUE);
+    }
+    else
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	    if (toWin->parent != NullWindow)
+	      (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+				  NotifyNonlinearVirtual, TRUE);
+	    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+	    if (IsParent(toWin, sprite.win))
+    	       (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+				   NotifyPointer, FALSE);
+	}
+	else
+	{
+	    if (IsParent(toWin, fromWin))
+	    {
+		FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+		FocusOutEvents(dev, fromWin->parent, toWin, mode,
+			       NotifyVirtual, FALSE);
+		FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+		if ((IsParent(toWin, sprite.win)) &&
+			(sprite.win != fromWin) &&
+			(!IsParent(fromWin, sprite.win)) &&
+			(!IsParent(sprite.win, fromWin)))
+		    (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					mode, NotifyPointer, FALSE);
+	    }
+	    else
+		if (IsParent(fromWin, toWin))
+		{
+		    if ((IsParent(fromWin, sprite.win)) &&
+			    (sprite.win != fromWin) &&
+			    (!IsParent(toWin, sprite.win)) &&
+			    (!IsParent(sprite.win, toWin)))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+		    (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+					NotifyVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+		}
+		else
+		{
+		/* neither fromWin or toWin is child of other */
+		    WindowPtr common = CommonAncestor(toWin, fromWin);
+		/* common == NullWindow ==> different screens */
+		    if (IsParent(fromWin, sprite.win))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+		    if (fromWin->parent != NullWindow)
+		      FocusOutEvents(dev, fromWin->parent, common, mode,
+				     NotifyNonlinearVirtual, FALSE);
+		    if (toWin->parent != NullWindow)
+		      (void)FocusInEvents(dev, common, toWin, toWin, mode,
+					  NotifyNonlinearVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+		    if (IsParent(toWin, sprite.win))
+			(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					    mode, NotifyPointer, FALSE);
+		}
+	}
+    }
+}
+
+int
+#if NeedFunctionPrototypes
+SetInputFocus(
+    ClientPtr client,
+    DeviceIntPtr dev,
+    Window focusID,
+    CARD8 revertTo,
+    Time ctime,
+    Bool followOK)
+#else
+SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
+    ClientPtr client;
+    DeviceIntPtr dev;
+    Window focusID;
+    CARD8 revertTo;
+    Time ctime;
+    Bool followOK;
+#endif
+{
+    register FocusClassPtr focus;
+    register WindowPtr focusWin;
+    int mode;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((revertTo != RevertToParent) &&
+	(revertTo != RevertToPointerRoot) &&
+	(revertTo != RevertToNone) &&
+	((revertTo != RevertToFollowKeyboard) || !followOK))
+    {
+	client->errorValue = revertTo;
+	return BadValue;
+    }
+    time = ClientTimeToServerTime(ctime);
+    if ((focusID == None) || (focusID == PointerRoot))
+	focusWin = (WindowPtr)(long)focusID;
+    else if ((focusID == FollowKeyboard) && followOK)
+	focusWin = inputInfo.keyboard->focus->win;
+    else if (!(focusWin = SecurityLookupWindow(focusID, client,
+					       SecurityReadAccess)))
+	return BadWindow;
+    else
+    {
+ 	/* It is a match error to try to set the input focus to an 
+	unviewable window. */
+
+	if(!focusWin->realized)
+	    return(BadMatch);
+    }
+    focus = dev->focus;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, focus->time) == EARLIER))
+	return Success;
+    mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+    if (focus->win == FollowKeyboardWin)
+	DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+    else
+	DoFocusEvents(dev, focus->win, focusWin, mode);
+    focus->time = time;
+    focus->revert = revertTo;
+    if (focusID == FollowKeyboard)
+	focus->win = FollowKeyboardWin;
+    else
+	focus->win = focusWin;
+    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+	focus->traceGood = 0;
+    else
+    {
+        int depth = 0;
+	register WindowPtr pWin;
+
+        for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+        if (depth > focus->traceSize)
+        {
+	    focus->traceSize = depth+1;
+	    Must_have_memory = TRUE; /* XXX */
+	    focus->trace = (WindowPtr *)xrealloc(focus->trace,
+						 focus->traceSize *
+						 sizeof(WindowPtr));
+	    Must_have_memory = FALSE; /* XXX */
+	}
+	focus->traceGood = depth;
+        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
+	    focus->trace[depth] = pWin;
+    }
+    return Success;
+}
+
+int
+ProcSetInputFocus(client)
+    ClientPtr client;
+{
+    REQUEST(xSetInputFocusReq);
+
+    REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+	return Success;
+#endif
+    return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+			 stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(client)
+    ClientPtr client;
+{
+    xGetInputFocusReply rep;
+    /* REQUEST(xReq); */
+    FocusClassPtr focus = inputInfo.keyboard->focus;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (focus->win == NoneWin)
+	rep.focus = None;
+    else if (focus->win == PointerRootWin)
+	rep.focus = PointerRoot;
+    else rep.focus = focus->win->drawable.id;
+    rep.revertTo = focus->revert;
+    WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+    return Success;
+}
+
+int
+ProcGrabPointer(client)
+    ClientPtr client;
+{
+    xGrabPointerReply rep;
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    WindowPtr pWin, confineTo;
+    CursorPtr cursor, oldCursor;
+    REQUEST(xGrabPointerReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xGrabPointerReq);
+    UpdateCurrentTime();
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+        return BadValue;
+    }
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+	confineTo = NullWindow;
+    else 
+    {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+	/* at this point, some sort of reply is guaranteed. */
+    time = ClientTimeToServerTime(stuff->time);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    grab = device->grab;
+    if ((grab) && !SameClient(grab, client))
+	rep.status = AlreadyGrabbed;
+    else if ((!pWin->realized) ||
+             (confineTo &&
+                !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+	rep.status = GrabNotViewable;
+    else if (device->sync.frozen &&
+	     device->sync.other && !SameClient(device->sync.other, client))
+	rep.status = GrabFrozen;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	rep.status = GrabInvalidTime;
+    else
+    {
+	GrabRec tempGrab;
+
+	oldCursor = NullCursor;
+	if (grab)
+ 	{
+	    if (grab->confineTo && !confineTo)
+		ConfineCursorToWindow(ROOT, FALSE, FALSE);
+	    oldCursor = grab->cursor;
+	}
+	tempGrab.cursor = cursor;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = stuff->ownerEvents;
+	tempGrab.eventMask = stuff->eventMask;
+	tempGrab.confineTo = confineTo;
+	tempGrab.window = pWin;
+	tempGrab.keyboardMode = stuff->keyboardMode;
+	tempGrab.pointerMode = stuff->pointerMode;
+	tempGrab.device = device;
+	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+	if (oldCursor)
+	    FreeCursor (oldCursor, (Cursor)0);
+	rep.status = GrabSuccess;
+    }
+    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+    return Success;
+}
+
+int
+ProcChangeActivePointerGrab(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    register GrabPtr grab = device->grab;
+    CursorPtr newCursor, oldCursor;
+    REQUEST(xChangeActivePointerGrabReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    if (stuff->cursor == None)
+	newCursor = NullCursor;
+    else
+    {
+	newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!newCursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+    if (!grab)
+	return Success;
+    if (!SameClient(grab, client))
+	return Success;
+    time = ClientTimeToServerTime(stuff->time);
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	return Success;
+    oldCursor = grab->cursor;
+    grab->cursor = newCursor;
+    if (newCursor)
+	newCursor->refcnt++;
+    PostNewCursor();
+    if (oldCursor)
+	FreeCursor(oldCursor, (Cursor)0);
+    grab->eventMask = stuff->eventMask;
+    return Success;
+}
+
+int
+ProcUngrabPointer(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	    (grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
+	   mask, status)
+    register ClientPtr client;
+    register DeviceIntPtr dev;
+    unsigned this_mode;
+    unsigned other_mode;
+    Window grabWindow;
+    unsigned ownerEvents;
+    Time ctime;
+    Mask mask;
+    CARD8 *status;
+{
+    register WindowPtr pWin;
+    register GrabPtr grab;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+    {
+	client->errorValue = this_mode;
+        return BadValue;
+    }
+    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+    {
+	client->errorValue = other_mode;
+        return BadValue;
+    }
+    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+    {
+	client->errorValue = ownerEvents;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    time = ClientTimeToServerTime(ctime);
+    grab = dev->grab;
+    if (grab && !SameClient(grab, client))
+	*status = AlreadyGrabbed;
+    else if (!pWin->realized)
+	*status = GrabNotViewable;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+	*status = GrabInvalidTime;
+    else if (dev->sync.frozen &&
+	     dev->sync.other && !SameClient(dev->sync.other, client))
+	*status = GrabFrozen;
+    else
+    {
+	GrabRec tempGrab;
+
+	tempGrab.window = pWin;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = ownerEvents;
+	tempGrab.keyboardMode = this_mode;
+	tempGrab.pointerMode = other_mode;
+	tempGrab.eventMask = mask;
+	tempGrab.device = dev;
+	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+	*status = GrabSuccess;
+    }
+    return Success;
+}
+
+int
+ProcGrabKeyboard(client)
+    ClientPtr client;
+{
+    xGrabKeyboardReply rep;
+    REQUEST(xGrabKeyboardReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+    {
+	result = Success;
+	rep.status = AlreadyGrabbed;
+    }
+    else
+#endif
+    result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+			stuff->pointerMode, stuff->grabWindow,
+			stuff->ownerEvents, stuff->time,
+			KeyPressMask | KeyReleaseMask, &rep.status);
+    if (result != Success)
+	return result;
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+    return Success;
+}
+
+int
+ProcUngrabKeyboard(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.keyboard;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	(grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+ProcQueryPointer(client)
+    ClientPtr client;
+{
+    xQueryPointerReply rep;
+    WindowPtr pWin, t;
+    REQUEST(xResourceReq);
+    DeviceIntPtr mouse = inputInfo.pointer;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (mouse->valuator->motionHintWindow)
+	MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+    rep.length = 0;
+    rep.root = (ROOT)->drawable.id;
+    rep.rootX = sprite.hot.x;
+    rep.rootY = sprite.hot.y;
+    rep.child = None;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	rep.sameScreen = xTrue;
+	rep.winX = sprite.hot.x - pWin->drawable.x;
+	rep.winY = sprite.hot.y - pWin->drawable.y;
+	for (t = sprite.win; t; t = t->parent)
+	    if (t->parent == pWin)
+	    {
+		rep.child = t->drawable.id;
+		break;
+	    }
+    }
+    else
+    {
+	rep.sameScreen = xFalse;
+	rep.winX = 0;
+	rep.winY = 0;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	rep.rootX += panoramiXdataPtr[0].x;
+	rep.rootY += panoramiXdataPtr[0].y;
+	if(stuff->id == rep.root) {
+	    rep.winX += panoramiXdataPtr[0].x;
+	    rep.winY += panoramiXdataPtr[0].y;
+	}
+    }
+#endif
+
+    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+    return(Success);    
+}
+
+void
+InitEvents()
+{
+    int i;
+
+    sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+    inputInfo.numDevices = 0;
+    inputInfo.devices = (DeviceIntPtr)NULL;
+    inputInfo.off_devices = (DeviceIntPtr)NULL;
+    inputInfo.keyboard = (DeviceIntPtr)NULL;
+    inputInfo.pointer = (DeviceIntPtr)NULL;
+    if (spriteTraceSize == 0)
+    {
+	spriteTraceSize = 32;
+	spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+	if (!spriteTrace)
+	    FatalError("failed to allocate spriteTrace");
+    }
+    spriteTraceGood = 0;
+    lastEventMask = OwnerGrabButtonMask;
+    filters[MotionNotify] = PointerMotionMask;
+    sprite.win = NullWindow;
+    sprite.current = NullCursor;
+    sprite.hotLimits.x1 = 0;
+    sprite.hotLimits.y1 = 0;
+    sprite.hotLimits.x2 = 0;
+    sprite.hotLimits.y2 = 0;
+    sprite.confined = FALSE;
+    syncEvents.replayDev = (DeviceIntPtr)NULL;
+    syncEvents.replayWin = NullWindow;
+    while (syncEvents.pending)
+    {
+	QdEventPtr next = syncEvents.pending->next;
+	xfree(syncEvents.pending);
+	syncEvents.pending = next;
+    }
+    syncEvents.pendtail = &syncEvents.pending;
+    syncEvents.playingEvents = FALSE;
+    syncEvents.time.months = 0;
+    syncEvents.time.milliseconds = 0;	/* hardly matters */
+    currentTime.months = 0;
+    currentTime.milliseconds = GetTimeInMillis();
+    lastDeviceEventTime = currentTime;
+    for (i = 0; i < DNPMCOUNT; i++)
+    {
+	DontPropagateMasks[i] = 0;
+	DontPropagateRefCnts[i] = 0;
+    }
+}
+
+void
+CloseDownEvents(void)
+{
+  xfree(spriteTrace);
+  spriteTrace = NULL;
+  spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(client)
+    ClientPtr client;
+{
+    WindowPtr pWin;
+    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+    REQUEST(xSendEventReq);
+
+    REQUEST_SIZE_MATCH(xSendEventReq);
+
+    /* The client's event type must be a core event type or one defined by an
+	extension. */
+
+
+#ifdef NXAGENT_CLIPBOARD
+
+    if (stuff -> event.u.u.type == SelectionNotify)
+    {
+    	extern int nxagentSendNotify(xEvent*);
+	if (nxagentSendNotify(&stuff->event) == 1)
+	  return Success;
+    }
+#endif
+
+    if ( ! ((stuff->event.u.u.type > X_Reply &&
+	     stuff->event.u.u.type < LASTEvent) || 
+	    (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+	     stuff->event.u.u.type < (unsigned)lastEvent)))
+    {
+	client->errorValue = stuff->event.u.u.type;
+	return BadValue;
+    }
+    if (stuff->event.u.u.type == ClientMessage &&
+	stuff->event.u.u.detail != 8 &&
+	stuff->event.u.u.detail != 16 &&
+	stuff->event.u.u.detail != 32 &&
+	!permitOldBugs)
+    {
+	client->errorValue = stuff->event.u.u.detail;
+	return BadValue;
+    }
+    if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+	return BadValue;
+    }
+
+    if (stuff->destination == PointerWindow)
+	pWin = sprite.win;
+    else if (stuff->destination == InputFocus)
+    {
+	WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+	if (inputFocus == NoneWin)
+	    return Success;
+
+	/* If the input focus is PointerRootWin, send the event to where
+	the pointer is if possible, then perhaps propogate up to root. */
+   	if (inputFocus == PointerRootWin)
+	    inputFocus = ROOT;
+
+	if (IsParent(inputFocus, sprite.win))
+	{
+	    effectiveFocus = inputFocus;
+	    pWin = sprite.win;
+	}
+	else
+	    effectiveFocus = pWin = inputFocus;
+    }
+    else
+	pWin = SecurityLookupWindow(stuff->destination, client,
+				    SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+    {
+	client->errorValue = stuff->propagate;
+	return BadValue;
+    }
+    stuff->event.u.u.type |= 0x80;
+    if (stuff->propagate)
+    {
+	for (;pWin; pWin = pWin->parent)
+	{
+	    if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				      NullGrab, 0))
+		return Success;
+	    if (pWin == effectiveFocus)
+		return Success;
+	    stuff->eventMask &= ~wDontPropagateMask(pWin);
+	    if (!stuff->eventMask)
+		break;
+	}
+    }
+    else
+	(void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				    NullGrab, 0);
+    return Success;
+}
+
+int
+ProcUngrabKey(client)
+    ClientPtr client;
+{
+    REQUEST(xUngrabKeyReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xUngrabKeyReq);
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = keybd;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = KeyPress;
+    tempGrab.detail.exact = stuff->key;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+int
+ProcGrabKey(client)
+    ClientPtr client;
+{
+    WindowPtr pWin;
+    REQUEST(xGrabKeyReq);
+    GrabPtr grab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xGrabKeyReq);
+    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return(BadValue);
+    }
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    grab = CreateGrab(client->index, keybd, pWin, 
+	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+	keybd, stuff->modifiers, KeyPress, stuff->key, 
+	NullWindow, NullCursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(client)
+    ClientPtr client;
+{
+    WindowPtr pWin, confineTo;
+    REQUEST(xGrabButtonReq);
+    CursorPtr cursor;
+    GrabPtr grab;
+
+    REQUEST_SIZE_MATCH(xGrabButtonReq);
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return BadValue;
+    }
+    if (stuff->eventMask & ~PointerGrabMask)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+       confineTo = NullWindow;
+    else {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+
+
+    grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
+    permitOldBugs ? (Mask)(stuff->eventMask |
+			       ButtonPressMask | ButtonReleaseMask) :
+			(Mask)stuff->eventMask,
+	(Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+	(Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+	ButtonPress, stuff->button, confineTo, cursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(client)
+    ClientPtr client;
+{
+    REQUEST(xUngrabButtonReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+
+    REQUEST_SIZE_MATCH(xUngrabButtonReq);
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = inputInfo.pointer;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = ButtonPress;
+    tempGrab.detail.exact = stuff->button;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(pWin, freeResources)
+    WindowPtr		pWin;
+    Bool		freeResources;
+{
+    WindowPtr		parent;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    FocusClassPtr	focus = keybd->focus;
+    OtherClientsPtr	oc;
+    GrabPtr		passive;
+
+
+    /* Deactivate any grabs performed on this window, before making any
+	input focus changes. */
+
+    if (mouse->grab &&
+	((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+	(*mouse->DeactivateGrab)(mouse);
+
+    /* Deactivating a keyboard grab should cause focus events. */
+
+    if (keybd->grab && (keybd->grab->window == pWin))
+	(*keybd->DeactivateGrab)(keybd);
+
+    /* If the focus window is a root window (ie. has no parent) then don't 
+	delete the focus from it. */
+    
+    if ((pWin == focus->win) && (pWin->parent != NullWindow))
+    {
+	int focusEventMode = NotifyNormal;
+
+ 	/* If a grab is in progress, then alter the mode of focus events. */
+
+	if (keybd->grab)
+	    focusEventMode = NotifyWhileGrabbed;
+
+	switch (focus->revert)
+	{
+	case RevertToNone:
+	    DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+	    focus->win = NoneWin;
+	    focus->traceGood = 0;
+	    break;
+	case RevertToParent:
+	    parent = pWin;
+	    do
+	    {
+		parent = parent->parent;
+		focus->traceGood--;
+	    } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+   during SaveSet processing would cause the focus to revert to the
+   nearest enclosing window which will survive the death of the exiting
+   client, instead of ending up reverting to a dying window and thence
+   to None
+ */
+#ifdef NOTDEF
+ 	      || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+		);
+	    DoFocusEvents(keybd, pWin, parent, focusEventMode);
+	    focus->win = parent;
+	    focus->revert = RevertToNone;
+	    break;
+	case RevertToPointerRoot:
+	    DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+	    focus->win = PointerRootWin;
+	    focus->traceGood = 0;
+	    break;
+	}
+    }
+
+    if (mouse->valuator->motionHintWindow == pWin)
+	mouse->valuator->motionHintWindow = NullWindow;
+
+    if (freeResources)
+    {
+	if (pWin->dontPropagate)
+	    DontPropagateRefCnts[pWin->dontPropagate]--;
+	while ( (oc = wOtherClients(pWin)) )
+	    FreeResource(oc->resource, RT_NONE);
+	while ( (passive = wPassiveGrabs(pWin)) )
+	    FreeResource(passive->resource, RT_NONE);
+     }
+#ifdef XINPUT
+    DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/* Call this whenever some window at or below pWin has changed geometry */
+
+/*ARGSUSED*/
+void
+CheckCursorConfinement(pWin)
+    WindowPtr pWin;
+{
+    GrabPtr grab = inputInfo.pointer->grab;
+    WindowPtr confineTo;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+    if (grab && (confineTo = grab->confineTo))
+    {
+	if (!BorderSizeNotEmpty(confineTo))
+	    (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+	else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+	    ConfineCursorToWindow(confineTo, TRUE, TRUE);
+    }
+}
+
+Mask
+EventMaskForClient(pWin, client)
+    WindowPtr		pWin;
+    ClientPtr		client;
+{
+    register OtherClientsPtr	other;
+
+    if (wClient (pWin) == client)
+	return pWin->eventMask;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (SameClient(other, client))
+	    return other->mask;
+    }
+    return 0;
+}
+
+int
+ProcRecolorCursor(client)
+    ClientPtr client;
+{
+    CursorPtr pCursor;
+    int		nscr;
+    ScreenPtr	pscr;
+    Bool 	displayed;
+    REQUEST(xRecolorCursorReq);
+
+    REQUEST_SIZE_MATCH(xRecolorCursorReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+					RT_CURSOR, SecurityWriteAccess);
+    if ( !pCursor) 
+    {
+	client->errorValue = stuff->cursor;
+	return (BadCursor);
+    }
+
+    pCursor->foreRed = stuff->foreRed;
+    pCursor->foreGreen = stuff->foreGreen;
+    pCursor->foreBlue = stuff->foreBlue;
+
+    pCursor->backRed = stuff->backRed;
+    pCursor->backGreen = stuff->backGreen;
+    pCursor->backBlue = stuff->backBlue;
+
+    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+    {
+	pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension)
+	    displayed = (pscr == sprite.screen);
+	else
+#endif
+	    displayed = (pscr == sprite.hotPhys.pScreen);
+	( *pscr->RecolorCursor)(pscr, pCursor,
+				(pCursor == sprite.current) && displayed);
+    }
+    return (Success);
+}
+
+void
+WriteEventsToClient(pClient, count, events)
+    ClientPtr	pClient;
+    int		count;
+    xEvent	*events;
+{
+#ifdef PANORAMIX
+    xEvent    eventCopy;
+#endif
+    xEvent    eventTo, *eventFrom;
+    int       i;
+
+#ifdef XKB
+    if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+	return;
+#endif
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && 
+       (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 
+    {
+	switch(events->u.u.type) {
+	case MotionNotify:
+	case ButtonPress:
+	case ButtonRelease:
+	case KeyPress:
+	case KeyRelease:
+	case EnterNotify:
+	case LeaveNotify:
+	/* 
+	   When multiple clients want the same event DeliverEventsToWindow
+	   passes the same event structure multiple times so we can't 
+	   modify the one passed to us 
+        */
+	    count = 1;  /* should always be 1 */
+	    memcpy(&eventCopy, events, sizeof(xEvent));
+	    eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+	    eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+	    if(eventCopy.u.keyButtonPointer.event == 
+	       eventCopy.u.keyButtonPointer.root) 
+	    {
+		eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+		eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+	    }
+	    events = &eventCopy;
+	    break;
+	default: break;
+	}
+    }
+#endif
+
+    if (EventCallback)
+    {
+	EventInfoRec eventinfo;
+	eventinfo.client = pClient;
+	eventinfo.events = events;
+	eventinfo.count = count;
+	CallCallbacks(&EventCallback, (pointer)&eventinfo);
+    }
+    if(pClient->swapped)
+    {
+	for(i = 0; i < count; i++)
+	{
+	    eventFrom = &events[i];
+	    /* Remember to strip off the leading bit of type in case
+	       this event was sent with "SendEvent." */
+	    (*EventSwapVector[eventFrom->u.u.type & 0177])
+		(eventFrom, &eventTo);
+	    (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+	}
+    }
+    else
+    {
+	(void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+    }
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.XF86.original
new file mode 100644
index 000000000..ce8e53f92
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.XF86.original
@@ -0,0 +1,4637 @@
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.46 2002/09/17 01:15:09 dawes Exp $ */
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/****************************************************************
+*                                                               *
+*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include "XKBsrv.h"
+#if NeedFunctionPrototypes
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#else
+extern Bool XkbFilterEvents();
+#endif
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+
+#include "XIproto.h"
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "dispatch.h"
+
+#define EXTENSION_EVENT_BASE  64
+
+#define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+	Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+	PointerMotionMask | Button1MotionMask | \
+	Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+	Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+	KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+	MotionMask )
+#define PointerGrabMask ( \
+	ButtonPressMask | ButtonReleaseMask | \
+	EnterWindowMask | LeaveWindowMask | \
+	PointerMotionHintMask | KeymapStateMask | \
+	MotionMask )
+#define AllModifiersMask ( \
+	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+	Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+			      (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+    QdEventPtr		pending, *pendtail;
+    DeviceIntPtr	replayDev;	/* kludgy rock to put flag for */
+    WindowPtr		replayWin;	/*   ComputeFreezes            */
+    Bool		playingEvents;
+    TimeStamp		time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+typedef struct {
+    int		x, y;
+    ScreenPtr	pScreen;
+} HotSpot;
+
+static  struct {
+    CursorPtr	current;
+    BoxRec	hotLimits;	/* logical constraints of hot spot */
+    Bool	confined;	/* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+    RegionPtr	hotShape;	/* additional logical shape constraint */
+#endif
+    BoxRec	physLimits;	/* physical constraints of hot spot */
+    WindowPtr	win;		/* window of logical position */
+    HotSpot	hot;		/* logical pointer position */
+    HotSpot	hotPhys;	/* physical pointer position */
+#ifdef PANORAMIX
+    ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
+    RegionRec   Reg1;	        /* Region 1 for confining motion */
+    RegionRec   Reg2;		/* Region 2 for confining virtual motion */
+    WindowPtr   windows[MAXSCREENS];
+    WindowPtr	confineWin;	/* confine window */ 
+#endif
+} sprite;			/* info about the cursor sprite */
+
+static void DoEnterLeaveEvents(
+#if NeedFunctionPrototypes
+    WindowPtr /*fromWin*/,
+    WindowPtr /*toWin*/,
+    int /*mode*/
+#endif
+);
+
+static WindowPtr XYToWindow(
+#if NeedFunctionPrototypes
+    int /*x*/,
+    int /*y*/
+#endif
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+	NoSuchEvent,		       /* 0 */
+	NoSuchEvent,		       /* 1 */
+	KeyPressMask,		       /* KeyPress */
+	KeyReleaseMask,		       /* KeyRelease */
+	ButtonPressMask,	       /* ButtonPress */
+	ButtonReleaseMask,	       /* ButtonRelease */
+	PointerMotionMask,	       /* MotionNotify (initial state) */
+	EnterWindowMask,	       /* EnterNotify */
+	LeaveWindowMask,	       /* LeaveNotify */
+	FocusChangeMask,	       /* FocusIn */
+	FocusChangeMask,	       /* FocusOut */
+	KeymapStateMask,	       /* KeymapNotify */
+	ExposureMask,		       /* Expose */
+	CantBeFiltered,		       /* GraphicsExpose */
+	CantBeFiltered,		       /* NoExpose */
+	VisibilityChangeMask,	       /* VisibilityNotify */
+	SubstructureNotifyMask,	       /* CreateNotify */
+	StructureAndSubMask,	       /* DestroyNotify */
+	StructureAndSubMask,	       /* UnmapNotify */
+	StructureAndSubMask,	       /* MapNotify */
+	SubstructureRedirectMask,      /* MapRequest */
+	StructureAndSubMask,	       /* ReparentNotify */
+	StructureAndSubMask,	       /* ConfigureNotify */
+	SubstructureRedirectMask,      /* ConfigureRequest */
+	StructureAndSubMask,	       /* GravityNotify */
+	ResizeRedirectMask,	       /* ResizeRequest */
+	StructureAndSubMask,	       /* CirculateNotify */
+	SubstructureRedirectMask,      /* CirculateRequest */
+	PropertyChangeMask,	       /* PropertyNotify */
+	CantBeFiltered,		       /* SelectionClear */
+	CantBeFiltered,		       /* SelectionRequest */
+	CantBeFiltered,		       /* SelectionNotify */
+	ColormapChangeMask,	       /* ColormapNotify */
+	CantBeFiltered,		       /* ClientMessage */
+	CantBeFiltered		       /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+    0x7c				/* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+    int x, 
+    int y, 
+    Bool generateEvent
+){
+    ScreenPtr pScreen;
+    BoxRec box;
+    int i;
+
+    /* x,y are in Screen 0 coordinates.  We need to decide what Screen
+       to send the message too and what the coordinates relative to 
+       that screen are. */
+
+    pScreen = sprite.screen;
+    x += panoramiXdataPtr[0].x;
+    y += panoramiXdataPtr[0].y;
+
+    if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+								x, y, &box)) 
+    {
+	FOR_NSCREENS(i) 
+	{
+	    if(i == pScreen->myNum) 
+		continue;
+	    if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+	    {
+		pScreen = screenInfo.screens[i];
+		break;
+	    }
+	}
+    }
+
+    sprite.screen = pScreen;
+    sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+    sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+    x -= panoramiXdataPtr[pScreen->myNum].x;
+    y -= panoramiXdataPtr[pScreen->myNum].y;
+
+    return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+    ScreenPtr pScreen = sprite.screen;
+    BoxRec newBox = sprite.physLimits;
+
+    /* Translate the constraining box to the screen
+       the sprite is actually on */
+    newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+    newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+    (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents
+){
+    HotSpot new;
+
+    if (!cursor)
+	return;
+ 
+    new = sprite.hotPhys;
+
+    /* I don't care what the DDX has to say about it */
+    sprite.physLimits = sprite.hotLimits;
+
+    /* constrain the pointer to those limits */
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+
+    if (sprite.hotShape)  /* more work if the shape is a mess */
+	ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+    if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	XineramaSetCursorPosition (new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+
+    /* Tell DDX what the limits are */
+    XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+    if(pWin == WindowTable[0]) {
+	    memcpy(sprite.windows, WindowTable, 
+				PanoramiXNumScreens*sizeof(WindowPtr));
+    } else {
+	PanoramiXRes *win;
+	int i;
+
+	win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+	if(!win)
+	    return FALSE;
+
+	for(i = 0; i < PanoramiXNumScreens; i++) {
+	   sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+	   if(!sprite.windows[i])  /* window is being unmapped */
+		return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+   QdEventPtr qe,
+   WindowPtr pWin
+){
+
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;  /* should always be Screen 0 */
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	int x, y, off_x, off_y, i;
+	BoxRec lims;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+        if (sprite.hot.x < lims.x1)
+            sprite.hot.x = lims.x1;
+        else if (sprite.hot.x >= lims.x2)
+            sprite.hot.x = lims.x2 - 1;
+        if (sprite.hot.y < lims.y1)
+            sprite.hot.y = lims.y1;
+        else if (sprite.hot.y >= lims.y2)
+            sprite.hot.y = lims.y2 - 1;
+
+	if (REGION_NUM_RECTS(&sprite.Reg2) > 1) 
+	    ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	/* Motion events entering DIX get translated to Screen 0
+	   coordinates.  Replayed events have already been 
+	   translated since they've entered DIX before */
+	XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			  panoramiXdataPtr[0].x;
+	XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			  panoramiXdataPtr[0].y;
+
+	sprite.hot.x = XE_KBPTR.rootX;
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+
+	if (sprite.hotShape) 
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    XineramaSetCursorPosition(
+			sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+    if (syncEvents.playingEvents)
+    {
+	XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	int x, y, off_x, off_y, i;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+	if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+	   sprite.hotShape = &sprite.Reg1;
+	else
+	   sprite.hotShape = NullRegion;
+	
+	sprite.confined = FALSE;
+	sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+	XineramaCheckPhysLimits(sprite.current, generateEvents);
+    }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    XineramaCheckPhysLimits(cursor, FALSE);
+    	(*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+	sprite.current = cursor;
+    }
+}
+
+
+#endif  /* PANORAMIX */
+
+void
+SetMaskForEvent(mask, event)
+    Mask mask;
+    int event;
+{
+    if ((event < LASTEvent) || (event >= 128))
+	FatalError("SetMaskForEvent: bogus event number");
+    filters[event] = mask;
+}
+
+void
+SetCriticalEvent(event)
+    int event;
+{
+    if (event >= 128)
+	FatalError("SetCriticalEvent: bogus event number");
+    criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+#if NeedFunctionPrototypes
+SyntheticMotion(int x, int y)
+#else
+SyntheticMotion(x, y)
+    int x, y;
+#endif
+{
+    xEvent xE;
+
+#ifdef PANORAMIX
+    /* Translate back to the sprite screen since processInputProc
+       will translate from sprite screen to screen 0 upon reentry
+       to the DIX layer */
+    if(!noPanoramiXExtension) {
+	x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+	y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+    }
+#endif
+    xE.u.keyButtonPointer.rootX = x;
+    xE.u.keyButtonPointer.rootY = y;
+    if (syncEvents.playingEvents)
+	xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+    else
+	xE.u.keyButtonPointer.time = currentTime.milliseconds;
+    xE.u.u.type = MotionNotify;
+    (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+#if NeedFunctionPrototypes
+ConfineToShape(RegionPtr shape, int *px, int *py)
+#else
+ConfineToShape(shape, px, py)
+    RegionPtr shape;
+    int *px, *py;
+#endif
+{
+    BoxRec box;
+    int x = *px, y = *py;
+    int incx = 1, incy = 1;
+
+    if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+	return;
+    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+    /* this is rather crude */
+    do {
+	x += incx;
+	if (x >= box.x2)
+	{
+	    incx = -1;
+	    x = *px - 1;
+	}
+	else if (x < box.x1)
+	{
+	    incx = 1;
+	    x = *px;
+	    y += incy;
+	    if (y >= box.y2)
+	    {
+		incy = -1;
+		y = *py - 1;
+	    }
+	    else if (y < box.y1)
+		return; /* should never get here! */
+	}
+    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+    *px = x;
+    *py = y;
+}
+#endif
+
+static void
+#if NeedFunctionPrototypes
+CheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents,
+    Bool confineToScreen,
+    ScreenPtr pScreen)
+#else
+CheckPhysLimits(cursor, generateEvents, confineToScreen, pScreen)
+    CursorPtr cursor;
+    Bool generateEvents;
+    Bool confineToScreen;
+    ScreenPtr pScreen;
+#endif
+{
+    HotSpot new;
+
+    if (!cursor)
+	return;
+    new = sprite.hotPhys;
+    if (pScreen)
+	new.pScreen = pScreen;
+    else
+	pScreen = new.pScreen;
+    (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+			      &sprite.physLimits);
+    sprite.confined = confineToScreen;
+    (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &new.x, &new.y); 
+#endif
+    if ((pScreen != sprite.hotPhys.pScreen) ||
+	(new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	if (pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys = new;
+	(*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+CheckVirtualMotion(
+    register QdEventPtr qe,
+    register WindowPtr pWin)
+#else
+CheckVirtualMotion(qe, pWin)
+    register QdEventPtr qe;
+    register WindowPtr pWin;
+#endif
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaCheckVirtualMotion(qe, pWin);
+	return;
+    }
+#endif
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	BoxRec lims;
+
+	if (sprite.hot.pScreen != pWin->drawable.pScreen)
+	{
+	    sprite.hot.pScreen = pWin->drawable.pScreen;
+	    sprite.hot.x = sprite.hot.y = 0;
+	}
+	lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+	if (sprite.hot.x < lims.x1)
+	    sprite.hot.x = lims.x1;
+	else if (sprite.hot.x >= lims.x2)
+	    sprite.hot.x = lims.x2 - 1;
+	if (sprite.hot.y < lims.y1)
+	    sprite.hot.y = lims.y1;
+	else if (sprite.hot.y >= lims.y2)
+	    sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+	if (wBoundingShape(pWin))
+	    ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaConfineCursorToWindow(pWin, generateEvents);
+	return;
+    }	
+#endif
+
+    if (syncEvents.playingEvents)
+    {
+	CheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+	sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+					       : NullRegion;
+#endif
+	CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+			pScreen);
+    }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+    return sprite.confined;
+}
+
+static void
+#if NeedFunctionPrototypes
+ChangeToCursor(CursorPtr cursor)
+#else
+ChangeToCursor(cursor)
+    CursorPtr cursor;
+#endif
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaChangeToCursor(cursor);
+	return;
+    }
+#endif
+
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    CheckPhysLimits(cursor, FALSE, sprite.confined,
+			    (ScreenPtr)NULL);
+	(*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+						  cursor);
+	sprite.current = cursor;
+    }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(a, b)
+    register WindowPtr a, b;
+{
+    for (b = b->parent; b; b = b->parent)
+	if (b == a) return TRUE;
+    return FALSE;
+}
+
+static void
+#if NeedFunctionPrototypes
+PostNewCursor(void)
+#else
+PostNewCursor()
+#endif
+{
+    register    WindowPtr win;
+    register    GrabPtr grab = inputInfo.pointer->grab;
+
+    if (syncEvents.playingEvents)
+	return;
+    if (grab)
+    {
+	if (grab->cursor)
+	{
+	    ChangeToCursor(grab->cursor);
+	    return;
+	}
+	if (IsParent(grab->window, sprite.win))
+	    win = sprite.win;
+	else
+	    win = grab->window;
+    }
+    else
+	win = sprite.win;
+    for (; win; win = win->parent)
+	if (win->optional && win->optional->cursor != NullCursor)
+	{
+	    ChangeToCursor(win->optional->cursor);
+	    return;
+	}
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+    return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+    return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+    return sprite.current;
+}
+
+void
+GetSpritePosition(px, py)
+    int *px, *py;
+{
+    *px = sprite.hotPhys.x;
+    *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+    if(!noPanoramiXExtension) {
+	return sprite.screen->myNum;
+    } else {
+	return 0;
+    }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+#if NeedFunctionPrototypes
+MonthChangedOrBadTime(register xEvent *xE)
+#else
+MonthChangedOrBadTime(xE)
+    register xEvent *xE;
+#endif
+{
+    /* If the ddx/OS is careless about not processing timestamped events from
+     * different sources in sorted order, then it's possible for time to go
+     * backwards when it should not.  Here we ensure a decent time.
+     */
+    if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+	currentTime.months++;
+    else
+	XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+    if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+	MonthChangedOrBadTime(xE); \
+    currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+    lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(xE)
+    register xEvent *xE;
+{
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE);
+}
+
+/**************************************************************************
+ *            The following procedures deal with synchronous events       *
+ **************************************************************************/
+
+void
+EnqueueEvent(xE, device, count)
+    xEvent		*xE;
+    DeviceIntPtr	device;
+    int			count;
+{
+    register QdEventPtr tail = *syncEvents.pendtail;
+    register QdEventPtr qe;
+    xEvent		*qxE;
+
+    NoticeTime(xE);
+    if (DeviceEventCallback)
+    {
+	DeviceEventInfoRec eventinfo;
+	/*  The RECORD spec says that the root window field of motion events
+	 *  must be valid.  At this point, it hasn't been filled in yet, so
+	 *  we do it here.  The long expression below is necessary to get
+	 *  the current root window; the apparently reasonable alternative
+	 *  GetCurrentRootWindow()->drawable.id doesn't give you the right
+	 *  answer on the first motion event after a screen change because
+	 *  the data that GetCurrentRootWindow relies on hasn't been
+	 *  updated yet.
+	 */
+	if (xE->u.u.type == MotionNotify)
+	    XE_KBPTR.root =
+		WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	eventinfo.events = xE;
+	eventinfo.count = count;
+	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+    }
+    if (xE->u.u.type == MotionNotify)
+    {
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension) {
+	    XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			      panoramiXdataPtr[0].x;
+	    XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			      panoramiXdataPtr[0].y;
+	}
+#endif
+	sprite.hotPhys.x = XE_KBPTR.rootX;
+	sprite.hotPhys.y = XE_KBPTR.rootY;
+	/* do motion compression */
+	if (tail &&
+	    (tail->event->u.u.type == MotionNotify) &&
+	    (tail->pScreen == sprite.hotPhys.pScreen))
+	{
+	    tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+	    tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+	    tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+	    tail->months = currentTime.months;
+	    return;
+	}
+    }
+    qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+    if (!qe)
+	return;
+    qe->next = (QdEventPtr)NULL;
+    qe->device = device;
+    qe->pScreen = sprite.hotPhys.pScreen;
+    qe->months = currentTime.months;
+    qe->event = (xEvent *)(qe + 1);
+    qe->evcount = count;
+    for (qxE = qe->event; --count >= 0; qxE++, xE++)
+	*qxE = *xE;
+    if (tail)
+	syncEvents.pendtail = &tail->next;
+    *syncEvents.pendtail = qe;
+}
+
+static void
+#if NeedFunctionPrototypes
+PlayReleasedEvents(void)
+#else
+PlayReleasedEvents()
+#endif
+{
+    register QdEventPtr *prev, qe;
+    register DeviceIntPtr dev;
+
+    prev = &syncEvents.pending;
+    while ( (qe = *prev) )
+    {
+	if (!qe->device->sync.frozen)
+	{
+	    *prev = qe->next;
+	    if (*syncEvents.pendtail == *prev)
+		syncEvents.pendtail = prev;
+	    if (qe->event->u.u.type == MotionNotify)
+		CheckVirtualMotion(qe, NullWindow);
+	    syncEvents.time.months = qe->months;
+	    syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+	   /* Translate back to the sprite screen since processInputProc
+	      will translate from sprite screen to screen 0 upon reentry
+	      to the DIX layer */
+	    if(!noPanoramiXExtension) {
+		qe->event->u.keyButtonPointer.rootX += 
+			panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x;
+		qe->event->u.keyButtonPointer.rootY += 
+			panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y;
+	    }
+#endif
+	    (*qe->device->public.processInputProc)(qe->event, qe->device,
+						   qe->evcount);
+	    xfree(qe);
+	    for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+		;
+	    if (!dev)
+		break;
+	    /* Playing the event may have unfrozen another device. */
+	    /* So to play it safe, restart at the head of the queue */
+	    prev = &syncEvents.pending;
+	}
+	else
+	    prev = &qe->next;
+    } 
+}
+
+static void
+#if NeedFunctionPrototypes
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+#else
+FreezeThaw(dev, frozen)
+    register DeviceIntPtr dev;
+    Bool frozen;
+#endif
+{
+    dev->sync.frozen = frozen;
+    if (frozen)
+	dev->public.processInputProc = dev->public.enqueueInputProc;
+    else
+	dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+    register DeviceIntPtr replayDev = syncEvents.replayDev;
+    register int i;
+    WindowPtr w;
+    register xEvent *xE;
+    int count;
+    GrabPtr grab;
+    register DeviceIntPtr dev;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+	FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+    if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+	return;
+    syncEvents.playingEvents = TRUE;
+    if (replayDev)
+    {
+	xE = replayDev->sync.event;
+	count = replayDev->sync.evcount;
+	syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+	for (i = 0; i < spriteTraceGood; i++)
+	{
+	    if (syncEvents.replayWin == spriteTrace[i])
+	    {
+		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+		    if (replayDev->focus)
+			DeliverFocusedEvent(replayDev, xE, w, count);
+		    else
+			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+					        replayDev, count);
+		}
+		goto playmore;
+	    }
+	}
+	/* must not still be in the same stack */
+	if (replayDev->focus)
+	    DeliverFocusedEvent(replayDev, xE, w, count);
+	else
+	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+    }
+playmore:
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (!dev->sync.frozen)
+	{
+	    PlayReleasedEvents();
+	    break;
+	}
+    }
+    syncEvents.playingEvents = FALSE;
+    /* the following may have been skipped during replay, so do it now */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+    PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+    GrabPtr grab;
+
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(thisDev, thisMode, otherMode)
+    register DeviceIntPtr thisDev;
+    Bool thisMode, otherMode;
+{
+    register GrabPtr grab = thisDev->grab;
+    register DeviceIntPtr dev;
+
+    if (thisMode == GrabModeSync)
+	thisDev->sync.state = FROZEN_NO_EVENT;
+    else
+    {	/* free both if same client owns both */
+	thisDev->sync.state = THAWED;
+	if (thisDev->sync.other &&
+	    (CLIENT_BITS(thisDev->sync.other->resource) ==
+	     CLIENT_BITS(grab->resource)))
+	    thisDev->sync.other = NullGrab;
+    }
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev != thisDev)
+	{
+	    if (otherMode == GrabModeSync)
+		dev->sync.other = grab;
+	    else
+	    {	/* free both if same client owns both */
+		if (dev->sync.other &&
+		    (CLIENT_BITS(dev->sync.other->resource) ==
+		     CLIENT_BITS(grab->resource)))
+		    dev->sync.other = NullGrab;
+	    }
+	}
+    }
+    ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(mouse, grab, time, autoGrab)
+    register GrabPtr grab;
+    register DeviceIntPtr mouse;
+    TimeStamp time;
+    Bool autoGrab;
+{
+    WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+				     : sprite.win;
+
+    if (grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+    }
+    DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+    mouse->valuator->motionHintWindow = NullWindow;
+    if (syncEvents.playingEvents)
+	mouse->grabTime = syncEvents.time;
+    else
+	mouse->grabTime = time;
+    if (grab->cursor)
+	grab->cursor->refcnt++;
+    mouse->activeGrab = *grab;
+    mouse->grab = &mouse->activeGrab;
+    mouse->fromPassiveGrab = autoGrab;
+    PostNewCursor();
+    CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+}
+
+void
+DeactivatePointerGrab(mouse)
+    register DeviceIntPtr mouse;
+{
+    register GrabPtr grab = mouse->grab;
+    register DeviceIntPtr dev;
+
+    mouse->valuator->motionHintWindow = NullWindow;
+    mouse->grab = NullGrab;
+    mouse->sync.state = NOT_GRABBED;
+    mouse->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+    if (grab->confineTo)
+	ConfineCursorToWindow(ROOT, FALSE, FALSE);
+    PostNewCursor();
+    if (grab->cursor)
+	FreeCursor(grab->cursor, (Cursor)0);
+    ComputeFreezes();
+}
+
+void
+ActivateKeyboardGrab(keybd, grab, time, passive)
+    register DeviceIntPtr keybd;
+    GrabPtr grab;
+    TimeStamp time;
+    Bool passive;
+{
+    WindowPtr oldWin;
+
+    if (keybd->grab)
+	oldWin = keybd->grab->window;
+    else if (keybd->focus)
+	oldWin = keybd->focus->win;
+    else
+	oldWin = sprite.win;
+    if (oldWin == FollowKeyboardWin)
+	oldWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+    if (syncEvents.playingEvents)
+	keybd->grabTime = syncEvents.time;
+    else
+	keybd->grabTime = time;
+    keybd->activeGrab = *grab;
+    keybd->grab = &keybd->activeGrab;
+    keybd->fromPassiveGrab = passive;
+    CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(keybd)
+    register DeviceIntPtr keybd;
+{
+    register GrabPtr grab = keybd->grab;
+    register DeviceIntPtr dev;
+    register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+					       : sprite.win;
+
+    if (focusWin == FollowKeyboardWin)
+	focusWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    keybd->grab = NullGrab;
+    keybd->sync.state = NOT_GRABBED;
+    keybd->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+    ComputeFreezes();
+}
+
+void
+AllowSome(client, time, thisDev, newState)
+    ClientPtr		client;
+    TimeStamp		time;
+    register DeviceIntPtr thisDev;
+    int			newState;
+{
+    Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+    TimeStamp grabTime;
+    register DeviceIntPtr dev;
+
+    thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+    thisSynced = FALSE;
+    otherGrabbed = FALSE;
+    othersFrozen = TRUE;
+    grabTime = thisDev->grabTime;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev == thisDev)
+	    continue;
+	if (dev->grab && SameClient(dev->grab, client))
+	{
+	    if (!(thisGrabbed || otherGrabbed) ||
+		(CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+		grabTime = dev->grabTime;
+	    otherGrabbed = TRUE;
+	    if (thisDev->sync.other == dev->grab)
+		thisSynced = TRUE;
+	    if (dev->sync.state < FROZEN)
+		othersFrozen = FALSE;
+	}
+	else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+	    othersFrozen = FALSE;
+    }
+    if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+	return;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, grabTime) == EARLIER))
+	return;
+    switch (newState)
+    {
+	case THAWED:	 	       /* Async */
+	    if (thisGrabbed)
+		thisDev->sync.state = THAWED;
+	    if (thisSynced)
+		thisDev->sync.other = NullGrab;
+	    ComputeFreezes();
+	    break;
+	case FREEZE_NEXT_EVENT:		/* Sync */
+	    if (thisGrabbed)
+	    {
+		thisDev->sync.state = FREEZE_NEXT_EVENT;
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		ComputeFreezes();
+	    }
+	    break;
+	case THAWED_BOTH:		/* AsyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case FREEZE_BOTH_NEXT_EVENT:	/* SyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case NOT_GRABBED:		/* Replay */
+	    if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+	    {
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		syncEvents.replayDev = thisDev;
+		syncEvents.replayWin = thisDev->grab->window;
+		(*thisDev->DeactivateGrab)(thisDev);
+		syncEvents.replayDev = (DeviceIntPtr)NULL;
+	    }
+	    break;
+	case THAW_OTHERS:		/* AsyncOthers */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev == thisDev)
+			continue;
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+    }
+}
+
+int
+ProcAllowEvents(client)
+    register ClientPtr client;
+{
+    TimeStamp		time;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    REQUEST(xAllowEventsReq);
+
+    REQUEST_SIZE_MATCH(xAllowEventsReq);
+    time = ClientTimeToServerTime(stuff->time);
+    switch (stuff->mode)
+    {
+	case ReplayPointer:
+	    AllowSome(client, time, mouse, NOT_GRABBED);
+	    break;
+	case SyncPointer: 
+	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncPointer: 
+	    AllowSome(client, time, mouse, THAWED);
+	    break;
+	case ReplayKeyboard: 
+	    AllowSome(client, time, keybd, NOT_GRABBED);
+	    break;
+	case SyncKeyboard: 
+	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncKeyboard: 
+	    AllowSome(client, time, keybd, THAWED);
+	    break;
+	case SyncBoth:
+	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+	    break;
+	case AsyncBoth:
+	    AllowSome(client, time, keybd, THAWED_BOTH);
+	    break;
+	default: 
+	    client->errorValue = stuff->mode;
+	    return BadValue;
+    }
+    return Success;
+}
+
+void
+ReleaseActiveGrabs(client)
+    ClientPtr client;
+{
+    register DeviceIntPtr dev;
+    Bool    done;
+
+    /* XXX CloseDownClient should remove passive grabs before
+     * releasing active grabs.
+     */
+    do {
+    	done = TRUE;
+    	for (dev = inputInfo.devices; dev; dev = dev->next)
+    	{
+	    if (dev->grab && SameClient(dev->grab, client))
+	    {
+	    	(*dev->DeactivateGrab)(dev);
+	    	done = FALSE;
+	    }
+    	}
+    } while (!done);
+}
+
+/**************************************************************************
+ *            The following procedures deal with delivering events        *
+ **************************************************************************/
+
+int
+TryClientEvents (client, pEvents, count, mask, filter, grab)
+    ClientPtr client;
+    GrabPtr grab;
+    xEvent *pEvents;
+    int count;
+    Mask mask, filter;
+{
+    int i;
+    int type;
+
+#ifdef DEBUG
+    if (debug_events) ErrorF(
+	"Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+	((filter == CantBeFiltered) || (mask & filter)))
+    {
+	if (grab && !SameClient(grab, client))
+	    return -1; /* don't send, but notify caller */
+	type = pEvents->u.u.type;
+	if (type == MotionNotify)
+	{
+	    if (mask & PointerMotionHintMask)
+	    {
+		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+		    pEvents->u.keyButtonPointer.event)
+		{
+#ifdef DEBUG
+		    if (debug_events) ErrorF("\n");
+	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+		    return 1; /* don't send, but pretend we did */
+		}
+		pEvents->u.u.detail = NotifyHint;
+	    }
+	    else
+	    {
+		pEvents->u.u.detail = NotifyNormal;
+	    }
+	}
+#ifdef XINPUT
+	else
+	{
+	    if ((type == DeviceMotionNotify) &&
+		MaybeSendDeviceMotionNotifyHint
+			((deviceKeyButtonPointer*)pEvents, mask) != 0)
+		return 1;
+	}
+#endif
+	type &= 0177;
+	if (type != KeymapNotify)
+	{
+	    /* all extension events must have a sequence number */
+	    for (i = 0; i < count; i++)
+		pEvents[i].u.u.sequenceNumber = client->sequence;
+	}
+
+	if (BitIsOn(criticalEvents, type))
+	{
+#ifdef SMART_SCHEDULE
+	    if (client->smart_priority < SMART_MAX_PRIORITY)
+		client->smart_priority++;
+#endif
+	    SetCriticalOutputPending();
+	}
+
+	WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+	if (debug_events) ErrorF(  " delivered\n");
+#endif
+	return 1;
+    }
+    else
+    {
+#ifdef DEBUG
+	if (debug_events) ErrorF("\n");
+#endif
+	return 0;
+    }
+}
+
+int
+DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
+    register WindowPtr pWin;
+    GrabPtr grab;
+    xEvent *pEvents;
+    int count;
+    Mask filter;
+    int mskidx;
+{
+    int deliveries = 0, nondeliveries = 0;
+    int attempt;
+    register InputClients *other;
+    ClientPtr client = NullClient;
+    Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+		              this mask is the mask of the grab. */
+    int type = pEvents->u.u.type;
+
+    /* CantBeFiltered means only window owner gets the event */
+    if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+    {
+	/* if nobody ever wants to see this event, skip some work */
+	if (filter != CantBeFiltered &&
+	    !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+	    return 0;
+	if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+				      pWin->eventMask, filter, grab)) )
+	{
+	    if (attempt > 0)
+	    {
+		deliveries++;
+		client = wClient(pWin);
+		deliveryMask = pWin->eventMask;
+	    } else
+		nondeliveries--;
+	}
+    }
+    if (filter != CantBeFiltered)
+    {
+	if (type & EXTENSION_EVENT_BASE)
+	{
+	    OtherInputMasks *inputMasks;
+
+	    inputMasks = wOtherInputMasks(pWin);
+	    if (!inputMasks ||
+		!(inputMasks->inputEvents[mskidx] & filter))
+		return 0;
+	    other = inputMasks->inputClients;
+	}
+	else
+	    other = (InputClients *)wOtherClients(pWin);
+	for (; other; other = other->next)
+	{
+	    if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+					  other->mask[mskidx], filter, grab)) )
+	    {
+		if (attempt > 0)
+		{
+		    deliveries++;
+		    client = rClient(other);
+		    deliveryMask = other->mask[mskidx];
+		} else
+		    nondeliveries--;
+	    }
+	}
+    }
+    if ((type == ButtonPress) && deliveries && (!grab))
+    {
+	GrabRec tempGrab;
+
+	tempGrab.device = inputInfo.pointer;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.window = pWin;
+	tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+	tempGrab.eventMask = deliveryMask;
+	tempGrab.keyboardMode = GrabModeAsync;
+	tempGrab.pointerMode = GrabModeAsync;
+	tempGrab.confineTo = NullWindow;
+	tempGrab.cursor = NullCursor;
+	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+					   currentTime, TRUE);
+    }
+    else if ((type == MotionNotify) && deliveries)
+	inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+    else
+    {
+	if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
+	    deliveries)
+	    CheckDeviceGrabAndHintWindow (pWin, type,
+					  (deviceKeyButtonPointer*) pEvents,
+					  grab, client, deliveryMask);
+    }
+#endif
+    if (deliveries)
+	return deliveries;
+    return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0.  if
+   send works,  return 1 or if send didn't work, return 2.
+   Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int 
+XineramaTryClientEventsResult(
+    ClientPtr client,
+    GrabPtr grab,
+    Mask mask, 
+    Mask filter
+){
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+        ((filter == CantBeFiltered) || (mask & filter)))
+    {
+        if (grab && !SameClient(grab, client)) return -1;
+	else return 1;
+    }
+    return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
+    register WindowPtr pWin;
+    xEvent *pEvents;
+    int count;
+    Mask filter;
+    ClientPtr dontClient;
+{
+    register OtherClients *other;
+
+
+    if (pWin->eventMask & filter)
+    {
+        if (wClient(pWin) == dontClient)
+	    return 0;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	    return XineramaTryClientEventsResult(
+			wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+	return TryClientEvents(wClient(pWin), pEvents, count,
+			       pWin->eventMask, filter, NullGrab);
+    }
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->mask & filter)
+	{
+            if (SameClient(other, dontClient))
+		return 0;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	      return XineramaTryClientEventsResult(
+			rClient(other), NullGrab, other->mask, filter);
+#endif
+	    return TryClientEvents(rClient(other), pEvents, count,
+				   other->mask, filter, NullGrab);
+	}
+    }
+    return 2;
+}
+
+static void
+#if NeedFunctionPrototypes
+FixUpEventFromWindow(
+    xEvent *xE,
+    WindowPtr pWin,
+    Window child,
+    Bool calcChild)
+#else
+FixUpEventFromWindow(xE, pWin, child, calcChild)
+    xEvent *xE;
+    WindowPtr pWin;
+    Window child;
+    Bool calcChild;
+#endif
+{
+    if (calcChild)
+    {
+        WindowPtr w=spriteTrace[spriteTraceGood-1];
+	/* If the search ends up past the root should the child field be 
+	 	set to none or should the value in the argument be passed 
+		through. It probably doesn't matter since everyone calls 
+		this function with child == None anyway. */
+
+        while (w) 
+        {
+            /* If the source window is same as event window, child should be
+		none.  Don't bother going all all the way back to the root. */
+
+ 	    if (w == pWin)
+	    { 
+   		child = None;
+ 		break;
+	    }
+	    
+	    if (w->parent == pWin)
+	    {
+		child = w->drawable.id;
+		break;
+            }
+ 	    w = w->parent;
+        } 	    
+    }
+    XE_KBPTR.root = ROOT->drawable.id;
+    XE_KBPTR.event = pWin->drawable.id;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	XE_KBPTR.sameScreen = xTrue;
+	XE_KBPTR.child = child;
+	XE_KBPTR.eventX =
+	XE_KBPTR.rootX - pWin->drawable.x;
+	XE_KBPTR.eventY =
+	XE_KBPTR.rootY - pWin->drawable.y;
+    }
+    else
+    {
+	XE_KBPTR.sameScreen = xFalse;
+	XE_KBPTR.child = None;
+	XE_KBPTR.eventX = 0;
+	XE_KBPTR.eventY = 0;
+    }
+}
+
+int
+DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
+    register WindowPtr pWin, stopAt;
+    register xEvent *xE;
+    GrabPtr grab;
+    DeviceIntPtr dev;
+    int count;
+{
+    Window child = None;
+    int type = xE->u.u.type;
+    Mask filter = filters[type];
+    int deliveries = 0;
+
+    if (type & EXTENSION_EVENT_BASE)
+    {
+	register OtherInputMasks *inputMasks;
+	int mskidx = dev->id;
+
+	inputMasks = wOtherInputMasks(pWin);
+	if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+	    return 0;
+	while (pWin)
+	{
+	    if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, mskidx);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(inputMasks &&
+		 (filter & inputMasks->dontPropagateMask[mskidx])))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	    if (pWin)
+		inputMasks = wOtherInputMasks(pWin);
+	}
+    }
+    else
+    {
+	if (!(filter & pWin->deliverableEvents))
+	    return 0;
+	while (pWin)
+	{
+	    if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, 0);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(filter & wDontPropagateMask(pWin)))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	}
+    }
+    return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(pWin, xE, count, otherParent)
+    register WindowPtr pWin, otherParent;
+    register xEvent *xE;
+    int count;
+{
+    Mask filter;
+    int     deliveries;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+	return count;
+#endif
+
+    if (!count)
+	return 0;
+    filter = filters[xE->u.u.type];
+    if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+	xE->u.destroyNotify.event = pWin->drawable.id;
+    if (filter != StructureAndSubMask)
+	return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+    deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+				       NullGrab, 0);
+    if (pWin->parent)
+    {
+	xE->u.destroyNotify.event = pWin->parent->drawable.id;
+	deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+					    SubstructureNotifyMask, NullGrab,
+					    0);
+	if (xE->u.u.type == ReparentNotify)
+	{
+	    xE->u.destroyNotify.event = otherParent->drawable.id;
+	    deliveries += DeliverEventsToWindow(otherParent, xE, count,
+						SubstructureNotifyMask,
+						NullGrab, 0);
+	}
+    }
+    return deliveries;
+}
+
+
+static Bool 
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+	return TRUE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	   if(POINT_IN_REGION(sprite.screen, 
+			&sprite.windows[i]->borderSize, 
+			x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, 
+			y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, 
+			&box))
+		return TRUE;
+	}
+    }
+#endif
+    return FALSE;
+}
+
+static WindowPtr 
+#if NeedFunctionPrototypes
+XYToWindow(int x, int y)
+#else
+XYToWindow(x, y)
+	int x, y;
+#endif
+{
+    register WindowPtr  pWin;
+
+    spriteTraceGood = 1;	/* root window still there */
+    pWin = ROOT->firstChild;
+    while (pWin)
+    {
+	if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		    wBorderWidth(pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		    wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+#endif
+		)
+	{
+	    if (spriteTraceGood >= spriteTraceSize)
+	    {
+		spriteTraceSize += 10;
+		Must_have_memory = TRUE; /* XXX */
+		spriteTrace = (WindowPtr *)xrealloc(
+		    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    spriteTrace[spriteTraceGood++] = pWin;
+	    pWin = pWin->firstChild;
+	}
+	else
+	    pWin = pWin->nextSib;
+    }
+    return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+#if NeedFunctionPrototypes
+CheckMotion(xEvent *xE)
+#else
+CheckMotion(xE)
+    xEvent *xE;
+#endif
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaCheckMotion(xE);
+#endif
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+	{
+	    sprite.hot.pScreen = sprite.hotPhys.pScreen;
+	    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+	}
+	sprite.hot.x = XE_KBPTR.rootX;
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    (*sprite.hotPhys.pScreen->SetCursorPosition)(
+		sprite.hotPhys.pScreen,
+		sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+    if (!(sprite.win->deliverableEvents &
+	  Motion_Filter(inputInfo.pointer->button))
+	!syncEvents.playingEvents)
+    {
+	/* XXX Do PointerNonInterestBox here */
+    }
+#endif
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+    (void) CheckMotion((xEvent *)NULL);
+}
+
+void
+DefineInitialRootWindow(win)
+    register WindowPtr win;
+{
+    register ScreenPtr pScreen = win->drawable.pScreen;
+
+    sprite.hotPhys.pScreen = pScreen;
+    sprite.hotPhys.x = pScreen->width / 2;
+    sprite.hotPhys.y = pScreen->height / 2;
+    sprite.hot = sprite.hotPhys;
+    sprite.hotLimits.x2 = pScreen->width;
+    sprite.hotLimits.y2 = pScreen->height;
+    sprite.win = win;
+    sprite.current = wCursor (win);
+    spriteTraceGood = 1;
+    ROOT = win;
+    (*pScreen->CursorLimits) (
+	pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+    sprite.confined = FALSE;
+    (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+    (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+    (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+	sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+	sprite.hotLimits.x2 = PanoramiXPixWidth  - panoramiXdataPtr[0].x;
+	sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+	sprite.physLimits = sprite.hotLimits;
+	sprite.confineWin = NullWindow;
+	sprite.screen = pScreen;
+	/* gotta UNINIT these someplace */
+	REGION_INIT(pScreen, &sprite.Reg1, NullBox, 1);
+	REGION_INIT(pScreen, &sprite.Reg2, NullBox, 1);
+    }
+#endif
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+/*ARGSUSED*/
+void
+WindowHasNewCursor(pWin)
+    WindowPtr pWin;
+{
+    PostNewCursor();
+}
+
+void
+NewCurrentScreen(newScreen, x, y)
+    ScreenPtr newScreen;
+    int x,y;
+{
+    sprite.hotPhys.x = x;
+    sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - 
+			    panoramiXdataPtr[0].x;
+	sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - 
+			    panoramiXdataPtr[0].y;
+	if (newScreen != sprite.screen) {
+	    sprite.screen = newScreen;
+	    /* Make sure we tell the DDX to update its copy of the screen */
+	    if(sprite.confineWin)
+		XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+	    else
+		XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+	    /* if the pointer wasn't confined, the DDX won't get 
+	       told of the pointer warp so we reposition it here */
+	    if(!syncEvents.playingEvents)
+		(*sprite.screen->SetCursorPosition)(sprite.screen,
+		    sprite.hotPhys.x + panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x,
+		    sprite.hotPhys.y + panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+	}
+    } else 
+#endif
+    if (newScreen != sprite.hotPhys.pScreen)
+	ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+    WindowPtr pWin,
+    int x,
+    int y
+)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    BoxRec box;
+    int i, xoff, yoff;
+
+    if (!pWin->realized) return FALSE;
+
+    if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+        return TRUE;
+    
+    if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+    xoff = x + panoramiXdataPtr[0].x;  
+    yoff = y + panoramiXdataPtr[0].y;  
+
+    for(i = 1; i < PanoramiXNumScreens; i++) {
+	pWin = sprite.windows[i];
+	pScreen = pWin->drawable.pScreen;
+	x = xoff - panoramiXdataPtr[i].x;
+	y = yoff - panoramiXdataPtr[i].y;
+
+	if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+            return TRUE;
+
+    }
+
+    return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+
+    REQUEST(xWarpPointerReq);
+
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if(source == WindowTable[0]) {
+	    winX -= panoramiXdataPtr[0].x;
+	    winY -= panoramiXdataPtr[0].y;
+	}
+	if (x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !XineramaPointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	if(dest == WindowTable[0]) {
+	    x -= panoramiXdataPtr[0].x;
+	    y -= panoramiXdataPtr[0].y;
+	}
+    } 
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < sprite.physLimits.x1)
+	x = sprite.physLimits.x1;
+    else if (x >= sprite.physLimits.x2)
+	x = sprite.physLimits.x2 - 1;
+    if (y < sprite.physLimits.y1)
+	y = sprite.physLimits.y1;
+    else if (y >= sprite.physLimits.y2)
+	y = sprite.physLimits.y2 - 1;
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &x, &y);
+
+    XineramaSetCursorPosition(x, y, TRUE);
+
+    return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(client)
+    ClientPtr client;
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+    ScreenPtr	newScreen;
+
+    REQUEST(xWarpPointerReq);
+
+    REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaWarpPointer(client);
+#endif
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+	    x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !PointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) 
+    {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	newScreen = dest->drawable.pScreen;
+    } else 
+	newScreen = sprite.hotPhys.pScreen;
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < 0)
+	x = 0;
+    else if (x >= newScreen->width)
+	x = newScreen->width - 1;
+    if (y < 0)
+	y = 0;
+    else if (y >= newScreen->height)
+	y = newScreen->height - 1;
+
+    if (newScreen == sprite.hotPhys.pScreen)
+    {
+	if (x < sprite.physLimits.x1)
+	    x = sprite.physLimits.x1;
+	else if (x >= sprite.physLimits.x2)
+	    x = sprite.physLimits.x2 - 1;
+	if (y < sprite.physLimits.y1)
+	    y = sprite.physLimits.y1;
+	else if (y >= sprite.physLimits.y2)
+	    y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+	(*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+    }
+    else if (!PointerConfinedToScreen())
+    {
+	NewCurrentScreen(newScreen, x, y);
+    }
+    return Success;
+}
+
+static Bool 
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+     if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+	return TRUE;
+
+#ifdef PANORAMIX
+     if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	    if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+		return TRUE;
+	}
+     }
+#endif
+     return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+	passive grab set on the window to be activated. */
+
+static Bool
+#if NeedFunctionPrototypes
+CheckPassiveGrabsOnWindow(
+    WindowPtr pWin,
+    register DeviceIntPtr device,
+    register xEvent *xE,
+    int count)
+#else
+CheckPassiveGrabsOnWindow(pWin, device, xE, count)
+    WindowPtr pWin;
+    register DeviceIntPtr device;
+    register xEvent *xE;
+    int count;
+#endif
+{
+    register GrabPtr grab = wPassiveGrabs(pWin);
+    GrabRec tempGrab;
+    register xEvent *dxE;
+
+    if (!grab)
+	return FALSE;
+    tempGrab.window = pWin;
+    tempGrab.device = device;
+    tempGrab.type = xE->u.u.type;
+    tempGrab.detail.exact = xE->u.u.detail;
+    tempGrab.detail.pMask = NULL;
+    tempGrab.modifiersDetail.pMask = NULL;
+    for (; grab; grab = grab->next)
+    {
+#ifdef XKB
+	DeviceIntPtr	gdev;
+	XkbSrvInfoPtr	xkbi;
+
+	gdev= grab->modifierDevice;
+	xkbi= gdev->key->xkbInfo;
+#endif
+	tempGrab.modifierDevice = grab->modifierDevice;
+	if (device == grab->modifierDevice &&
+	    (xE->u.u.type == KeyPress
+#ifdef XINPUT
+	     || xE->u.u.type == DeviceKeyPress
+#endif
+	     ))
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->prev_state;
+#endif
+	else
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->state;
+#endif
+	if (GrabMatchesSecond(&tempGrab, grab) &&
+	    (!grab->confineTo ||
+	     (grab->confineTo->realized && 
+				BorderSizeNotEmpty(grab->confineTo))))
+	{
+#ifdef XCSECURITY
+	    if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+		return FALSE;
+#endif
+#ifdef XKB
+	    if (!noXkbExtension) {
+		XE_KBPTR.state &= 0x1f00;
+		XE_KBPTR.state |=
+				tempGrab.modifiersDetail.exact&(~0x1f00);
+	    }
+#endif
+	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+ 
+	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+	    (void) TryClientEvents(rClient(grab), xE, count,
+				   filters[xE->u.u.type],
+				   filters[xE->u.u.type],  grab);
+
+	    if (device->sync.state == FROZEN_NO_EVENT)
+	    {
+		if (device->sync.evcount < count)
+		{
+		    Must_have_memory = TRUE; /* XXX */
+		    device->sync.event = (xEvent *)xrealloc(device->sync.event,
+							    count*
+							    sizeof(xEvent));
+		    Must_have_memory = FALSE; /* XXX */
+		}
+		device->sync.evcount = count;
+		for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+		    *dxE = *xE;
+	    	device->sync.state = FROZEN_WITH_EVENT;
+            }	
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/*
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated.  If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated.  If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated.  If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(device, xE, checkFirst, count)
+    register DeviceIntPtr device;
+    register xEvent *xE;
+    int checkFirst;
+    int count;
+{
+    register int i;
+    register WindowPtr pWin = NULL;
+    register FocusClassPtr focus = device->focus;
+
+    if ((xE->u.u.type == ButtonPress
+#ifdef XINPUT
+	 || xE->u.u.type == DeviceButtonPress
+#endif
+	 ) && device->button->buttonsDown != 1)
+	return FALSE;
+
+    i = checkFirst;
+
+    if (focus)
+    {
+	for (; i < focus->traceGood; i++)
+	{
+	    pWin = focus->trace[i];
+	    if (pWin->optional &&
+		CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+		return TRUE;
+	}
+  
+	if ((focus->win == NoneWin) ||
+	    (i >= spriteTraceGood) ||
+	    ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+	    return FALSE;
+    }
+
+    for (; i < spriteTraceGood; i++)
+    {
+	pWin = spriteTrace[i];
+	if (pWin->optional &&
+	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+DeliverFocusedEvent(keybd, xE, window, count)
+    xEvent *xE;
+    DeviceIntPtr keybd;
+    WindowPtr window;
+    int count;
+{
+    WindowPtr focus = keybd->focus->win;
+    int mskidx = 0;
+
+    if (focus == FollowKeyboardWin)
+	focus = inputInfo.keyboard->focus->win;
+    if (!focus)
+	return;
+    if (focus == PointerRootWin)
+    {
+	DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+	return;
+    }
+    if ((focus == window) || IsParent(focus, window))
+    {
+	if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+	    return;
+    }
+    /* just deliver it to the focus window */
+    FixUpEventFromWindow(xE, focus, None, FALSE);
+    if (xE->u.u.type & EXTENSION_EVENT_BASE)
+	mskidx = keybd->id;
+    (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+				NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
+    register xEvent *xE;
+    register DeviceIntPtr thisDev;
+    Bool deactivateGrab;
+    int count;
+{
+    register GrabPtr grab = thisDev->grab;
+    int deliveries = 0;
+    register DeviceIntPtr dev;
+    register xEvent *dxE;
+
+    if (grab->ownerEvents)
+    {
+	WindowPtr focus;
+
+	if (thisDev->focus)
+	{
+	    focus = thisDev->focus->win;
+	    if (focus == FollowKeyboardWin)
+		focus = inputInfo.keyboard->focus->win;
+	}
+	else
+	    focus = PointerRootWin;
+	if (focus == PointerRootWin)
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+					     thisDev, count);
+	else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+					     thisDev, count);
+	else if (focus)
+	    deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+					     thisDev, count);
+    }
+    if (!deliveries)
+    {
+	FixUpEventFromWindow(xE, grab->window, None, TRUE);
+	deliveries = TryClientEvents(rClient(grab), xE, count,
+				     (Mask)grab->eventMask,
+				     filters[xE->u.u.type], grab);
+	if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+			   || xE->u.u.type == DeviceMotionNotify
+#endif
+			   ))
+	    thisDev->valuator->motionHintWindow = grab->window;
+    }
+    if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+					  && xE->u.u.type != DeviceMotionNotify
+#endif
+					  ))
+	switch (thisDev->sync.state)
+	{
+	case FREEZE_BOTH_NEXT_EVENT:
+	    for (dev = inputInfo.devices; dev; dev = dev->next)
+	    {
+		if (dev == thisDev)
+		    continue;
+		FreezeThaw(dev, TRUE);
+		if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+		    (CLIENT_BITS(dev->grab->resource) ==
+		     CLIENT_BITS(thisDev->grab->resource)))
+		    dev->sync.state = FROZEN_NO_EVENT;
+		else
+		    dev->sync.other = thisDev->grab;
+	    }
+	    /* fall through */
+	case FREEZE_NEXT_EVENT:
+	    thisDev->sync.state = FROZEN_WITH_EVENT;
+	    FreezeThaw(thisDev, TRUE);
+	    if (thisDev->sync.evcount < count)
+	    {
+		Must_have_memory = TRUE; /* XXX */
+		thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+							 count*sizeof(xEvent));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    thisDev->sync.evcount = count;
+	    for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+		*dxE = *xE;
+	    break;
+	}
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (xE, keybd, count)
+#else
+ProcessKeyboardEvent (xE, keybd, count)
+#endif
+    register xEvent *xE;
+    register DeviceIntPtr keybd;
+    int count;
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register int    i;
+    register CARD8  modifiers;
+    register CARD16 mask;
+    GrabPtr         grab = keybd->grab;
+    Bool            deactivateGrab = FALSE;
+    register KeyClassPtr keyc = keybd->key;
+
+    if (!syncEvents.playingEvents)
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+    XE_KBPTR.rootX = sprite.hot.x;
+    XE_KBPTR.rootY = sprite.hot.y;
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+    modifiers = keyc->modifierMap[key];
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    if (*kptr & bit) /* allow ddx to generate multiple downs */
+	    {   
+		if (!modifiers)
+		{
+		    xE->u.u.type = KeyRelease;
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		    xE->u.u.type = KeyPress;
+		    /* release can have side effects, don't fall through */
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		}
+		return;
+	    }
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr |= bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers)
+		{
+		    /* This key affects modifier "i" */
+		    keyc->modifierKeyCount[i]++;
+		    keyc->state |= mask;
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+	    {
+		keybd->activatingKey = key;
+		return;
+	    }
+	    break;
+	case KeyRelease: 
+	    if (!(*kptr & bit)) /* guard against duplicates */
+		return;
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr &= ~bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers) {
+		    /* This key affects modifier "i" */
+		    if (--keyc->modifierKeyCount[i] <= 0) {
+			keyc->state &= ~mask;
+			keyc->modifierKeyCount[i] = 0;
+		    }
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+    if (grab)
+	DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+    else
+	DeliverFocusedEvent(keybd, xE, sprite.win, count);
+    if (deactivateGrab)
+        (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+   this is only used when the pressing of keys does not cause 
+   CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (xE, keybd)
+    register xEvent *xE;
+    register DeviceIntPtr keybd;
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register KeyClassPtr keyc = keybd->key;
+
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("FixKeyState: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    *kptr |= bit;
+	    break;
+	case KeyRelease: 
+	    *kptr &= ~bit;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (xE, mouse, count)
+#else
+ProcessPointerEvent (xE, mouse, count)
+#endif
+    register xEvent 		*xE;
+    register DeviceIntPtr 	mouse;
+    int				count;
+{
+    register GrabPtr	grab = mouse->grab;
+    Bool                deactivateGrab = FALSE;
+    register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+    XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
+#endif
+
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE)
+    XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+			(noXkbExtension ?
+				inputInfo.keyboard->key->state :
+				xkbi->state.grab_mods)
+#else
+			inputInfo.keyboard->key->state
+#endif
+				    ));
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    /* see comment in EnqueueEvents regarding the next three lines */
+	    if (xE->u.u.type == MotionNotify)
+		XE_KBPTR.root =
+		    WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    if (xE->u.u.type != MotionNotify)
+    {
+	register int  key;
+	register BYTE *kptr;
+	int           bit;
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+
+	key = xE->u.u.detail;
+	kptr = &butc->down[key >> 3];
+	bit = 1 << (key & 7);
+	switch (xE->u.u.type)
+	{
+	case ButtonPress: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (!(*kptr & bit))
+		butc->buttonsDown++;
+	    butc->motionMask = ButtonMotionMask;
+	    *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!grab)
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		    return;
+	    break;
+	case ButtonRelease: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (*kptr & bit)
+		--butc->buttonsDown;
+	    if (!butc->buttonsDown)
+		butc->motionMask = 0;
+	    *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!butc->state && mouse->fromPassiveGrab)
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("bogus pointer event from ddx");
+	}
+    }
+    else if (!CheckMotion(xE))
+	return;
+    if (grab)
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    else
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    if (deactivateGrab)
+        (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+	(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+    register WindowPtr pWin;
+{
+    register OtherClients *others;
+    register WindowPtr pChild;
+
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->optional)
+	{
+	    pChild->optional->otherEventMasks = 0;
+	    for (others = wOtherClients(pChild); others; others = others->next)
+	    {
+		pChild->optional->otherEventMasks |= others->mask;
+	    }
+	}
+	pChild->deliverableEvents = pChild->eventMask|
+				    wOtherEventMasks(pChild);
+	if (pChild->parent)
+	    pChild->deliverableEvents |=
+		(pChild->parent->deliverableEvents &
+		 ~wDontPropagateMask(pChild) & PropagateMask);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+int
+OtherClientGone(value, id)
+    pointer value; /* must conform to DeleteType */
+    XID   id;
+{
+    register OtherClientsPtr other, prev;
+    register WindowPtr pWin = (WindowPtr)value;
+
+    prev = 0;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->resource == id)
+	{
+	    if (prev)
+		prev->next = other->next;
+	    else
+	    {
+		if (!(pWin->optional->otherClients = other->next))
+		    CheckWindowOptionalNeed (pWin);
+	    }
+	    xfree(other);
+	    RecalculateDeliverableEvents(pWin);
+	    return(Success);
+	}
+	prev = other;
+    }
+    FatalError("client not on event list");
+    /*NOTREACHED*/
+    return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(pWin, client, mask)
+    register WindowPtr pWin;
+    register ClientPtr client;
+    Mask mask;
+{
+    Mask check;
+    OtherClients * others;
+
+    if (mask & ~AllEventMasks)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    check = (mask & AtMostOneClient);
+    if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+    {				       /* It is illegal for two different
+				          clients to select on any of the
+				          events for AtMostOneClient. However,
+				          it is OK, for some client to
+				          continue selecting on one of those
+				          events.  */
+	if ((wClient(pWin) != client) && (check & pWin->eventMask))
+	    return BadAccess;
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (!SameClient(others, client) && (check & others->mask))
+		return BadAccess;
+	}
+    }
+    if (wClient (pWin) == client)
+    {
+	check = pWin->eventMask;
+#ifdef SGIMISC
+	pWin->eventMask =
+	    (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+	pWin->eventMask = mask;
+#endif
+    }
+    else
+    {
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (SameClient(others, client))
+	    {
+		check = others->mask;
+#ifdef SGIMISC
+		mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+		if (mask == 0)
+		{
+		    FreeResource(others->resource, RT_NONE);
+		    return Success;
+		}
+		else
+		    others->mask = mask;
+		goto maskSet;
+	    }
+	}
+	check = 0;
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return BadAlloc;
+	others = (OtherClients *) xalloc(sizeof(OtherClients));
+	if (!others)
+	    return BadAlloc;
+	others->mask = mask;
+	others->resource = FakeClientID(client->index);
+	others->next = pWin->optional->otherClients;
+	pWin->optional->otherClients = others;
+	if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+	    return BadAlloc;
+    }
+maskSet: 
+    if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+	(mask & PointerMotionHintMask) &&
+	!(check & PointerMotionHintMask) &&
+	!inputInfo.pointer->grab)
+	inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+/*ARGSUSED*/
+int
+EventSuppressForWindow(pWin, client, mask, checkOptional)
+    register WindowPtr pWin;
+    register ClientPtr client;
+    Mask mask;
+    Bool *checkOptional;
+{
+    register int i, free;
+
+    if ((mask & ~PropagateMask) && !permitOldBugs)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    if (pWin->dontPropagate)
+	DontPropagateRefCnts[pWin->dontPropagate]--;
+    if (!mask)
+	i = 0;
+    else
+    {
+	for (i = DNPMCOUNT, free = 0; --i > 0; )
+	{
+	    if (!DontPropagateRefCnts[i])
+		free = i;
+	    else if (mask == DontPropagateMasks[i])
+		break;
+	}
+	if (!i && free)
+	{
+	    i = free;
+	    DontPropagateMasks[i] = mask;
+	}
+    }
+    if (i || !mask)
+    {
+	pWin->dontPropagate = i;
+	if (i)
+	    DontPropagateRefCnts[i]++;
+	if (pWin->optional)
+	{
+	    pWin->optional->dontPropagateMask = mask;
+	    *checkOptional = TRUE;
+	}
+    }
+    else
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	{
+	    if (pWin->dontPropagate)
+		DontPropagateRefCnts[pWin->dontPropagate]++;
+	    return BadAlloc;
+	}
+	pWin->dontPropagate = 0;
+        pWin->optional->dontPropagateMask = mask;
+    }
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+static WindowPtr 
+#if NeedFunctionPrototypes
+CommonAncestor(
+    register WindowPtr a,
+    register WindowPtr b)
+#else
+CommonAncestor(a, b)
+    register WindowPtr a, b;
+#endif
+{
+    for (b = b->parent; b; b = b->parent)
+	if (IsParent(b, a)) return b;
+    return NullWindow;
+}
+
+static void
+#if NeedFunctionPrototypes
+EnterLeaveEvent(
+    int type,
+    int mode,
+    int detail,
+    register WindowPtr pWin,
+    Window child)
+#else
+EnterLeaveEvent(type, mode, detail, pWin, child)
+    int type, mode, detail;
+    register WindowPtr pWin;
+    Window child;
+#endif
+{
+    xEvent		event;
+    register DeviceIntPtr keybd = inputInfo.keyboard;
+    WindowPtr		focus;
+    register DeviceIntPtr mouse = inputInfo.pointer;
+    register GrabPtr	grab = mouse->grab;
+    Mask		mask;
+
+    if ((pWin == mouse->valuator->motionHintWindow) &&
+	(detail != NotifyInferior))
+	mouse->valuator->motionHintWindow = NullWindow;
+    if (grab)
+    {
+	mask = (pWin == grab->window) ? grab->eventMask : 0;
+	if (grab->ownerEvents)
+	    mask |= EventMaskForClient(pWin, rClient(grab));
+    }
+    else
+    {
+	mask = pWin->eventMask | wOtherEventMasks(pWin);
+    }
+    if (mask & filters[type])
+    {
+	event.u.u.type = type;
+	event.u.u.detail = detail;
+	event.u.enterLeave.time = currentTime.milliseconds;
+	event.u.enterLeave.rootX = sprite.hot.x;
+	event.u.enterLeave.rootY = sprite.hot.y;
+	/* Counts on the same initial structure of crossing & button events! */
+	FixUpEventFromWindow(&event, pWin, None, FALSE);
+	/* Enter/Leave events always set child */
+	event.u.enterLeave.child = child;
+	event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+					    ELFlagSameScreen : 0;
+#ifdef XKB
+	if (!noXkbExtension) {
+	    event.u.enterLeave.state = mouse->button->state & 0x1f00;
+	    event.u.enterLeave.state |= 
+			XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+	} else
+#endif
+	event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+	event.u.enterLeave.mode = mode;
+	focus = keybd->focus->win;
+	if ((focus != NoneWin) &&
+	    ((pWin == focus) || (focus == PointerRootWin) ||
+	     IsParent(focus, pWin)))
+	    event.u.enterLeave.flags |= ELFlagFocus;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), &event, 1, mask,
+				  filters[type], grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+					NullGrab, 0);
+    }
+    if ((type == EnterNotify) && (mask & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+
+#ifdef XCSECURITY
+	ClientPtr client = grab ? rClient(grab)
+				: clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+	ke.type = KeymapNotify;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+				  KeymapStateMask, grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+					KeymapStateMask, NullGrab, 0);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+#else
+EnterNotifies(ancestor, child, mode, detail)
+    WindowPtr ancestor, child;
+    int mode, detail;
+#endif
+{
+    WindowPtr	parent = child->parent;
+
+    if (ancestor == parent)
+	return;
+    EnterNotifies(ancestor, parent, mode, detail);
+    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+#if NeedFunctionPrototypes
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+#else
+LeaveNotifies(child, ancestor, mode, detail)
+    WindowPtr child, ancestor;
+    int detail, mode;
+#endif
+{
+    register WindowPtr  pWin;
+
+    if (ancestor == child)
+	return;
+    for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+    {
+	EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+	child = pWin;
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+#else
+DoEnterLeaveEvents(fromWin, toWin, mode)
+    WindowPtr fromWin, toWin;
+    int mode;
+#endif
+{
+    if (fromWin == toWin)
+	return;
+    if (IsParent(fromWin, toWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+	EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+    }
+    else if (IsParent(toWin, fromWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+	LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+    }
+    else
+    { /* neither fromWin nor toWin is descendent of the other */
+	WindowPtr common = CommonAncestor(toWin, fromWin);
+	/* common == NullWindow ==> different screens */
+	EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+	LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+	EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+#else
+FocusEvent(dev, type, mode, detail, pWin)
+    DeviceIntPtr dev;
+    int type, mode, detail;
+    register WindowPtr pWin;
+#endif
+{
+    xEvent event;
+
+#ifdef XINPUT
+    if (dev != inputInfo.keyboard)
+    {
+	DeviceFocusEvent(dev, type, mode, detail, pWin);
+	return;
+    }
+#endif
+    event.u.focus.mode = mode;
+    event.u.u.type = type;
+    event.u.u.detail = detail;
+    event.u.focus.window = pWin->drawable.id;
+    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+				0);
+    if ((type == FocusIn) &&
+	((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+#ifdef XCSECURITY
+	ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+	ke.type = KeymapNotify;
+	(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+				    KeymapStateMask, NullGrab, 0);
+    }
+}
+
+ /*
+  * recursive because it is easier
+  * no-op if child not descended from ancestor
+  */
+static Bool
+#if NeedFunctionPrototypes
+FocusInEvents(
+    DeviceIntPtr dev,
+    WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+    int mode, int detail,
+    Bool doAncestor)
+#else
+FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
+    DeviceIntPtr dev;
+    WindowPtr ancestor, child, skipChild;
+    int mode, detail;
+    Bool doAncestor;
+#endif
+{
+    if (child == NullWindow)
+	return ancestor == NullWindow;
+    if (ancestor == child)
+    {
+	if (doAncestor)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+		      doAncestor))
+    {
+	if (child != skipChild)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+#if NeedFunctionPrototypes
+FocusOutEvents(
+    DeviceIntPtr dev,
+    WindowPtr child, WindowPtr ancestor,
+    int mode, int detail,
+    Bool doAncestor)
+#else
+FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
+    DeviceIntPtr dev;
+    WindowPtr child, ancestor;
+    int mode;
+    int detail;
+    Bool doAncestor;
+#endif
+{
+    register WindowPtr  pWin;
+
+    for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+	FocusEvent(dev, FocusOut, mode, detail, pWin);
+    if (doAncestor)
+	FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(dev, fromWin, toWin, mode)
+    DeviceIntPtr dev;
+    WindowPtr fromWin, toWin;
+    int mode;
+{
+    int     out, in;		       /* for holding details for to/from
+				          PointerRoot/None */
+    int     i;
+
+    if (fromWin == toWin)
+	return;
+    out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+    in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+    if ((toWin == NullWindow) || (toWin == PointerRootWin))
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+   	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+	    /* Notify all the roots */
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	}
+	else
+	{
+	    if (IsParent(fromWin, sprite.win))
+	      FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+			     FALSE);
+	    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+	    /* next call catches the root too, if the screen changed */
+	    FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+			   NotifyNonlinearVirtual, FALSE);
+	}
+	/* Notify all the roots */
+#ifdef PANORAMIX
+	if ( !noPanoramiXExtension )
+	    FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+	else 
+#endif
+	    for (i=0; i<screenInfo.numScreens; i++)
+	        FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+	if (toWin == PointerRootWin)
+	    (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+				NotifyPointer, TRUE);
+    }
+    else
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	    if (toWin->parent != NullWindow)
+	      (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+				  NotifyNonlinearVirtual, TRUE);
+	    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+	    if (IsParent(toWin, sprite.win))
+    	       (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+				   NotifyPointer, FALSE);
+	}
+	else
+	{
+	    if (IsParent(toWin, fromWin))
+	    {
+		FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+		FocusOutEvents(dev, fromWin->parent, toWin, mode,
+			       NotifyVirtual, FALSE);
+		FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+		if ((IsParent(toWin, sprite.win)) &&
+			(sprite.win != fromWin) &&
+			(!IsParent(fromWin, sprite.win)) &&
+			(!IsParent(sprite.win, fromWin)))
+		    (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					mode, NotifyPointer, FALSE);
+	    }
+	    else
+		if (IsParent(fromWin, toWin))
+		{
+		    if ((IsParent(fromWin, sprite.win)) &&
+			    (sprite.win != fromWin) &&
+			    (!IsParent(toWin, sprite.win)) &&
+			    (!IsParent(sprite.win, toWin)))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+		    (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+					NotifyVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+		}
+		else
+		{
+		/* neither fromWin or toWin is child of other */
+		    WindowPtr common = CommonAncestor(toWin, fromWin);
+		/* common == NullWindow ==> different screens */
+		    if (IsParent(fromWin, sprite.win))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+		    if (fromWin->parent != NullWindow)
+		      FocusOutEvents(dev, fromWin->parent, common, mode,
+				     NotifyNonlinearVirtual, FALSE);
+		    if (toWin->parent != NullWindow)
+		      (void)FocusInEvents(dev, common, toWin, toWin, mode,
+					  NotifyNonlinearVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+		    if (IsParent(toWin, sprite.win))
+			(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					    mode, NotifyPointer, FALSE);
+		}
+	}
+    }
+}
+
+int
+#if NeedFunctionPrototypes
+SetInputFocus(
+    ClientPtr client,
+    DeviceIntPtr dev,
+    Window focusID,
+    CARD8 revertTo,
+    Time ctime,
+    Bool followOK)
+#else
+SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
+    ClientPtr client;
+    DeviceIntPtr dev;
+    Window focusID;
+    CARD8 revertTo;
+    Time ctime;
+    Bool followOK;
+#endif
+{
+    register FocusClassPtr focus;
+    register WindowPtr focusWin;
+    int mode;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((revertTo != RevertToParent) &&
+	(revertTo != RevertToPointerRoot) &&
+	(revertTo != RevertToNone) &&
+	((revertTo != RevertToFollowKeyboard) || !followOK))
+    {
+	client->errorValue = revertTo;
+	return BadValue;
+    }
+    time = ClientTimeToServerTime(ctime);
+    if ((focusID == None) || (focusID == PointerRoot))
+	focusWin = (WindowPtr)(long)focusID;
+    else if ((focusID == FollowKeyboard) && followOK)
+	focusWin = inputInfo.keyboard->focus->win;
+    else if (!(focusWin = SecurityLookupWindow(focusID, client,
+					       SecurityReadAccess)))
+	return BadWindow;
+    else
+    {
+ 	/* It is a match error to try to set the input focus to an 
+	unviewable window. */
+
+	if(!focusWin->realized)
+	    return(BadMatch);
+    }
+    focus = dev->focus;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, focus->time) == EARLIER))
+	return Success;
+    mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+    if (focus->win == FollowKeyboardWin)
+	DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+    else
+	DoFocusEvents(dev, focus->win, focusWin, mode);
+    focus->time = time;
+    focus->revert = revertTo;
+    if (focusID == FollowKeyboard)
+	focus->win = FollowKeyboardWin;
+    else
+	focus->win = focusWin;
+    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+	focus->traceGood = 0;
+    else
+    {
+        int depth = 0;
+	register WindowPtr pWin;
+
+        for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+        if (depth > focus->traceSize)
+        {
+	    focus->traceSize = depth+1;
+	    Must_have_memory = TRUE; /* XXX */
+	    focus->trace = (WindowPtr *)xrealloc(focus->trace,
+						 focus->traceSize *
+						 sizeof(WindowPtr));
+	    Must_have_memory = FALSE; /* XXX */
+	}
+	focus->traceGood = depth;
+        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
+	    focus->trace[depth] = pWin;
+    }
+    return Success;
+}
+
+int
+ProcSetInputFocus(client)
+    ClientPtr client;
+{
+    REQUEST(xSetInputFocusReq);
+
+    REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+	return Success;
+#endif
+    return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+			 stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(client)
+    ClientPtr client;
+{
+    xGetInputFocusReply rep;
+    /* REQUEST(xReq); */
+    FocusClassPtr focus = inputInfo.keyboard->focus;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (focus->win == NoneWin)
+	rep.focus = None;
+    else if (focus->win == PointerRootWin)
+	rep.focus = PointerRoot;
+    else rep.focus = focus->win->drawable.id;
+    rep.revertTo = focus->revert;
+    WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+    return Success;
+}
+
+int
+ProcGrabPointer(client)
+    ClientPtr client;
+{
+    xGrabPointerReply rep;
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    WindowPtr pWin, confineTo;
+    CursorPtr cursor, oldCursor;
+    REQUEST(xGrabPointerReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xGrabPointerReq);
+    UpdateCurrentTime();
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+        return BadValue;
+    }
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+	confineTo = NullWindow;
+    else 
+    {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+	/* at this point, some sort of reply is guaranteed. */
+    time = ClientTimeToServerTime(stuff->time);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    grab = device->grab;
+    if ((grab) && !SameClient(grab, client))
+	rep.status = AlreadyGrabbed;
+    else if ((!pWin->realized) ||
+             (confineTo &&
+                !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+	rep.status = GrabNotViewable;
+    else if (device->sync.frozen &&
+	     device->sync.other && !SameClient(device->sync.other, client))
+	rep.status = GrabFrozen;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	rep.status = GrabInvalidTime;
+    else
+    {
+	GrabRec tempGrab;
+
+	oldCursor = NullCursor;
+	if (grab)
+ 	{
+	    if (grab->confineTo && !confineTo)
+		ConfineCursorToWindow(ROOT, FALSE, FALSE);
+	    oldCursor = grab->cursor;
+	}
+	tempGrab.cursor = cursor;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = stuff->ownerEvents;
+	tempGrab.eventMask = stuff->eventMask;
+	tempGrab.confineTo = confineTo;
+	tempGrab.window = pWin;
+	tempGrab.keyboardMode = stuff->keyboardMode;
+	tempGrab.pointerMode = stuff->pointerMode;
+	tempGrab.device = device;
+	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+	if (oldCursor)
+	    FreeCursor (oldCursor, (Cursor)0);
+	rep.status = GrabSuccess;
+    }
+    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+    return Success;
+}
+
+int
+ProcChangeActivePointerGrab(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    register GrabPtr grab = device->grab;
+    CursorPtr newCursor, oldCursor;
+    REQUEST(xChangeActivePointerGrabReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    if (stuff->cursor == None)
+	newCursor = NullCursor;
+    else
+    {
+	newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!newCursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+    if (!grab)
+	return Success;
+    if (!SameClient(grab, client))
+	return Success;
+    time = ClientTimeToServerTime(stuff->time);
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	return Success;
+    oldCursor = grab->cursor;
+    grab->cursor = newCursor;
+    if (newCursor)
+	newCursor->refcnt++;
+    PostNewCursor();
+    if (oldCursor)
+	FreeCursor(oldCursor, (Cursor)0);
+    grab->eventMask = stuff->eventMask;
+    return Success;
+}
+
+int
+ProcUngrabPointer(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	    (grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
+	   mask, status)
+    register ClientPtr client;
+    register DeviceIntPtr dev;
+    unsigned this_mode;
+    unsigned other_mode;
+    Window grabWindow;
+    unsigned ownerEvents;
+    Time ctime;
+    Mask mask;
+    CARD8 *status;
+{
+    register WindowPtr pWin;
+    register GrabPtr grab;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+    {
+	client->errorValue = this_mode;
+        return BadValue;
+    }
+    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+    {
+	client->errorValue = other_mode;
+        return BadValue;
+    }
+    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+    {
+	client->errorValue = ownerEvents;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    time = ClientTimeToServerTime(ctime);
+    grab = dev->grab;
+    if (grab && !SameClient(grab, client))
+	*status = AlreadyGrabbed;
+    else if (!pWin->realized)
+	*status = GrabNotViewable;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+	*status = GrabInvalidTime;
+    else if (dev->sync.frozen &&
+	     dev->sync.other && !SameClient(dev->sync.other, client))
+	*status = GrabFrozen;
+    else
+    {
+	GrabRec tempGrab;
+
+	tempGrab.window = pWin;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = ownerEvents;
+	tempGrab.keyboardMode = this_mode;
+	tempGrab.pointerMode = other_mode;
+	tempGrab.eventMask = mask;
+	tempGrab.device = dev;
+	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+	*status = GrabSuccess;
+    }
+    return Success;
+}
+
+int
+ProcGrabKeyboard(client)
+    ClientPtr client;
+{
+    xGrabKeyboardReply rep;
+    REQUEST(xGrabKeyboardReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+    {
+	result = Success;
+	rep.status = AlreadyGrabbed;
+    }
+    else
+#endif
+    result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+			stuff->pointerMode, stuff->grabWindow,
+			stuff->ownerEvents, stuff->time,
+			KeyPressMask | KeyReleaseMask, &rep.status);
+    if (result != Success)
+	return result;
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+    return Success;
+}
+
+int
+ProcUngrabKeyboard(client)
+    ClientPtr client;
+{
+    DeviceIntPtr device = inputInfo.keyboard;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	(grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+ProcQueryPointer(client)
+    ClientPtr client;
+{
+    xQueryPointerReply rep;
+    WindowPtr pWin, t;
+    REQUEST(xResourceReq);
+    DeviceIntPtr mouse = inputInfo.pointer;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (mouse->valuator->motionHintWindow)
+	MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+    rep.length = 0;
+    rep.root = (ROOT)->drawable.id;
+    rep.rootX = sprite.hot.x;
+    rep.rootY = sprite.hot.y;
+    rep.child = None;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	rep.sameScreen = xTrue;
+	rep.winX = sprite.hot.x - pWin->drawable.x;
+	rep.winY = sprite.hot.y - pWin->drawable.y;
+	for (t = sprite.win; t; t = t->parent)
+	    if (t->parent == pWin)
+	    {
+		rep.child = t->drawable.id;
+		break;
+	    }
+    }
+    else
+    {
+	rep.sameScreen = xFalse;
+	rep.winX = 0;
+	rep.winY = 0;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	rep.rootX += panoramiXdataPtr[0].x;
+	rep.rootY += panoramiXdataPtr[0].y;
+	if(stuff->id == rep.root) {
+	    rep.winX += panoramiXdataPtr[0].x;
+	    rep.winY += panoramiXdataPtr[0].y;
+	}
+    }
+#endif
+
+    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+    return(Success);    
+}
+
+void
+InitEvents()
+{
+    int i;
+
+    sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+    inputInfo.numDevices = 0;
+    inputInfo.devices = (DeviceIntPtr)NULL;
+    inputInfo.off_devices = (DeviceIntPtr)NULL;
+    inputInfo.keyboard = (DeviceIntPtr)NULL;
+    inputInfo.pointer = (DeviceIntPtr)NULL;
+    if (spriteTraceSize == 0)
+    {
+	spriteTraceSize = 32;
+	spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+	if (!spriteTrace)
+	    FatalError("failed to allocate spriteTrace");
+    }
+    spriteTraceGood = 0;
+    lastEventMask = OwnerGrabButtonMask;
+    filters[MotionNotify] = PointerMotionMask;
+    sprite.win = NullWindow;
+    sprite.current = NullCursor;
+    sprite.hotLimits.x1 = 0;
+    sprite.hotLimits.y1 = 0;
+    sprite.hotLimits.x2 = 0;
+    sprite.hotLimits.y2 = 0;
+    sprite.confined = FALSE;
+    syncEvents.replayDev = (DeviceIntPtr)NULL;
+    syncEvents.replayWin = NullWindow;
+    while (syncEvents.pending)
+    {
+	QdEventPtr next = syncEvents.pending->next;
+	xfree(syncEvents.pending);
+	syncEvents.pending = next;
+    }
+    syncEvents.pendtail = &syncEvents.pending;
+    syncEvents.playingEvents = FALSE;
+    syncEvents.time.months = 0;
+    syncEvents.time.milliseconds = 0;	/* hardly matters */
+    currentTime.months = 0;
+    currentTime.milliseconds = GetTimeInMillis();
+    lastDeviceEventTime = currentTime;
+    for (i = 0; i < DNPMCOUNT; i++)
+    {
+	DontPropagateMasks[i] = 0;
+	DontPropagateRefCnts[i] = 0;
+    }
+}
+
+void
+CloseDownEvents(void)
+{
+  xfree(spriteTrace);
+  spriteTrace = NULL;
+  spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(client)
+    ClientPtr client;
+{
+    WindowPtr pWin;
+    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+    REQUEST(xSendEventReq);
+
+    REQUEST_SIZE_MATCH(xSendEventReq);
+
+    /* The client's event type must be a core event type or one defined by an
+	extension. */
+
+    if ( ! ((stuff->event.u.u.type > X_Reply &&
+	     stuff->event.u.u.type < LASTEvent) || 
+	    (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+	     stuff->event.u.u.type < (unsigned)lastEvent)))
+    {
+	client->errorValue = stuff->event.u.u.type;
+	return BadValue;
+    }
+    if (stuff->event.u.u.type == ClientMessage &&
+	stuff->event.u.u.detail != 8 &&
+	stuff->event.u.u.detail != 16 &&
+	stuff->event.u.u.detail != 32 &&
+	!permitOldBugs)
+    {
+	client->errorValue = stuff->event.u.u.detail;
+	return BadValue;
+    }
+    if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+	return BadValue;
+    }
+
+    if (stuff->destination == PointerWindow)
+	pWin = sprite.win;
+    else if (stuff->destination == InputFocus)
+    {
+	WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+	if (inputFocus == NoneWin)
+	    return Success;
+
+	/* If the input focus is PointerRootWin, send the event to where
+	the pointer is if possible, then perhaps propogate up to root. */
+   	if (inputFocus == PointerRootWin)
+	    inputFocus = ROOT;
+
+	if (IsParent(inputFocus, sprite.win))
+	{
+	    effectiveFocus = inputFocus;
+	    pWin = sprite.win;
+	}
+	else
+	    effectiveFocus = pWin = inputFocus;
+    }
+    else
+	pWin = SecurityLookupWindow(stuff->destination, client,
+				    SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+    {
+	client->errorValue = stuff->propagate;
+	return BadValue;
+    }
+    stuff->event.u.u.type |= 0x80;
+    if (stuff->propagate)
+    {
+	for (;pWin; pWin = pWin->parent)
+	{
+	    if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				      NullGrab, 0))
+		return Success;
+	    if (pWin == effectiveFocus)
+		return Success;
+	    stuff->eventMask &= ~wDontPropagateMask(pWin);
+	    if (!stuff->eventMask)
+		break;
+	}
+    }
+    else
+	(void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				    NullGrab, 0);
+    return Success;
+}
+
+int
+ProcUngrabKey(client)
+    ClientPtr client;
+{
+    REQUEST(xUngrabKeyReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xUngrabKeyReq);
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = keybd;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = KeyPress;
+    tempGrab.detail.exact = stuff->key;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+int
+ProcGrabKey(client)
+    ClientPtr client;
+{
+    WindowPtr pWin;
+    REQUEST(xGrabKeyReq);
+    GrabPtr grab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xGrabKeyReq);
+    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return(BadValue);
+    }
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    grab = CreateGrab(client->index, keybd, pWin, 
+	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+	keybd, stuff->modifiers, KeyPress, stuff->key, 
+	NullWindow, NullCursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(client)
+    ClientPtr client;
+{
+    WindowPtr pWin, confineTo;
+    REQUEST(xGrabButtonReq);
+    CursorPtr cursor;
+    GrabPtr grab;
+
+    REQUEST_SIZE_MATCH(xGrabButtonReq);
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return BadValue;
+    }
+    if (stuff->eventMask & ~PointerGrabMask)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+       confineTo = NullWindow;
+    else {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+
+
+    grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
+    permitOldBugs ? (Mask)(stuff->eventMask |
+			       ButtonPressMask | ButtonReleaseMask) :
+			(Mask)stuff->eventMask,
+	(Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+	(Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+	ButtonPress, stuff->button, confineTo, cursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(client)
+    ClientPtr client;
+{
+    REQUEST(xUngrabButtonReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+
+    REQUEST_SIZE_MATCH(xUngrabButtonReq);
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = inputInfo.pointer;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = ButtonPress;
+    tempGrab.detail.exact = stuff->button;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(pWin, freeResources)
+    WindowPtr		pWin;
+    Bool		freeResources;
+{
+    WindowPtr		parent;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    FocusClassPtr	focus = keybd->focus;
+    OtherClientsPtr	oc;
+    GrabPtr		passive;
+
+
+    /* Deactivate any grabs performed on this window, before making any
+	input focus changes. */
+
+    if (mouse->grab &&
+	((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+	(*mouse->DeactivateGrab)(mouse);
+
+    /* Deactivating a keyboard grab should cause focus events. */
+
+    if (keybd->grab && (keybd->grab->window == pWin))
+	(*keybd->DeactivateGrab)(keybd);
+
+    /* If the focus window is a root window (ie. has no parent) then don't 
+	delete the focus from it. */
+    
+    if ((pWin == focus->win) && (pWin->parent != NullWindow))
+    {
+	int focusEventMode = NotifyNormal;
+
+ 	/* If a grab is in progress, then alter the mode of focus events. */
+
+	if (keybd->grab)
+	    focusEventMode = NotifyWhileGrabbed;
+
+	switch (focus->revert)
+	{
+	case RevertToNone:
+	    DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+	    focus->win = NoneWin;
+	    focus->traceGood = 0;
+	    break;
+	case RevertToParent:
+	    parent = pWin;
+	    do
+	    {
+		parent = parent->parent;
+		focus->traceGood--;
+	    } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+   during SaveSet processing would cause the focus to revert to the
+   nearest enclosing window which will survive the death of the exiting
+   client, instead of ending up reverting to a dying window and thence
+   to None
+ */
+#ifdef NOTDEF
+ 	      || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+		);
+	    DoFocusEvents(keybd, pWin, parent, focusEventMode);
+	    focus->win = parent;
+	    focus->revert = RevertToNone;
+	    break;
+	case RevertToPointerRoot:
+	    DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+	    focus->win = PointerRootWin;
+	    focus->traceGood = 0;
+	    break;
+	}
+    }
+
+    if (mouse->valuator->motionHintWindow == pWin)
+	mouse->valuator->motionHintWindow = NullWindow;
+
+    if (freeResources)
+    {
+	if (pWin->dontPropagate)
+	    DontPropagateRefCnts[pWin->dontPropagate]--;
+	while ( (oc = wOtherClients(pWin)) )
+	    FreeResource(oc->resource, RT_NONE);
+	while ( (passive = wPassiveGrabs(pWin)) )
+	    FreeResource(passive->resource, RT_NONE);
+     }
+#ifdef XINPUT
+    DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/* Call this whenever some window at or below pWin has changed geometry */
+
+/*ARGSUSED*/
+void
+CheckCursorConfinement(pWin)
+    WindowPtr pWin;
+{
+    GrabPtr grab = inputInfo.pointer->grab;
+    WindowPtr confineTo;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+    if (grab && (confineTo = grab->confineTo))
+    {
+	if (!BorderSizeNotEmpty(confineTo))
+	    (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+	else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+	    ConfineCursorToWindow(confineTo, TRUE, TRUE);
+    }
+}
+
+Mask
+EventMaskForClient(pWin, client)
+    WindowPtr		pWin;
+    ClientPtr		client;
+{
+    register OtherClientsPtr	other;
+
+    if (wClient (pWin) == client)
+	return pWin->eventMask;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (SameClient(other, client))
+	    return other->mask;
+    }
+    return 0;
+}
+
+int
+ProcRecolorCursor(client)
+    ClientPtr client;
+{
+    CursorPtr pCursor;
+    int		nscr;
+    ScreenPtr	pscr;
+    Bool 	displayed;
+    REQUEST(xRecolorCursorReq);
+
+    REQUEST_SIZE_MATCH(xRecolorCursorReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+					RT_CURSOR, SecurityWriteAccess);
+    if ( !pCursor) 
+    {
+	client->errorValue = stuff->cursor;
+	return (BadCursor);
+    }
+
+    pCursor->foreRed = stuff->foreRed;
+    pCursor->foreGreen = stuff->foreGreen;
+    pCursor->foreBlue = stuff->foreBlue;
+
+    pCursor->backRed = stuff->backRed;
+    pCursor->backGreen = stuff->backGreen;
+    pCursor->backBlue = stuff->backBlue;
+
+    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+    {
+	pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension)
+	    displayed = (pscr == sprite.screen);
+	else
+#endif
+	    displayed = (pscr == sprite.hotPhys.pScreen);
+	( *pscr->RecolorCursor)(pscr, pCursor,
+				(pCursor == sprite.current) && displayed);
+    }
+    return (Success);
+}
+
+void
+WriteEventsToClient(pClient, count, events)
+    ClientPtr	pClient;
+    int		count;
+    xEvent	*events;
+{
+#ifdef PANORAMIX
+    xEvent    eventCopy;
+#endif
+    xEvent    eventTo, *eventFrom;
+    int       i;
+
+#ifdef XKB
+    if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+	return;
+#endif
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && 
+       (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 
+    {
+	switch(events->u.u.type) {
+	case MotionNotify:
+	case ButtonPress:
+	case ButtonRelease:
+	case KeyPress:
+	case KeyRelease:
+	case EnterNotify:
+	case LeaveNotify:
+	/* 
+	   When multiple clients want the same event DeliverEventsToWindow
+	   passes the same event structure multiple times so we can't 
+	   modify the one passed to us 
+        */
+	    count = 1;  /* should always be 1 */
+	    memcpy(&eventCopy, events, sizeof(xEvent));
+	    eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+	    eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+	    if(eventCopy.u.keyButtonPointer.event == 
+	       eventCopy.u.keyButtonPointer.root) 
+	    {
+		eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+		eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+	    }
+	    events = &eventCopy;
+	    break;
+	default: break;
+	}
+    }
+#endif
+
+    if (EventCallback)
+    {
+	EventInfoRec eventinfo;
+	eventinfo.client = pClient;
+	eventinfo.events = events;
+	eventinfo.count = count;
+	CallCallbacks(&EventCallback, (pointer)&eventinfo);
+    }
+    if(pClient->swapped)
+    {
+	for(i = 0; i < count; i++)
+	{
+	    eventFrom = &events[i];
+	    /* Remember to strip off the leading bit of type in case
+	       this event was sent with "SendEvent." */
+	    (*EventSwapVector[eventFrom->u.u.type & 0177])
+		(eventFrom, &eventTo);
+	    (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+	}
+    }
+    else
+    {
+	(void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
new file mode 100644
index 000000000..295b885c2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
@@ -0,0 +1,528 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXextension.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "../../dix/dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#include "Trap.h"
+
+#define EXTENSION_BASE  128
+#define EXTENSION_EVENT_BASE  64
+#define LAST_EVENT  128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors, 
+	     int (*MainProc)(ClientPtr c1), 
+	     int (*SwappedMainProc)(ClientPtr c2), 
+	     void (*CloseDownProc)(ExtensionEntry *e), 
+	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+    int i;
+    register ExtensionEntry *ext, **newexts;
+
+    if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+        return((ExtensionEntry *) NULL);
+    if ((lastEvent + NumEvents > LAST_EVENT) || 
+	        (unsigned)(lastError + NumErrors > LAST_ERROR))
+        return((ExtensionEntry *) NULL);
+
+    ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+    if (!ext)
+	return((ExtensionEntry *) NULL);
+    ext->name = (char *)xalloc(strlen(name) + 1);
+    ext->num_aliases = 0;
+    ext->aliases = (char **)NULL;
+    if (!ext->name)
+    {
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    strcpy(ext->name,  name);
+    i = NumExtensions;
+    newexts = (ExtensionEntry **) xrealloc(extensions,
+					   (i + 1) * sizeof(ExtensionEntry *));
+    if (!newexts)
+    {
+	xfree(ext->name);
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    NumExtensions++;
+    extensions = newexts;
+    extensions[i] = ext;
+    ext->index = i;
+    ext->base = i + EXTENSION_BASE;
+    ext->CloseDown = CloseDownProc;
+    ext->MinorOpcode = MinorOpcodeProc;
+    ProcVector[i + EXTENSION_BASE] = MainProc;
+    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+    if (NumEvents)
+    {
+        ext->eventBase = lastEvent;
+	ext->eventLast = lastEvent + NumEvents;
+	lastEvent += NumEvents;
+    }
+    else
+    {
+        ext->eventBase = 0;
+        ext->eventLast = 0;
+    }
+    if (NumErrors)
+    {
+        ext->errorBase = lastError;
+	ext->errorLast = lastError + NumErrors;
+	lastError += NumErrors;
+    }
+    else
+    {
+        ext->errorBase = 0;
+        ext->errorLast = 0;
+    }
+#ifdef XCSECURITY
+    ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+    (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+    return(ext);
+}
+
+Bool AddExtensionAlias(alias, ext)
+    char *alias;
+    ExtensionEntry *ext;
+{
+    char *name;
+    char **aliases;
+
+    aliases = (char **)xrealloc(ext->aliases,
+				(ext->num_aliases + 1) * sizeof(char *));
+    if (!aliases)
+	return FALSE;
+    ext->aliases = aliases;
+    name = (char *)xalloc(strlen(alias) + 1);
+    if (!name)
+	return FALSE;
+    strcpy(name,  alias);
+    ext->aliases[ext->num_aliases] = name;
+    ext->num_aliases++;
+#ifdef LBX
+    return LbxAddExtensionAlias(ext->index, alias);
+#else
+    return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+    int i, j;
+
+    for (i=0; i<NumExtensions; i++)
+    {
+	if ((strlen(extensions[i]->name) == len) &&
+	    !strncmp(extname, extensions[i]->name, len))
+	    break;
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	{
+	    if ((strlen(extensions[i]->aliases[j]) == len) &&
+		!strncmp(extname, extensions[i]->aliases[j], len))
+		break;
+	}
+	if (j >= 0) break;
+    }
+    return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name.  Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+    int n;
+
+    n = FindExtension((char*)extname, strlen(extname));
+    if (n != -1)
+	return extensions[n];
+    else
+	return NULL;
+}
+
+void
+DeclareExtensionSecurity(extname, secure)
+    char *extname;
+    Bool secure;
+{
+#ifdef XCSECURITY
+    int i = FindExtension(extname, strlen(extname));
+    if (i >= 0)
+    {
+	int majorop = extensions[i]->base;
+	extensions[i]->secure = secure;
+	if (secure)
+	{
+	    UntrustedProcVector[majorop] = ProcVector[majorop];
+	    SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+	}
+	else
+	{
+	    UntrustedProcVector[majorop]	= ProcBadRequest;
+	    SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+	}
+    }
+#endif
+#ifdef LBX
+    LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(client)
+    ClientPtr client;
+{
+    return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(client)
+    ClientPtr client;
+{
+    unsigned char major;
+
+    major = ((xReq *)client->requestBuffer)->reqType;
+    if (major < EXTENSION_BASE)
+	return 0;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return 0;
+    return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+    register int i,j;
+
+#ifdef LBX
+    LbxCloseDownExtensions();
+#endif
+
+    for (i = NumExtensions - 1; i >= 0; i--)
+    {
+	(* extensions[i]->CloseDown)(extensions[i]);
+	NumExtensions = i;
+	xfree(extensions[i]->name);
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	    xfree(extensions[i]->aliases[j]);
+	xfree(extensions[i]->aliases);
+	xfree(extensions[i]);
+    }
+    xfree(extensions);
+    extensions = (ExtensionEntry **)NULL;
+    lastEvent = EXTENSION_EVENT_BASE;
+    lastError = FirstExtensionError;
+    for (i=0; i<MAXSCREENS; i++)
+    {
+	register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+	while (spentry->num)
+	{
+	    spentry->num--;
+	    xfree(spentry->procList[spentry->num].name);
+	}
+	xfree(spentry->procList);
+	spentry->procList = (ProcEntryPtr)NULL;
+    }
+}
+
+
+int
+ProcQueryExtension(client)
+    ClientPtr client;
+{
+    xQueryExtensionReply reply;
+    int i;
+    REQUEST(xQueryExtensionReq);
+
+    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+    
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.major_opcode = 0;
+    reply.sequenceNumber = client->sequence;
+
+    if ( ! NumExtensions )
+        reply.present = xFalse;
+    else
+    {
+	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+        if (i < 0
+
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    || (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+#endif
+	    )
+            reply.present = xFalse;
+        else
+        {            
+            reply.present = xTrue;
+	    reply.major_opcode = extensions[i]->base;
+	    reply.first_event = extensions[i]->eventBase;
+	    reply.first_error = extensions[i]->errorBase;
+	}
+    }
+    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListExtensions(client)
+    ClientPtr client;
+{
+    xListExtensionsReply reply;
+    char *bufptr, *buffer;
+    int total_length = 0;
+
+    REQUEST_SIZE_MATCH(xReq);
+
+    reply.type = X_Reply;
+    reply.nExtensions = 0;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    buffer = NULL;
+
+    if ( NumExtensions )
+    {
+        register int i, j;
+
+        for (i=0;  i<NumExtensions; i++)
+	{
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+                continue;
+
+	    total_length += strlen(extensions[i]->name) + 1;
+	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+		total_length += strlen(extensions[i]->aliases[j]) + 1;
+	}
+        reply.length = (total_length + 3) >> 2;
+	buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+	if (!buffer)
+	    return(BadAlloc);
+        for (i=0;  i<NumExtensions; i++)
+        {
+	    int len;
+#ifdef XCSECURITY
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            *bufptr++ = len = strlen(extensions[i]->name);
+	    memmove(bufptr, extensions[i]->name,  len);
+	    bufptr += len;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+	    {
+		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
+		memmove(bufptr, extensions[i]->aliases[j],  len);
+		bufptr += len;
+	    }
+	}
+    }
+    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+    if (reply.length)
+    {
+        WriteToClient(client, total_length, buffer);
+    	DEALLOCATE_LOCAL(buffer);
+    }
+    return(client->noClientException);
+}
+
+
+ExtensionLookupProc 
+LookupProc(name, pGC)
+    char *name;
+    GCPtr pGC;
+{
+    register int i;
+    register ScreenProcEntry *spentry;
+    spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+    if (spentry->num)    
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+                return(spentry->procList[i].proc);
+    }
+    return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(name, pGC, proc)
+    char *name;
+    GC *pGC;
+    ExtensionLookupProc proc;
+{
+    return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(name, pScreen, proc)
+    char *name;
+    ScreenPtr pScreen;
+    ExtensionLookupProc proc;
+{
+    register ScreenProcEntry *spentry;
+    register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+    char *newname;
+    int i;
+
+    spentry = &AuxillaryScreenProcs[pScreen->myNum];
+    /* first replace duplicates */
+    if (spentry->num)
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+	    {
+                procEntry = &spentry->procList[i];
+		break;
+	    }
+    }
+    if (procEntry)
+        procEntry->proc = proc;
+    else
+    {
+	newname = (char *)xalloc(strlen(name)+1);
+	if (!newname)
+	    return FALSE;
+	procEntry = (ProcEntryPtr)
+			    xrealloc(spentry->procList,
+				     sizeof(ProcEntryRec) * (spentry->num+1));
+	if (!procEntry)
+	{
+	    xfree(newname);
+	    return FALSE;
+	}
+	spentry->procList = procEntry;
+        procEntry += spentry->num;
+        procEntry->name = newname;
+        strcpy(newname, name);
+        procEntry->proc = proc;
+        spentry->num++;        
+    }
+    return TRUE;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
new file mode 100644
index 000000000..295b885c2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
@@ -0,0 +1,528 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXextension.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "../../dix/dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#include "Trap.h"
+
+#define EXTENSION_BASE  128
+#define EXTENSION_EVENT_BASE  64
+#define LAST_EVENT  128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors, 
+	     int (*MainProc)(ClientPtr c1), 
+	     int (*SwappedMainProc)(ClientPtr c2), 
+	     void (*CloseDownProc)(ExtensionEntry *e), 
+	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+    int i;
+    register ExtensionEntry *ext, **newexts;
+
+    if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+        return((ExtensionEntry *) NULL);
+    if ((lastEvent + NumEvents > LAST_EVENT) || 
+	        (unsigned)(lastError + NumErrors > LAST_ERROR))
+        return((ExtensionEntry *) NULL);
+
+    ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+    if (!ext)
+	return((ExtensionEntry *) NULL);
+    ext->name = (char *)xalloc(strlen(name) + 1);
+    ext->num_aliases = 0;
+    ext->aliases = (char **)NULL;
+    if (!ext->name)
+    {
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    strcpy(ext->name,  name);
+    i = NumExtensions;
+    newexts = (ExtensionEntry **) xrealloc(extensions,
+					   (i + 1) * sizeof(ExtensionEntry *));
+    if (!newexts)
+    {
+	xfree(ext->name);
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    NumExtensions++;
+    extensions = newexts;
+    extensions[i] = ext;
+    ext->index = i;
+    ext->base = i + EXTENSION_BASE;
+    ext->CloseDown = CloseDownProc;
+    ext->MinorOpcode = MinorOpcodeProc;
+    ProcVector[i + EXTENSION_BASE] = MainProc;
+    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+    if (NumEvents)
+    {
+        ext->eventBase = lastEvent;
+	ext->eventLast = lastEvent + NumEvents;
+	lastEvent += NumEvents;
+    }
+    else
+    {
+        ext->eventBase = 0;
+        ext->eventLast = 0;
+    }
+    if (NumErrors)
+    {
+        ext->errorBase = lastError;
+	ext->errorLast = lastError + NumErrors;
+	lastError += NumErrors;
+    }
+    else
+    {
+        ext->errorBase = 0;
+        ext->errorLast = 0;
+    }
+#ifdef XCSECURITY
+    ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+    (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+    return(ext);
+}
+
+Bool AddExtensionAlias(alias, ext)
+    char *alias;
+    ExtensionEntry *ext;
+{
+    char *name;
+    char **aliases;
+
+    aliases = (char **)xrealloc(ext->aliases,
+				(ext->num_aliases + 1) * sizeof(char *));
+    if (!aliases)
+	return FALSE;
+    ext->aliases = aliases;
+    name = (char *)xalloc(strlen(alias) + 1);
+    if (!name)
+	return FALSE;
+    strcpy(name,  alias);
+    ext->aliases[ext->num_aliases] = name;
+    ext->num_aliases++;
+#ifdef LBX
+    return LbxAddExtensionAlias(ext->index, alias);
+#else
+    return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+    int i, j;
+
+    for (i=0; i<NumExtensions; i++)
+    {
+	if ((strlen(extensions[i]->name) == len) &&
+	    !strncmp(extname, extensions[i]->name, len))
+	    break;
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	{
+	    if ((strlen(extensions[i]->aliases[j]) == len) &&
+		!strncmp(extname, extensions[i]->aliases[j], len))
+		break;
+	}
+	if (j >= 0) break;
+    }
+    return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name.  Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+    int n;
+
+    n = FindExtension((char*)extname, strlen(extname));
+    if (n != -1)
+	return extensions[n];
+    else
+	return NULL;
+}
+
+void
+DeclareExtensionSecurity(extname, secure)
+    char *extname;
+    Bool secure;
+{
+#ifdef XCSECURITY
+    int i = FindExtension(extname, strlen(extname));
+    if (i >= 0)
+    {
+	int majorop = extensions[i]->base;
+	extensions[i]->secure = secure;
+	if (secure)
+	{
+	    UntrustedProcVector[majorop] = ProcVector[majorop];
+	    SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+	}
+	else
+	{
+	    UntrustedProcVector[majorop]	= ProcBadRequest;
+	    SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+	}
+    }
+#endif
+#ifdef LBX
+    LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(client)
+    ClientPtr client;
+{
+    return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(client)
+    ClientPtr client;
+{
+    unsigned char major;
+
+    major = ((xReq *)client->requestBuffer)->reqType;
+    if (major < EXTENSION_BASE)
+	return 0;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return 0;
+    return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+    register int i,j;
+
+#ifdef LBX
+    LbxCloseDownExtensions();
+#endif
+
+    for (i = NumExtensions - 1; i >= 0; i--)
+    {
+	(* extensions[i]->CloseDown)(extensions[i]);
+	NumExtensions = i;
+	xfree(extensions[i]->name);
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	    xfree(extensions[i]->aliases[j]);
+	xfree(extensions[i]->aliases);
+	xfree(extensions[i]);
+    }
+    xfree(extensions);
+    extensions = (ExtensionEntry **)NULL;
+    lastEvent = EXTENSION_EVENT_BASE;
+    lastError = FirstExtensionError;
+    for (i=0; i<MAXSCREENS; i++)
+    {
+	register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+	while (spentry->num)
+	{
+	    spentry->num--;
+	    xfree(spentry->procList[spentry->num].name);
+	}
+	xfree(spentry->procList);
+	spentry->procList = (ProcEntryPtr)NULL;
+    }
+}
+
+
+int
+ProcQueryExtension(client)
+    ClientPtr client;
+{
+    xQueryExtensionReply reply;
+    int i;
+    REQUEST(xQueryExtensionReq);
+
+    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+    
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.major_opcode = 0;
+    reply.sequenceNumber = client->sequence;
+
+    if ( ! NumExtensions )
+        reply.present = xFalse;
+    else
+    {
+	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+        if (i < 0
+
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    || (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+#endif
+	    )
+            reply.present = xFalse;
+        else
+        {            
+            reply.present = xTrue;
+	    reply.major_opcode = extensions[i]->base;
+	    reply.first_event = extensions[i]->eventBase;
+	    reply.first_error = extensions[i]->errorBase;
+	}
+    }
+    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListExtensions(client)
+    ClientPtr client;
+{
+    xListExtensionsReply reply;
+    char *bufptr, *buffer;
+    int total_length = 0;
+
+    REQUEST_SIZE_MATCH(xReq);
+
+    reply.type = X_Reply;
+    reply.nExtensions = 0;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    buffer = NULL;
+
+    if ( NumExtensions )
+    {
+        register int i, j;
+
+        for (i=0;  i<NumExtensions; i++)
+	{
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+                continue;
+
+	    total_length += strlen(extensions[i]->name) + 1;
+	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+		total_length += strlen(extensions[i]->aliases[j]) + 1;
+	}
+        reply.length = (total_length + 3) >> 2;
+	buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+	if (!buffer)
+	    return(BadAlloc);
+        for (i=0;  i<NumExtensions; i++)
+        {
+	    int len;
+#ifdef XCSECURITY
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            *bufptr++ = len = strlen(extensions[i]->name);
+	    memmove(bufptr, extensions[i]->name,  len);
+	    bufptr += len;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+	    {
+		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
+		memmove(bufptr, extensions[i]->aliases[j],  len);
+		bufptr += len;
+	    }
+	}
+    }
+    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+    if (reply.length)
+    {
+        WriteToClient(client, total_length, buffer);
+    	DEALLOCATE_LOCAL(buffer);
+    }
+    return(client->noClientException);
+}
+
+
+ExtensionLookupProc 
+LookupProc(name, pGC)
+    char *name;
+    GCPtr pGC;
+{
+    register int i;
+    register ScreenProcEntry *spentry;
+    spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+    if (spentry->num)    
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+                return(spentry->procList[i].proc);
+    }
+    return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(name, pGC, proc)
+    char *name;
+    GC *pGC;
+    ExtensionLookupProc proc;
+{
+    return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(name, pScreen, proc)
+    char *name;
+    ScreenPtr pScreen;
+    ExtensionLookupProc proc;
+{
+    register ScreenProcEntry *spentry;
+    register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+    char *newname;
+    int i;
+
+    spentry = &AuxillaryScreenProcs[pScreen->myNum];
+    /* first replace duplicates */
+    if (spentry->num)
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+	    {
+                procEntry = &spentry->procList[i];
+		break;
+	    }
+    }
+    if (procEntry)
+        procEntry->proc = proc;
+    else
+    {
+	newname = (char *)xalloc(strlen(name)+1);
+	if (!newname)
+	    return FALSE;
+	procEntry = (ProcEntryPtr)
+			    xrealloc(spentry->procList,
+				     sizeof(ProcEntryRec) * (spentry->num+1));
+	if (!procEntry)
+	{
+	    xfree(newname);
+	    return FALSE;
+	}
+	spentry->procList = procEntry;
+        procEntry += spentry->num;
+        procEntry->name = newname;
+        strcpy(newname, name);
+        procEntry->proc = proc;
+        spentry->num++;        
+    }
+    return TRUE;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.XF86.original
new file mode 100644
index 000000000..36f053f02
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.XF86.original
@@ -0,0 +1,486 @@
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#define EXTENSION_BASE  128
+#define EXTENSION_EVENT_BASE  64
+#define LAST_EVENT  128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors, 
+	     int (*MainProc)(ClientPtr c1), 
+	     int (*SwappedMainProc)(ClientPtr c2), 
+	     void (*CloseDownProc)(ExtensionEntry *e), 
+	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+    int i;
+    register ExtensionEntry *ext, **newexts;
+
+    if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+        return((ExtensionEntry *) NULL);
+    if ((lastEvent + NumEvents > LAST_EVENT) || 
+	        (unsigned)(lastError + NumErrors > LAST_ERROR))
+        return((ExtensionEntry *) NULL);
+
+    ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+    if (!ext)
+	return((ExtensionEntry *) NULL);
+    ext->name = (char *)xalloc(strlen(name) + 1);
+    ext->num_aliases = 0;
+    ext->aliases = (char **)NULL;
+    if (!ext->name)
+    {
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    strcpy(ext->name,  name);
+    i = NumExtensions;
+    newexts = (ExtensionEntry **) xrealloc(extensions,
+					   (i + 1) * sizeof(ExtensionEntry *));
+    if (!newexts)
+    {
+	xfree(ext->name);
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    NumExtensions++;
+    extensions = newexts;
+    extensions[i] = ext;
+    ext->index = i;
+    ext->base = i + EXTENSION_BASE;
+    ext->CloseDown = CloseDownProc;
+    ext->MinorOpcode = MinorOpcodeProc;
+    ProcVector[i + EXTENSION_BASE] = MainProc;
+    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+    if (NumEvents)
+    {
+        ext->eventBase = lastEvent;
+	ext->eventLast = lastEvent + NumEvents;
+	lastEvent += NumEvents;
+    }
+    else
+    {
+        ext->eventBase = 0;
+        ext->eventLast = 0;
+    }
+    if (NumErrors)
+    {
+        ext->errorBase = lastError;
+	ext->errorLast = lastError + NumErrors;
+	lastError += NumErrors;
+    }
+    else
+    {
+        ext->errorBase = 0;
+        ext->errorLast = 0;
+    }
+#ifdef XCSECURITY
+    ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+    (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+    return(ext);
+}
+
+Bool AddExtensionAlias(alias, ext)
+    char *alias;
+    ExtensionEntry *ext;
+{
+    char *name;
+    char **aliases;
+
+    aliases = (char **)xrealloc(ext->aliases,
+				(ext->num_aliases + 1) * sizeof(char *));
+    if (!aliases)
+	return FALSE;
+    ext->aliases = aliases;
+    name = (char *)xalloc(strlen(alias) + 1);
+    if (!name)
+	return FALSE;
+    strcpy(name,  alias);
+    ext->aliases[ext->num_aliases] = name;
+    ext->num_aliases++;
+#ifdef LBX
+    return LbxAddExtensionAlias(ext->index, alias);
+#else
+    return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+    int i, j;
+
+    for (i=0; i<NumExtensions; i++)
+    {
+	if ((strlen(extensions[i]->name) == len) &&
+	    !strncmp(extname, extensions[i]->name, len))
+	    break;
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	{
+	    if ((strlen(extensions[i]->aliases[j]) == len) &&
+		!strncmp(extname, extensions[i]->aliases[j], len))
+		break;
+	}
+	if (j >= 0) break;
+    }
+    return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name.  Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+    int n;
+
+    n = FindExtension((char*)extname, strlen(extname));
+    if (n != -1)
+	return extensions[n];
+    else
+	return NULL;
+}
+
+void
+DeclareExtensionSecurity(extname, secure)
+    char *extname;
+    Bool secure;
+{
+#ifdef XCSECURITY
+    int i = FindExtension(extname, strlen(extname));
+    if (i >= 0)
+    {
+	int majorop = extensions[i]->base;
+	extensions[i]->secure = secure;
+	if (secure)
+	{
+	    UntrustedProcVector[majorop] = ProcVector[majorop];
+	    SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+	}
+	else
+	{
+	    UntrustedProcVector[majorop]	= ProcBadRequest;
+	    SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+	}
+    }
+#endif
+#ifdef LBX
+    LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(client)
+    ClientPtr client;
+{
+    return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(client)
+    ClientPtr client;
+{
+    unsigned char major;
+
+    major = ((xReq *)client->requestBuffer)->reqType;
+    if (major < EXTENSION_BASE)
+	return 0;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return 0;
+    return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+    register int i,j;
+
+#ifdef LBX
+    LbxCloseDownExtensions();
+#endif
+
+    for (i = NumExtensions - 1; i >= 0; i--)
+    {
+	(* extensions[i]->CloseDown)(extensions[i]);
+	NumExtensions = i;
+	xfree(extensions[i]->name);
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	    xfree(extensions[i]->aliases[j]);
+	xfree(extensions[i]->aliases);
+	xfree(extensions[i]);
+    }
+    xfree(extensions);
+    extensions = (ExtensionEntry **)NULL;
+    lastEvent = EXTENSION_EVENT_BASE;
+    lastError = FirstExtensionError;
+    for (i=0; i<MAXSCREENS; i++)
+    {
+	register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+	while (spentry->num)
+	{
+	    spentry->num--;
+	    xfree(spentry->procList[spentry->num].name);
+	}
+	xfree(spentry->procList);
+	spentry->procList = (ProcEntryPtr)NULL;
+    }
+}
+
+
+int
+ProcQueryExtension(client)
+    ClientPtr client;
+{
+    xQueryExtensionReply reply;
+    int i;
+    REQUEST(xQueryExtensionReq);
+
+    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+    
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.major_opcode = 0;
+    reply.sequenceNumber = client->sequence;
+
+    if ( ! NumExtensions )
+        reply.present = xFalse;
+    else
+    {
+	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+        if (i < 0
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    || (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+#endif
+	    )
+            reply.present = xFalse;
+        else
+        {            
+            reply.present = xTrue;
+	    reply.major_opcode = extensions[i]->base;
+	    reply.first_event = extensions[i]->eventBase;
+	    reply.first_error = extensions[i]->errorBase;
+	}
+    }
+    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListExtensions(client)
+    ClientPtr client;
+{
+    xListExtensionsReply reply;
+    char *bufptr, *buffer;
+    int total_length = 0;
+
+    REQUEST_SIZE_MATCH(xReq);
+
+    reply.type = X_Reply;
+    reply.nExtensions = 0;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    buffer = NULL;
+
+    if ( NumExtensions )
+    {
+        register int i, j;
+
+        for (i=0;  i<NumExtensions; i++)
+	{
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+	    total_length += strlen(extensions[i]->name) + 1;
+	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+		total_length += strlen(extensions[i]->aliases[j]) + 1;
+	}
+        reply.length = (total_length + 3) >> 2;
+	buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+	if (!buffer)
+	    return(BadAlloc);
+        for (i=0;  i<NumExtensions; i++)
+        {
+	    int len;
+#ifdef XCSECURITY
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            *bufptr++ = len = strlen(extensions[i]->name);
+	    memmove(bufptr, extensions[i]->name,  len);
+	    bufptr += len;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+	    {
+		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
+		memmove(bufptr, extensions[i]->aliases[j],  len);
+		bufptr += len;
+	    }
+	}
+    }
+    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+    if (reply.length)
+    {
+        WriteToClient(client, total_length, buffer);
+    	DEALLOCATE_LOCAL(buffer);
+    }
+    return(client->noClientException);
+}
+
+
+ExtensionLookupProc 
+LookupProc(name, pGC)
+    char *name;
+    GCPtr pGC;
+{
+    register int i;
+    register ScreenProcEntry *spentry;
+    spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+    if (spentry->num)    
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+                return(spentry->procList[i].proc);
+    }
+    return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(name, pGC, proc)
+    char *name;
+    GC *pGC;
+    ExtensionLookupProc proc;
+{
+    return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(name, pScreen, proc)
+    char *name;
+    ScreenPtr pScreen;
+    ExtensionLookupProc proc;
+{
+    register ScreenProcEntry *spentry;
+    register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+    char *newname;
+    int i;
+
+    spentry = &AuxillaryScreenProcs[pScreen->myNum];
+    /* first replace duplicates */
+    if (spentry->num)
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+	    {
+                procEntry = &spentry->procList[i];
+		break;
+	    }
+    }
+    if (procEntry)
+        procEntry->proc = proc;
+    else
+    {
+	newname = (char *)xalloc(strlen(name)+1);
+	if (!newname)
+	    return FALSE;
+	procEntry = (ProcEntryPtr)
+			    xrealloc(spentry->procList,
+				     sizeof(ProcEntryRec) * (spentry->num+1));
+	if (!procEntry)
+	{
+	    xfree(newname);
+	    return FALSE;
+	}
+	spentry->procList = procEntry;
+        procEntry += spentry->num;
+        procEntry->name = newname;
+        strcpy(newname, name);
+        procEntry->proc = proc;
+        spentry->num++;        
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c
new file mode 100644
index 000000000..fe2f4aa6c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c
@@ -0,0 +1,550 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglxext.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.8 2001/08/23 18:25:40 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+extern __GLXextensionInfo __glDDXExtensionInfo;
+
+__GLXextensionInfo *__glXExt = &__glDDXExtensionInfo;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+    __glXFlushContextCache();
+    (*__glXExt->resetExtension)();
+    __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+    __GLXclientState *cl = __glXClients[clientIndex];
+
+    if (cl->returnBuf) __glXFree(cl->returnBuf);
+    if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+    if (cl->currentContexts) __glXFree(cl->currentContexts);
+    __glXMemset(cl, 0, sizeof(__GLXclientState));
+    /*
+    ** By default, assume that the client supports
+    ** GLX major version 1 minor version 0 protocol.
+    */
+    cl->GLClientmajorVersion = 1;
+    cl->GLClientminorVersion = 0;
+    if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+    cl->largeCmdBytesSoFar = 0;
+    cl->largeCmdBytesTotal = 0;
+    cl->largeCmdRequestsSoFar = 0;
+    cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called.  In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+    cx->idExists = GL_FALSE;
+    if (!cx->isCurrent) {
+	__glXFreeContext(cx);
+    }
+
+    return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+    __GLXcontext *cx;
+    __GLXclientState *cl = __glXClients[clientIndex];
+    int i;
+
+    if (cl) {
+	/*
+	** Free all the contexts that are current for this client.
+	*/
+	for (i=0; i < cl->numCurrentContexts; i++) {
+	    cx = cl->currentContexts[i];
+	    if (cx) {
+		__glXDeassociateContext(cx, cx->glxPriv);
+		cx->isCurrent = GL_FALSE;
+		if (!cx->idExists) {
+		    __glXFreeContext(cx);
+		}
+	    }
+	}
+	/*
+	** Re-initialize the client state structure.  Don't free it because
+	** we'll probably get another client with this index and use the struct
+	** again.  There is a maximum of MAXCLIENTS of these structures.
+	*/
+	ResetClientState(clientIndex);
+    }
+
+    return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+    PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+    pGlxPixmap->idExists = False;
+    if (!pGlxPixmap->refcnt) {
+	/*
+	** The DestroyPixmap routine should decrement the refcount and free
+	** only if it's zero.
+	*/
+	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+	__glXFree(pGlxPixmap);
+    }
+
+    return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+    if (cx->idExists || cx->isCurrent) return GL_FALSE;
+    
+    if (!cx->isDirect) {
+	if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+	    return GL_FALSE;
+	}
+    }
+    if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+    if (cx->selectBuf) __glXFree(cx->selectBuf);
+    __glXFree(cx);
+    if (cx == __glXLastContext) {
+	__glXFlushContextCache();
+    }
+
+    return GL_TRUE;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error.  Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+    errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+    errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+    return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+    ExtensionEntry *extEntry;
+    int i;
+    
+#ifdef X11R5
+    __glXContextRes = CreateNewResourceType(ContextGone);
+    __glXClientRes = CreateNewResourceType(ClientGone);
+    __glXPixmapRes = CreateNewResourceType(PixmapGone);
+#else
+    __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+#endif 
+
+    /*
+    ** Add extension to server extensions.
+    */
+    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+			    __GLX_NUMBER_ERRORS, __glXDispatch,
+			    __glXSwapDispatch, ResetExtension,
+			    StandardMinorOpcode);
+    if (!extEntry) {
+	FatalError("__glXExtensionInit: AddExtensions failed\n");
+	return;
+    }
+    if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+	ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+	return;
+    }
+
+    __glXBadContext = extEntry->errorBase + GLXBadContext;
+    __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+    __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+    __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+    __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+    __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+    __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+    __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+    __glXUnsupportedPrivateRequest = extEntry->errorBase +
+      			GLXUnsupportedPrivateRequest;
+
+    /*
+    ** Initialize table of client state.  There is never a client 0.
+    */
+    for (i=1; i <= MAXCLIENTS; i++) {
+	__glXClients[i] = 0;
+    }
+
+    /*
+    ** Initialize screen specific data.
+    */
+    __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+    return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates)
+{
+    (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+		    int *nvisualp, int *ndepthp,
+		    int *rootDepthp, VisualID *defaultVisp,
+		    unsigned long sizes, int bitsPerRGB,
+		    int preferredVis)
+{
+    Bool ret;
+
+    if (saveInitVisualsProc) {
+        ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+                                  rootDepthp, defaultVisp, sizes, bitsPerRGB,
+                                  preferredVis);
+        if (!ret)
+            return False;
+    }
+    (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+                             defaultVisp, sizes, bitsPerRGB);
+    return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+    saveInitVisualsProc = *initVisProc;
+    *initVisProc = GlxInitVisuals;
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+    __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts).  While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+				int *error)
+{
+    __GLXcontext *cx;
+
+    /*
+    ** See if the context tag is legal; it is managed by the extension,
+    ** so if it's invalid, we have an implementation error.
+    */
+    cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+    if (!cx) {
+	cl->client->errorValue = tag;
+	*error = __glXBadContextTag;
+	return 0;
+    }
+
+    if (!cx->isDirect) {
+	if (cx->glxPriv == NULL) {
+	    /*
+	    ** The drawable has vanished.  It must be a window, because only
+	    ** windows can be destroyed from under us; GLX pixmaps are
+	    ** refcounted and don't go away until no one is using them.
+	    */
+	    *error = __glXBadCurrentWindow;
+	    return 0;
+    	}
+    }
+    
+    if (cx == __glXLastContext) {
+	/* No need to re-bind */
+	return cx;
+    }
+
+    /* Make this context the current one for the GL. */
+    if (!cx->isDirect) {
+	if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+	    /* Bind failed, and set the error code.  Bummer */
+	    cl->client->errorValue = cx->id;
+	    *error = __glXBadContextState;
+	    return 0;
+    	}
+    }
+    __glXLastContext = cx;
+    return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** If we're expecting a glXRenderLarge request, this better be one.
+    */
+    if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+	client->errorValue = stuff->glxCode;
+	return __glXBadLargeRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSwapSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+    return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+    return;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.NX.original
new file mode 100644
index 000000000..fe2f4aa6c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.NX.original
@@ -0,0 +1,550 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglxext.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.8 2001/08/23 18:25:40 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+extern __GLXextensionInfo __glDDXExtensionInfo;
+
+__GLXextensionInfo *__glXExt = &__glDDXExtensionInfo;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+    __glXFlushContextCache();
+    (*__glXExt->resetExtension)();
+    __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+    __GLXclientState *cl = __glXClients[clientIndex];
+
+    if (cl->returnBuf) __glXFree(cl->returnBuf);
+    if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+    if (cl->currentContexts) __glXFree(cl->currentContexts);
+    __glXMemset(cl, 0, sizeof(__GLXclientState));
+    /*
+    ** By default, assume that the client supports
+    ** GLX major version 1 minor version 0 protocol.
+    */
+    cl->GLClientmajorVersion = 1;
+    cl->GLClientminorVersion = 0;
+    if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+    cl->largeCmdBytesSoFar = 0;
+    cl->largeCmdBytesTotal = 0;
+    cl->largeCmdRequestsSoFar = 0;
+    cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called.  In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+    cx->idExists = GL_FALSE;
+    if (!cx->isCurrent) {
+	__glXFreeContext(cx);
+    }
+
+    return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+    __GLXcontext *cx;
+    __GLXclientState *cl = __glXClients[clientIndex];
+    int i;
+
+    if (cl) {
+	/*
+	** Free all the contexts that are current for this client.
+	*/
+	for (i=0; i < cl->numCurrentContexts; i++) {
+	    cx = cl->currentContexts[i];
+	    if (cx) {
+		__glXDeassociateContext(cx, cx->glxPriv);
+		cx->isCurrent = GL_FALSE;
+		if (!cx->idExists) {
+		    __glXFreeContext(cx);
+		}
+	    }
+	}
+	/*
+	** Re-initialize the client state structure.  Don't free it because
+	** we'll probably get another client with this index and use the struct
+	** again.  There is a maximum of MAXCLIENTS of these structures.
+	*/
+	ResetClientState(clientIndex);
+    }
+
+    return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+    PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+    pGlxPixmap->idExists = False;
+    if (!pGlxPixmap->refcnt) {
+	/*
+	** The DestroyPixmap routine should decrement the refcount and free
+	** only if it's zero.
+	*/
+	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+	__glXFree(pGlxPixmap);
+    }
+
+    return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+    if (cx->idExists || cx->isCurrent) return GL_FALSE;
+    
+    if (!cx->isDirect) {
+	if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+	    return GL_FALSE;
+	}
+    }
+    if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+    if (cx->selectBuf) __glXFree(cx->selectBuf);
+    __glXFree(cx);
+    if (cx == __glXLastContext) {
+	__glXFlushContextCache();
+    }
+
+    return GL_TRUE;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error.  Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+    errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+    errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+    return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+    ExtensionEntry *extEntry;
+    int i;
+    
+#ifdef X11R5
+    __glXContextRes = CreateNewResourceType(ContextGone);
+    __glXClientRes = CreateNewResourceType(ClientGone);
+    __glXPixmapRes = CreateNewResourceType(PixmapGone);
+#else
+    __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+#endif 
+
+    /*
+    ** Add extension to server extensions.
+    */
+    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+			    __GLX_NUMBER_ERRORS, __glXDispatch,
+			    __glXSwapDispatch, ResetExtension,
+			    StandardMinorOpcode);
+    if (!extEntry) {
+	FatalError("__glXExtensionInit: AddExtensions failed\n");
+	return;
+    }
+    if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+	ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+	return;
+    }
+
+    __glXBadContext = extEntry->errorBase + GLXBadContext;
+    __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+    __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+    __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+    __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+    __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+    __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+    __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+    __glXUnsupportedPrivateRequest = extEntry->errorBase +
+      			GLXUnsupportedPrivateRequest;
+
+    /*
+    ** Initialize table of client state.  There is never a client 0.
+    */
+    for (i=1; i <= MAXCLIENTS; i++) {
+	__glXClients[i] = 0;
+    }
+
+    /*
+    ** Initialize screen specific data.
+    */
+    __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+    return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates)
+{
+    (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+		    int *nvisualp, int *ndepthp,
+		    int *rootDepthp, VisualID *defaultVisp,
+		    unsigned long sizes, int bitsPerRGB,
+		    int preferredVis)
+{
+    Bool ret;
+
+    if (saveInitVisualsProc) {
+        ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+                                  rootDepthp, defaultVisp, sizes, bitsPerRGB,
+                                  preferredVis);
+        if (!ret)
+            return False;
+    }
+    (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+                             defaultVisp, sizes, bitsPerRGB);
+    return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+    saveInitVisualsProc = *initVisProc;
+    *initVisProc = GlxInitVisuals;
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+    __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts).  While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+				int *error)
+{
+    __GLXcontext *cx;
+
+    /*
+    ** See if the context tag is legal; it is managed by the extension,
+    ** so if it's invalid, we have an implementation error.
+    */
+    cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+    if (!cx) {
+	cl->client->errorValue = tag;
+	*error = __glXBadContextTag;
+	return 0;
+    }
+
+    if (!cx->isDirect) {
+	if (cx->glxPriv == NULL) {
+	    /*
+	    ** The drawable has vanished.  It must be a window, because only
+	    ** windows can be destroyed from under us; GLX pixmaps are
+	    ** refcounted and don't go away until no one is using them.
+	    */
+	    *error = __glXBadCurrentWindow;
+	    return 0;
+    	}
+    }
+    
+    if (cx == __glXLastContext) {
+	/* No need to re-bind */
+	return cx;
+    }
+
+    /* Make this context the current one for the GL. */
+    if (!cx->isDirect) {
+	if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+	    /* Bind failed, and set the error code.  Bummer */
+	    cl->client->errorValue = cx->id;
+	    *error = __glXBadContextState;
+	    return 0;
+    	}
+    }
+    __glXLastContext = cx;
+    return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** If we're expecting a glXRenderLarge request, this better be one.
+    */
+    if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+	client->errorValue = stuff->glxCode;
+	return __glXBadLargeRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSwapSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+    return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+    return;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.XF86.original
new file mode 100644
index 000000000..95a9c2e6e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglxext.c.XF86.original
@@ -0,0 +1,489 @@
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.8 2001/08/23 18:25:40 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+
+extern __GLXextensionInfo __glDDXExtensionInfo;
+
+__GLXextensionInfo *__glXExt = &__glDDXExtensionInfo;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+    __glXFlushContextCache();
+    (*__glXExt->resetExtension)();
+    __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+    __GLXclientState *cl = __glXClients[clientIndex];
+
+    if (cl->returnBuf) __glXFree(cl->returnBuf);
+    if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+    if (cl->currentContexts) __glXFree(cl->currentContexts);
+    __glXMemset(cl, 0, sizeof(__GLXclientState));
+    /*
+    ** By default, assume that the client supports
+    ** GLX major version 1 minor version 0 protocol.
+    */
+    cl->GLClientmajorVersion = 1;
+    cl->GLClientminorVersion = 0;
+    if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+    cl->largeCmdBytesSoFar = 0;
+    cl->largeCmdBytesTotal = 0;
+    cl->largeCmdRequestsSoFar = 0;
+    cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called.  In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+    cx->idExists = GL_FALSE;
+    if (!cx->isCurrent) {
+	__glXFreeContext(cx);
+    }
+
+    return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+    __GLXcontext *cx;
+    __GLXclientState *cl = __glXClients[clientIndex];
+    int i;
+
+    if (cl) {
+	/*
+	** Free all the contexts that are current for this client.
+	*/
+	for (i=0; i < cl->numCurrentContexts; i++) {
+	    cx = cl->currentContexts[i];
+	    if (cx) {
+		__glXDeassociateContext(cx, cx->glxPriv);
+		cx->isCurrent = GL_FALSE;
+		if (!cx->idExists) {
+		    __glXFreeContext(cx);
+		}
+	    }
+	}
+	/*
+	** Re-initialize the client state structure.  Don't free it because
+	** we'll probably get another client with this index and use the struct
+	** again.  There is a maximum of MAXCLIENTS of these structures.
+	*/
+	ResetClientState(clientIndex);
+    }
+
+    return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+    PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+    pGlxPixmap->idExists = False;
+    if (!pGlxPixmap->refcnt) {
+	/*
+	** The DestroyPixmap routine should decrement the refcount and free
+	** only if it's zero.
+	*/
+	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+	__glXFree(pGlxPixmap);
+    }
+
+    return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+    if (cx->idExists || cx->isCurrent) return GL_FALSE;
+    
+    if (!cx->isDirect) {
+	if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+	    return GL_FALSE;
+	}
+    }
+    if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+    if (cx->selectBuf) __glXFree(cx->selectBuf);
+    __glXFree(cx);
+    if (cx == __glXLastContext) {
+	__glXFlushContextCache();
+    }
+
+    return GL_TRUE;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error.  Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+    errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+    errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+    return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+    ExtensionEntry *extEntry;
+    int i;
+    
+#ifdef X11R5
+    __glXContextRes = CreateNewResourceType(ContextGone);
+    __glXClientRes = CreateNewResourceType(ClientGone);
+    __glXPixmapRes = CreateNewResourceType(PixmapGone);
+#else
+    __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+#endif 
+
+    /*
+    ** Add extension to server extensions.
+    */
+    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+			    __GLX_NUMBER_ERRORS, __glXDispatch,
+			    __glXSwapDispatch, ResetExtension,
+			    StandardMinorOpcode);
+    if (!extEntry) {
+	FatalError("__glXExtensionInit: AddExtensions failed\n");
+	return;
+    }
+    if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+	ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+	return;
+    }
+
+    __glXBadContext = extEntry->errorBase + GLXBadContext;
+    __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+    __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+    __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+    __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+    __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+    __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+    __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+    __glXUnsupportedPrivateRequest = extEntry->errorBase +
+      			GLXUnsupportedPrivateRequest;
+
+    /*
+    ** Initialize table of client state.  There is never a client 0.
+    */
+    for (i=1; i <= MAXCLIENTS; i++) {
+	__glXClients[i] = 0;
+    }
+
+    /*
+    ** Initialize screen specific data.
+    */
+    __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+    return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates)
+{
+    (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+		    int *nvisualp, int *ndepthp,
+		    int *rootDepthp, VisualID *defaultVisp,
+		    unsigned long sizes, int bitsPerRGB,
+		    int preferredVis)
+{
+    Bool ret;
+
+    if (saveInitVisualsProc) {
+        ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+                                  rootDepthp, defaultVisp, sizes, bitsPerRGB,
+                                  preferredVis);
+        if (!ret)
+            return False;
+    }
+    (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+                             defaultVisp, sizes, bitsPerRGB);
+    return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+    saveInitVisualsProc = *initVisProc;
+    *initVisProc = GlxInitVisuals;
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+    __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts).  While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+				int *error)
+{
+    __GLXcontext *cx;
+
+    /*
+    ** See if the context tag is legal; it is managed by the extension,
+    ** so if it's invalid, we have an implementation error.
+    */
+    cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+    if (!cx) {
+	cl->client->errorValue = tag;
+	*error = __glXBadContextTag;
+	return 0;
+    }
+
+    if (!cx->isDirect) {
+	if (cx->glxPriv == NULL) {
+	    /*
+	    ** The drawable has vanished.  It must be a window, because only
+	    ** windows can be destroyed from under us; GLX pixmaps are
+	    ** refcounted and don't go away until no one is using them.
+	    */
+	    *error = __glXBadCurrentWindow;
+	    return 0;
+    	}
+    }
+    
+    if (cx == __glXLastContext) {
+	/* No need to re-bind */
+	return cx;
+    }
+
+    /* Make this context the current one for the GL. */
+    if (!cx->isDirect) {
+	if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+	    /* Bind failed, and set the error code.  Bummer */
+	    cl->client->errorValue = cx->id;
+	    *error = __glXBadContextState;
+	    return 0;
+    	}
+    }
+    __glXLastContext = cx;
+    return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** If we're expecting a glXRenderLarge request, this better be one.
+    */
+    if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+	client->errorValue = stuff->glxCode;
+	return __glXBadLargeRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSingleTable[opcode];
+    return (*proc)(cl, (GLbyte *) stuff);
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSwapSingleTable[opcode];
+    return (*proc)(cl, (GLbyte *) stuff);
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+    return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+    return;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
new file mode 100644
index 000000000..dfd82b76b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
@@ -0,0 +1,511 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyph.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.6 2001/10/28 03:34:19 tsi Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef  DEBUG
+#undef  TEST
+
+#endif
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime.  These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+    { 32,		43,		41        },
+    { 64,		73,		71        },
+    { 128,		151,		149       },
+    { 256,		283,		281       },
+    { 512,		571,		569       },
+    { 1024,		1153,		1151      },
+    { 2048,		2269,		2267      },
+    { 4096,		4519,		4517      },
+    { 8192,		9013,		9011      },
+    { 16384,		18043,		18041     },
+    { 32768,		36109,		36107     },
+    { 65536,		72091,		72089     },
+    { 131072,		144409,		144407    },
+    { 262144,		288361,		288359    },
+    { 524288,		576883,		576881    },
+    { 1048576,		1153459,	1153457   },
+    { 2097152,		2307163,	2307161   },
+    { 4194304,		4613893,	4613891   },
+    { 8388608,		9227641,	9227639   },
+    { 16777216,		18455029,	18455027  },
+    { 33554432,		36911011,	36911009  },
+    { 67108864,		73819861,	73819859  },
+    { 134217728,	147639589,	147639587 },
+    { 268435456,	295279081,	295279079 },
+    { 536870912,	590559793,	590559791 }
+};
+
+#define NGLYPHHASHSETS	(sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8	glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+    int	i;
+
+    for (i = 0; i < NGLYPHHASHSETS; i++)
+	if (glyphHashSets[i].entries >= filled)
+	    return &glyphHashSets[i];
+    return 0;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+    return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+    CARD32	elt, step, s;
+    GlyphPtr	glyph;
+    GlyphRefPtr	table, gr, del;
+    CARD32	tableSize = hash->hashSet->size;
+
+    table = hash->table;
+    elt = signature % tableSize;
+    step = 0;
+    del = 0;
+    for (;;)
+    {
+	gr = &table[elt];
+	s = gr->signature;
+	glyph = gr->glyph;
+	if (!glyph)
+	{
+	    if (del)
+		gr = del;
+	    break;
+	}
+	if (glyph == DeletedGlyph)
+	{
+	    if (!del)
+		del = gr;
+	    else if (gr == del)
+		break;
+	}
+	else if (s == signature &&
+		 (!match || 
+		  memcmp (&compare->info, &glyph->info, compare->size) == 0))
+	{
+	    break;
+	}
+	if (!step)
+	{
+	    step = signature % hash->hashSet->rehash;
+	    if (!step)
+		step = 1;
+	}
+	elt += step;
+	if (elt >= tableSize)
+	    elt -= tableSize;
+    }
+    return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+    CARD32  *bits = (CARD32 *) &(glyph->info);
+    CARD32  hash;
+    int	    n = glyph->size / sizeof (CARD32);
+
+    hash = 0;
+    while (n--)
+	hash ^= *bits++;
+    return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+    ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+    GlyphPtr	g;
+    int		i, j;
+
+    for (i = 0; i < hash->hashSet->size; i++)
+    {
+	g = hash->table[i].glyph;
+	if (!g || g == DeletedGlyph)
+	    continue;
+	for (j = i + 1; j < hash->hashSet->size; j++)
+	    if (hash->table[j].glyph == g)
+		DuplicateRef (g, where);
+    }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+    CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+    if (--glyph->refcnt == 0)
+    {
+	GlyphRefPtr gr;
+	int	    i;
+	int	    first;
+
+	first = -1;
+	for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+	    if (globalGlyphs[format].table[i].glyph == glyph)
+	    {
+		if (first != -1)
+		    DuplicateRef (glyph, "FreeGlyph check");
+		first = i;
+	    }
+
+	gr = FindGlyphRef (&globalGlyphs[format],
+			   HashGlyph (glyph), TRUE, glyph);
+	if (gr - globalGlyphs[format].table != first)
+	    DuplicateRef (glyph, "Found wrong one");
+	if (gr->glyph && gr->glyph != DeletedGlyph)
+	{
+	    gr->glyph = DeletedGlyph;
+	    gr->signature = 0;
+	    globalGlyphs[format].tableEntries--;
+	}
+	xfree (glyph);
+    }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+    GlyphRefPtr	    gr;
+    CARD32	    hash;
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+    /* Locate existing matching glyph */
+    hash = HashGlyph (glyph);
+    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+    {
+	xfree (glyph);
+	glyph = gr->glyph;
+    }
+    else
+    {
+	gr->glyph = glyph;
+	gr->signature = hash;
+	globalGlyphs[glyphSet->fdepth].tableEntries++;
+    }
+ 
+    /* Insert/replace glyphset value */
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    ++glyph->refcnt;
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+	FreeGlyph (gr->glyph, glyphSet->fdepth);
+    else
+	glyphSet->hash.tableEntries++;
+    gr->glyph = glyph;
+    gr->signature = id;
+
+    #ifdef NXAGENT_SERVER
+
+    gr -> corruptedGlyph = 1;
+
+    #endif
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphRefPtr     gr;
+    GlyphPtr	    glyph;
+
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    glyph = gr->glyph;
+    if (glyph && glyph != DeletedGlyph)
+    {
+	gr->glyph = DeletedGlyph;
+	glyphSet->hash.tableEntries--;
+	FreeGlyph (glyph, glyphSet->fdepth);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+#ifdef NXAGENT_SERVER
+
+GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+  GlyphRefPtr gr;
+  GlyphPtr    glyph;
+
+  gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+  glyph = gr -> glyph;
+
+  if (glyph == DeletedGlyph)
+  {
+    glyph = 0;
+  }
+  else if (gr -> corruptedGlyph == 1)
+  {
+     #ifdef DEBUG
+     fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
+                 (void *) glyph, (void *) glyphSet);
+     #endif
+
+    nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
+                         (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
+  }
+
+  return glyph;
+}
+
+#else
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphPtr        glyph;
+
+    glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+    if (glyph == DeletedGlyph)
+	glyph = 0;
+    return glyph;
+}
+
+#endif
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+    int		size;
+    GlyphPtr	glyph;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+    if (!glyph)
+	return 0;
+    glyph->refcnt = 0;
+    glyph->size = size + sizeof (xGlyphInfo);
+    glyph->info = *gi;
+    return glyph;
+}
+    
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+    hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+    if (!hash->table)
+	return FALSE;
+    memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+    hash->hashSet = hashSet;
+    hash->tableEntries = 0;
+    return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+    CARD32	    tableEntries;
+    GlyphHashSetPtr hashSet;
+    GlyphHashRec    newHash;
+    GlyphRefPtr	    gr;
+    GlyphPtr	    glyph;
+    int		    i;
+    int		    oldSize;
+    CARD32	    s;
+
+    #ifdef NXAGENT_SERVER
+
+    CARD32          c;
+
+    #endif
+
+    tableEntries = hash->tableEntries + change;
+    hashSet = FindGlyphHashSet (tableEntries);
+    if (hashSet == hash->hashSet)
+	return TRUE;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash top");
+    if (!AllocateGlyphHash (&newHash, hashSet))
+	return FALSE;
+    if (hash->table)
+    {
+	oldSize = hash->hashSet->size;
+	for (i = 0; i < oldSize; i++)
+	{
+	    glyph = hash->table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+	    {
+		s = hash->table[i].signature;
+
+                #ifdef NXAGENT_SERVER
+
+                c = hash->table[i].corruptedGlyph;
+
+                #endif
+
+		gr = FindGlyphRef (&newHash, s, global, glyph);
+		gr->signature = s;
+		gr->glyph = glyph;
+
+                #ifdef NXAGENT_SERVER
+
+                gr -> corruptedGlyph = c;
+
+                #endif
+
+		++newHash.tableEntries;
+	    }
+	}
+	xfree (hash->table);
+    }
+    *hash = newHash;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash bottom");
+    return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+    return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+			    
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+    GlyphSetPtr	glyphSet;
+    
+    if (!globalGlyphs[fdepth].hashSet)
+    {
+	if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+	    return FALSE;
+    }
+    glyphSet = xalloc (sizeof (GlyphSetRec));
+    if (!glyphSet)
+	return FALSE;
+    if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+    {
+	xfree (glyphSet);
+	return FALSE;
+    }
+    glyphSet->refcnt = 1;
+    glyphSet->fdepth = fdepth;
+    glyphSet->format = format;
+    return glyphSet;	
+}
+
+int
+FreeGlyphSet (pointer	value,
+	      XID       gid)
+{
+    GlyphSetPtr	glyphSet = (GlyphSetPtr) value;
+    
+    if (--glyphSet->refcnt == 0)
+    {
+	CARD32	    i, tableSize = glyphSet->hash.hashSet->size;
+	GlyphRefPtr table = glyphSet->hash.table;
+	GlyphPtr    glyph;
+    
+	for (i = 0; i < tableSize; i++)
+	{
+	    glyph = table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+		FreeGlyph (glyph, glyphSet->fdepth);
+	}
+	if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+	{
+	    xfree (globalGlyphs[glyphSet->fdepth].table);
+	    globalGlyphs[glyphSet->fdepth].table = 0;
+	    globalGlyphs[glyphSet->fdepth].hashSet = 0;
+	}
+	else
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+	xfree (table);
+	xfree (glyphSet);
+    }
+    return Success;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
new file mode 100644
index 000000000..dfd82b76b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
@@ -0,0 +1,511 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyph.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.6 2001/10/28 03:34:19 tsi Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef  DEBUG
+#undef  TEST
+
+#endif
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime.  These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+    { 32,		43,		41        },
+    { 64,		73,		71        },
+    { 128,		151,		149       },
+    { 256,		283,		281       },
+    { 512,		571,		569       },
+    { 1024,		1153,		1151      },
+    { 2048,		2269,		2267      },
+    { 4096,		4519,		4517      },
+    { 8192,		9013,		9011      },
+    { 16384,		18043,		18041     },
+    { 32768,		36109,		36107     },
+    { 65536,		72091,		72089     },
+    { 131072,		144409,		144407    },
+    { 262144,		288361,		288359    },
+    { 524288,		576883,		576881    },
+    { 1048576,		1153459,	1153457   },
+    { 2097152,		2307163,	2307161   },
+    { 4194304,		4613893,	4613891   },
+    { 8388608,		9227641,	9227639   },
+    { 16777216,		18455029,	18455027  },
+    { 33554432,		36911011,	36911009  },
+    { 67108864,		73819861,	73819859  },
+    { 134217728,	147639589,	147639587 },
+    { 268435456,	295279081,	295279079 },
+    { 536870912,	590559793,	590559791 }
+};
+
+#define NGLYPHHASHSETS	(sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8	glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+    int	i;
+
+    for (i = 0; i < NGLYPHHASHSETS; i++)
+	if (glyphHashSets[i].entries >= filled)
+	    return &glyphHashSets[i];
+    return 0;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+    return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+    CARD32	elt, step, s;
+    GlyphPtr	glyph;
+    GlyphRefPtr	table, gr, del;
+    CARD32	tableSize = hash->hashSet->size;
+
+    table = hash->table;
+    elt = signature % tableSize;
+    step = 0;
+    del = 0;
+    for (;;)
+    {
+	gr = &table[elt];
+	s = gr->signature;
+	glyph = gr->glyph;
+	if (!glyph)
+	{
+	    if (del)
+		gr = del;
+	    break;
+	}
+	if (glyph == DeletedGlyph)
+	{
+	    if (!del)
+		del = gr;
+	    else if (gr == del)
+		break;
+	}
+	else if (s == signature &&
+		 (!match || 
+		  memcmp (&compare->info, &glyph->info, compare->size) == 0))
+	{
+	    break;
+	}
+	if (!step)
+	{
+	    step = signature % hash->hashSet->rehash;
+	    if (!step)
+		step = 1;
+	}
+	elt += step;
+	if (elt >= tableSize)
+	    elt -= tableSize;
+    }
+    return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+    CARD32  *bits = (CARD32 *) &(glyph->info);
+    CARD32  hash;
+    int	    n = glyph->size / sizeof (CARD32);
+
+    hash = 0;
+    while (n--)
+	hash ^= *bits++;
+    return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+    ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+    GlyphPtr	g;
+    int		i, j;
+
+    for (i = 0; i < hash->hashSet->size; i++)
+    {
+	g = hash->table[i].glyph;
+	if (!g || g == DeletedGlyph)
+	    continue;
+	for (j = i + 1; j < hash->hashSet->size; j++)
+	    if (hash->table[j].glyph == g)
+		DuplicateRef (g, where);
+    }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+    CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+    if (--glyph->refcnt == 0)
+    {
+	GlyphRefPtr gr;
+	int	    i;
+	int	    first;
+
+	first = -1;
+	for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+	    if (globalGlyphs[format].table[i].glyph == glyph)
+	    {
+		if (first != -1)
+		    DuplicateRef (glyph, "FreeGlyph check");
+		first = i;
+	    }
+
+	gr = FindGlyphRef (&globalGlyphs[format],
+			   HashGlyph (glyph), TRUE, glyph);
+	if (gr - globalGlyphs[format].table != first)
+	    DuplicateRef (glyph, "Found wrong one");
+	if (gr->glyph && gr->glyph != DeletedGlyph)
+	{
+	    gr->glyph = DeletedGlyph;
+	    gr->signature = 0;
+	    globalGlyphs[format].tableEntries--;
+	}
+	xfree (glyph);
+    }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+    GlyphRefPtr	    gr;
+    CARD32	    hash;
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+    /* Locate existing matching glyph */
+    hash = HashGlyph (glyph);
+    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+    {
+	xfree (glyph);
+	glyph = gr->glyph;
+    }
+    else
+    {
+	gr->glyph = glyph;
+	gr->signature = hash;
+	globalGlyphs[glyphSet->fdepth].tableEntries++;
+    }
+ 
+    /* Insert/replace glyphset value */
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    ++glyph->refcnt;
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+	FreeGlyph (gr->glyph, glyphSet->fdepth);
+    else
+	glyphSet->hash.tableEntries++;
+    gr->glyph = glyph;
+    gr->signature = id;
+
+    #ifdef NXAGENT_SERVER
+
+    gr -> corruptedGlyph = 1;
+
+    #endif
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphRefPtr     gr;
+    GlyphPtr	    glyph;
+
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    glyph = gr->glyph;
+    if (glyph && glyph != DeletedGlyph)
+    {
+	gr->glyph = DeletedGlyph;
+	glyphSet->hash.tableEntries--;
+	FreeGlyph (glyph, glyphSet->fdepth);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+#ifdef NXAGENT_SERVER
+
+GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+  GlyphRefPtr gr;
+  GlyphPtr    glyph;
+
+  gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+  glyph = gr -> glyph;
+
+  if (glyph == DeletedGlyph)
+  {
+    glyph = 0;
+  }
+  else if (gr -> corruptedGlyph == 1)
+  {
+     #ifdef DEBUG
+     fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
+                 (void *) glyph, (void *) glyphSet);
+     #endif
+
+    nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
+                         (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
+  }
+
+  return glyph;
+}
+
+#else
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphPtr        glyph;
+
+    glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+    if (glyph == DeletedGlyph)
+	glyph = 0;
+    return glyph;
+}
+
+#endif
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+    int		size;
+    GlyphPtr	glyph;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+    if (!glyph)
+	return 0;
+    glyph->refcnt = 0;
+    glyph->size = size + sizeof (xGlyphInfo);
+    glyph->info = *gi;
+    return glyph;
+}
+    
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+    hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+    if (!hash->table)
+	return FALSE;
+    memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+    hash->hashSet = hashSet;
+    hash->tableEntries = 0;
+    return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+    CARD32	    tableEntries;
+    GlyphHashSetPtr hashSet;
+    GlyphHashRec    newHash;
+    GlyphRefPtr	    gr;
+    GlyphPtr	    glyph;
+    int		    i;
+    int		    oldSize;
+    CARD32	    s;
+
+    #ifdef NXAGENT_SERVER
+
+    CARD32          c;
+
+    #endif
+
+    tableEntries = hash->tableEntries + change;
+    hashSet = FindGlyphHashSet (tableEntries);
+    if (hashSet == hash->hashSet)
+	return TRUE;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash top");
+    if (!AllocateGlyphHash (&newHash, hashSet))
+	return FALSE;
+    if (hash->table)
+    {
+	oldSize = hash->hashSet->size;
+	for (i = 0; i < oldSize; i++)
+	{
+	    glyph = hash->table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+	    {
+		s = hash->table[i].signature;
+
+                #ifdef NXAGENT_SERVER
+
+                c = hash->table[i].corruptedGlyph;
+
+                #endif
+
+		gr = FindGlyphRef (&newHash, s, global, glyph);
+		gr->signature = s;
+		gr->glyph = glyph;
+
+                #ifdef NXAGENT_SERVER
+
+                gr -> corruptedGlyph = c;
+
+                #endif
+
+		++newHash.tableEntries;
+	    }
+	}
+	xfree (hash->table);
+    }
+    *hash = newHash;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash bottom");
+    return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+    return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+			    
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+    GlyphSetPtr	glyphSet;
+    
+    if (!globalGlyphs[fdepth].hashSet)
+    {
+	if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+	    return FALSE;
+    }
+    glyphSet = xalloc (sizeof (GlyphSetRec));
+    if (!glyphSet)
+	return FALSE;
+    if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+    {
+	xfree (glyphSet);
+	return FALSE;
+    }
+    glyphSet->refcnt = 1;
+    glyphSet->fdepth = fdepth;
+    glyphSet->format = format;
+    return glyphSet;	
+}
+
+int
+FreeGlyphSet (pointer	value,
+	      XID       gid)
+{
+    GlyphSetPtr	glyphSet = (GlyphSetPtr) value;
+    
+    if (--glyphSet->refcnt == 0)
+    {
+	CARD32	    i, tableSize = glyphSet->hash.hashSet->size;
+	GlyphRefPtr table = glyphSet->hash.table;
+	GlyphPtr    glyph;
+    
+	for (i = 0; i < tableSize; i++)
+	{
+	    glyph = table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+		FreeGlyph (glyph, glyphSet->fdepth);
+	}
+	if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+	{
+	    xfree (globalGlyphs[glyphSet->fdepth].table);
+	    globalGlyphs[glyphSet->fdepth].table = 0;
+	    globalGlyphs[glyphSet->fdepth].hashSet = 0;
+	}
+	else
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+	xfree (table);
+	xfree (glyphSet);
+    }
+    return Success;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.XF86.original
new file mode 100644
index 000000000..b4f08c223
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.XF86.original
@@ -0,0 +1,416 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.6 2001/10/28 03:34:19 tsi Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime.  These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+    { 32,		43,		41        },
+    { 64,		73,		71        },
+    { 128,		151,		149       },
+    { 256,		283,		281       },
+    { 512,		571,		569       },
+    { 1024,		1153,		1151      },
+    { 2048,		2269,		2267      },
+    { 4096,		4519,		4517      },
+    { 8192,		9013,		9011      },
+    { 16384,		18043,		18041     },
+    { 32768,		36109,		36107     },
+    { 65536,		72091,		72089     },
+    { 131072,		144409,		144407    },
+    { 262144,		288361,		288359    },
+    { 524288,		576883,		576881    },
+    { 1048576,		1153459,	1153457   },
+    { 2097152,		2307163,	2307161   },
+    { 4194304,		4613893,	4613891   },
+    { 8388608,		9227641,	9227639   },
+    { 16777216,		18455029,	18455027  },
+    { 33554432,		36911011,	36911009  },
+    { 67108864,		73819861,	73819859  },
+    { 134217728,	147639589,	147639587 },
+    { 268435456,	295279081,	295279079 },
+    { 536870912,	590559793,	590559791 }
+};
+
+#define NGLYPHHASHSETS	(sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8	glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+    int	i;
+
+    for (i = 0; i < NGLYPHHASHSETS; i++)
+	if (glyphHashSets[i].entries >= filled)
+	    return &glyphHashSets[i];
+    return 0;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+    return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+    CARD32	elt, step, s;
+    GlyphPtr	glyph;
+    GlyphRefPtr	table, gr, del;
+    CARD32	tableSize = hash->hashSet->size;
+
+    table = hash->table;
+    elt = signature % tableSize;
+    step = 0;
+    del = 0;
+    for (;;)
+    {
+	gr = &table[elt];
+	s = gr->signature;
+	glyph = gr->glyph;
+	if (!glyph)
+	{
+	    if (del)
+		gr = del;
+	    break;
+	}
+	if (glyph == DeletedGlyph)
+	{
+	    if (!del)
+		del = gr;
+	    else if (gr == del)
+		break;
+	}
+	else if (s == signature &&
+		 (!match || 
+		  memcmp (&compare->info, &glyph->info, compare->size) == 0))
+	{
+	    break;
+	}
+	if (!step)
+	{
+	    step = signature % hash->hashSet->rehash;
+	    if (!step)
+		step = 1;
+	}
+	elt += step;
+	if (elt >= tableSize)
+	    elt -= tableSize;
+    }
+    return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+    CARD32  *bits = (CARD32 *) &(glyph->info);
+    CARD32  hash;
+    int	    n = glyph->size / sizeof (CARD32);
+
+    hash = 0;
+    while (n--)
+	hash ^= *bits++;
+    return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+    ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+    GlyphPtr	g;
+    int		i, j;
+
+    for (i = 0; i < hash->hashSet->size; i++)
+    {
+	g = hash->table[i].glyph;
+	if (!g || g == DeletedGlyph)
+	    continue;
+	for (j = i + 1; j < hash->hashSet->size; j++)
+	    if (hash->table[j].glyph == g)
+		DuplicateRef (g, where);
+    }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+    CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+    if (--glyph->refcnt == 0)
+    {
+	GlyphRefPtr gr;
+	int	    i;
+	int	    first;
+
+	first = -1;
+	for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+	    if (globalGlyphs[format].table[i].glyph == glyph)
+	    {
+		if (first != -1)
+		    DuplicateRef (glyph, "FreeGlyph check");
+		first = i;
+	    }
+
+	gr = FindGlyphRef (&globalGlyphs[format],
+			   HashGlyph (glyph), TRUE, glyph);
+	if (gr - globalGlyphs[format].table != first)
+	    DuplicateRef (glyph, "Found wrong one");
+	if (gr->glyph && gr->glyph != DeletedGlyph)
+	{
+	    gr->glyph = DeletedGlyph;
+	    gr->signature = 0;
+	    globalGlyphs[format].tableEntries--;
+	}
+	xfree (glyph);
+    }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+    GlyphRefPtr	    gr;
+    CARD32	    hash;
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+    /* Locate existing matching glyph */
+    hash = HashGlyph (glyph);
+    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+    {
+	xfree (glyph);
+	glyph = gr->glyph;
+    }
+    else
+    {
+	gr->glyph = glyph;
+	gr->signature = hash;
+	globalGlyphs[glyphSet->fdepth].tableEntries++;
+    }
+    
+    /* Insert/replace glyphset value */
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    ++glyph->refcnt;
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+	FreeGlyph (gr->glyph, glyphSet->fdepth);
+    else
+	glyphSet->hash.tableEntries++;
+    gr->glyph = glyph;
+    gr->signature = id;
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphRefPtr     gr;
+    GlyphPtr	    glyph;
+
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    glyph = gr->glyph;
+    if (glyph && glyph != DeletedGlyph)
+    {
+	gr->glyph = DeletedGlyph;
+	glyphSet->hash.tableEntries--;
+	FreeGlyph (glyph, glyphSet->fdepth);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphPtr        glyph;
+
+    glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+    if (glyph == DeletedGlyph)
+	glyph = 0;
+    return glyph;
+}
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+    int		size;
+    GlyphPtr	glyph;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+    if (!glyph)
+	return 0;
+    glyph->refcnt = 0;
+    glyph->size = size + sizeof (xGlyphInfo);
+    glyph->info = *gi;
+    return glyph;
+}
+    
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+    hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+    if (!hash->table)
+	return FALSE;
+    memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+    hash->hashSet = hashSet;
+    hash->tableEntries = 0;
+    return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+    CARD32	    tableEntries;
+    GlyphHashSetPtr hashSet;
+    GlyphHashRec    newHash;
+    GlyphRefPtr	    gr;
+    GlyphPtr	    glyph;
+    int		    i;
+    int		    oldSize;
+    CARD32	    s;
+
+    tableEntries = hash->tableEntries + change;
+    hashSet = FindGlyphHashSet (tableEntries);
+    if (hashSet == hash->hashSet)
+	return TRUE;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash top");
+    if (!AllocateGlyphHash (&newHash, hashSet))
+	return FALSE;
+    if (hash->table)
+    {
+	oldSize = hash->hashSet->size;
+	for (i = 0; i < oldSize; i++)
+	{
+	    glyph = hash->table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+	    {
+		s = hash->table[i].signature;
+		gr = FindGlyphRef (&newHash, s, global, glyph);
+		gr->signature = s;
+		gr->glyph = glyph;
+		++newHash.tableEntries;
+	    }
+	}
+	xfree (hash->table);
+    }
+    *hash = newHash;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash bottom");
+    return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+    return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+			    
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+    GlyphSetPtr	glyphSet;
+    
+    if (!globalGlyphs[fdepth].hashSet)
+    {
+	if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+	    return FALSE;
+    }
+    glyphSet = xalloc (sizeof (GlyphSetRec));
+    if (!glyphSet)
+	return FALSE;
+    if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+    {
+	xfree (glyphSet);
+	return FALSE;
+    }
+    glyphSet->refcnt = 1;
+    glyphSet->fdepth = fdepth;
+    glyphSet->format = format;
+    return glyphSet;	
+}
+
+int
+FreeGlyphSet (pointer	value,
+	      XID       gid)
+{
+    GlyphSetPtr	glyphSet = (GlyphSetPtr) value;
+    
+    if (--glyphSet->refcnt == 0)
+    {
+	CARD32	    i, tableSize = glyphSet->hash.hashSet->size;
+	GlyphRefPtr table = glyphSet->hash.table;
+	GlyphPtr    glyph;
+    
+	for (i = 0; i < tableSize; i++)
+	{
+	    glyph = table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+		FreeGlyph (glyph, glyphSet->fdepth);
+	}
+	if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+	{
+	    xfree (globalGlyphs[glyphSet->fdepth].table);
+	    globalGlyphs[glyphSet->fdepth].table = 0;
+	    globalGlyphs[glyphSet->fdepth].hashSet = 0;
+	}
+	else
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+	xfree (table);
+	xfree (glyphSet);
+    }
+    return Success;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
new file mode 100644
index 000000000..599e4c616
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
@@ -0,0 +1,252 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyphcurs.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/************************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "misc.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+#include "../../fb/fb.h"
+#include "Pixmaps.h"
+
+#ifndef True
+#define True  1
+#endif
+
+/*
+    get the bits out of the font in a portable way.  to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+    since all screens return the same bitmap format, we'll just use
+the first one we find.
+    the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(pfont, ch, cm, ppbits)
+    FontPtr	pfont;
+    unsigned int ch;
+    register CursorMetricPtr cm;
+    unsigned char **ppbits;
+{
+    register ScreenPtr pScreen;
+    register GCPtr pGC;
+    xRectangle rect;
+    PixmapPtr ppix;
+    long nby;
+    char *pbits;
+    ChangeGCVal gcval[3];
+    unsigned char char2b[2];
+
+    /* turn glyph index into a protocol-format char2b */
+    char2b[0] = (unsigned char)(ch >> 8);
+    char2b[1] = (unsigned char)(ch & 0xff);
+
+    pScreen = screenInfo.screens[0];
+    nby = BitmapBytePad(cm->width) * (long)cm->height;
+    pbits = (char *)xalloc(nby);
+    if (!pbits)
+	return BadAlloc;
+    /* zeroing the (pad) bits seems to help some ddx cursor handling */
+    bzero(pbits, nby);
+
+    ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1);
+    pGC = GetScratchGC(1, pScreen);
+    if (!ppix || !pGC)
+    {
+	if (ppix)
+	    fbDestroyPixmap(ppix);
+	if (pGC)
+	    FreeScratchGC(pGC);
+	xfree(pbits);
+	return BadAlloc;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
+                (void *) ppix, cm->width, cm->height, 1);
+    #endif
+
+    nxagentPixmapPriv(ppix) -> id = 0;
+    nxagentPixmapPriv(ppix) -> mid = 0;
+    nxagentPixmapPriv(ppix) -> isVirtual = True;
+    nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
+    nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = cm->width;
+    rect.height = cm->height;
+
+    pGC->stateChanges |= GCFunction | GCForeground | GCFont;
+    pGC->alu = GXcopy;
+
+    pGC->fgPixel = 0;
+
+    pfont->refcnt++;
+
+    if (pGC->font)
+      CloseFont(pGC->font, (Font)0);
+
+    pGC->font = pfont;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+
+    /* draw the glyph */
+    gcval[0].val = 1;
+    pGC->fgPixel = 1;
+
+    pGC->stateChanges |= GCForeground;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
+    fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+                         XYPixmap, 1, pbits);
+    *ppbits = (unsigned char *)pbits;
+    FreeScratchGC(pGC);
+    fbDestroyPixmap(ppix);
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
+                (void *) ppix);
+    #endif
+
+    return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph( pfont, ch, cm)
+    register FontPtr 	pfont;
+    unsigned		ch;
+    register CursorMetricPtr cm;
+{
+    CharInfoPtr 	pci;
+    unsigned long	nglyphs;
+    CARD8		chs[2];
+    FontEncoding	encoding;
+
+    chs[0] = ch >> 8;
+    chs[1] = ch;
+    encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+    if (encoding == Linear16Bit)
+    {
+	if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+	    return FALSE;
+    }
+    else
+    {
+	if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+	    return FALSE;
+	if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+	    return FALSE;
+    }
+    (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+    if (nglyphs == 0)
+	return FALSE;
+    cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+    cm->height = pci->metrics.descent + pci->metrics.ascent;
+    if (pci->metrics.leftSideBearing > 0)
+    {
+	cm->width += pci->metrics.leftSideBearing;
+	cm->xhot = 0;
+    }
+    else
+    {
+	cm->xhot = -pci->metrics.leftSideBearing;
+	if (pci->metrics.rightSideBearing < 0)
+	    cm->width -= pci->metrics.rightSideBearing;
+    }
+    if (pci->metrics.ascent < 0)
+    {
+	cm->height -= pci->metrics.ascent;
+	cm->yhot = 0;
+    }
+    else
+    {
+	cm->yhot = pci->metrics.ascent;
+	if (pci->metrics.descent < 0)
+	    cm->height -= pci->metrics.descent;
+    }
+    return TRUE;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
new file mode 100644
index 000000000..599e4c616
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
@@ -0,0 +1,252 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyphcurs.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/************************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "misc.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+#include "../../fb/fb.h"
+#include "Pixmaps.h"
+
+#ifndef True
+#define True  1
+#endif
+
+/*
+    get the bits out of the font in a portable way.  to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+    since all screens return the same bitmap format, we'll just use
+the first one we find.
+    the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(pfont, ch, cm, ppbits)
+    FontPtr	pfont;
+    unsigned int ch;
+    register CursorMetricPtr cm;
+    unsigned char **ppbits;
+{
+    register ScreenPtr pScreen;
+    register GCPtr pGC;
+    xRectangle rect;
+    PixmapPtr ppix;
+    long nby;
+    char *pbits;
+    ChangeGCVal gcval[3];
+    unsigned char char2b[2];
+
+    /* turn glyph index into a protocol-format char2b */
+    char2b[0] = (unsigned char)(ch >> 8);
+    char2b[1] = (unsigned char)(ch & 0xff);
+
+    pScreen = screenInfo.screens[0];
+    nby = BitmapBytePad(cm->width) * (long)cm->height;
+    pbits = (char *)xalloc(nby);
+    if (!pbits)
+	return BadAlloc;
+    /* zeroing the (pad) bits seems to help some ddx cursor handling */
+    bzero(pbits, nby);
+
+    ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1);
+    pGC = GetScratchGC(1, pScreen);
+    if (!ppix || !pGC)
+    {
+	if (ppix)
+	    fbDestroyPixmap(ppix);
+	if (pGC)
+	    FreeScratchGC(pGC);
+	xfree(pbits);
+	return BadAlloc;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
+                (void *) ppix, cm->width, cm->height, 1);
+    #endif
+
+    nxagentPixmapPriv(ppix) -> id = 0;
+    nxagentPixmapPriv(ppix) -> mid = 0;
+    nxagentPixmapPriv(ppix) -> isVirtual = True;
+    nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
+    nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = cm->width;
+    rect.height = cm->height;
+
+    pGC->stateChanges |= GCFunction | GCForeground | GCFont;
+    pGC->alu = GXcopy;
+
+    pGC->fgPixel = 0;
+
+    pfont->refcnt++;
+
+    if (pGC->font)
+      CloseFont(pGC->font, (Font)0);
+
+    pGC->font = pfont;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+
+    /* draw the glyph */
+    gcval[0].val = 1;
+    pGC->fgPixel = 1;
+
+    pGC->stateChanges |= GCForeground;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
+    fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+                         XYPixmap, 1, pbits);
+    *ppbits = (unsigned char *)pbits;
+    FreeScratchGC(pGC);
+    fbDestroyPixmap(ppix);
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
+                (void *) ppix);
+    #endif
+
+    return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph( pfont, ch, cm)
+    register FontPtr 	pfont;
+    unsigned		ch;
+    register CursorMetricPtr cm;
+{
+    CharInfoPtr 	pci;
+    unsigned long	nglyphs;
+    CARD8		chs[2];
+    FontEncoding	encoding;
+
+    chs[0] = ch >> 8;
+    chs[1] = ch;
+    encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+    if (encoding == Linear16Bit)
+    {
+	if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+	    return FALSE;
+    }
+    else
+    {
+	if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+	    return FALSE;
+	if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+	    return FALSE;
+    }
+    (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+    if (nglyphs == 0)
+	return FALSE;
+    cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+    cm->height = pci->metrics.descent + pci->metrics.ascent;
+    if (pci->metrics.leftSideBearing > 0)
+    {
+	cm->width += pci->metrics.leftSideBearing;
+	cm->xhot = 0;
+    }
+    else
+    {
+	cm->xhot = -pci->metrics.leftSideBearing;
+	if (pci->metrics.rightSideBearing < 0)
+	    cm->width -= pci->metrics.rightSideBearing;
+    }
+    if (pci->metrics.ascent < 0)
+    {
+	cm->height -= pci->metrics.ascent;
+	cm->yhot = 0;
+    }
+    else
+    {
+	cm->yhot = pci->metrics.ascent;
+	if (pci->metrics.descent < 0)
+	    cm->height -= pci->metrics.descent;
+    }
+    return TRUE;
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.XF86.original
new file mode 100644
index 000000000..630e98fa3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.XF86.original
@@ -0,0 +1,197 @@
+/************************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "misc.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+
+/*
+    get the bits out of the font in a portable way.  to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+    since all screens return the same bitmap format, we'll just use
+the first one we find.
+    the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(pfont, ch, cm, ppbits)
+    FontPtr	pfont;
+    unsigned int ch;
+    register CursorMetricPtr cm;
+    unsigned char **ppbits;
+{
+    register ScreenPtr pScreen;
+    register GCPtr pGC;
+    xRectangle rect;
+    PixmapPtr ppix;
+    long nby;
+    char *pbits;
+    ChangeGCVal gcval[3];
+    unsigned char char2b[2];
+
+    /* turn glyph index into a protocol-format char2b */
+    char2b[0] = (unsigned char)(ch >> 8);
+    char2b[1] = (unsigned char)(ch & 0xff);
+
+    pScreen = screenInfo.screens[0];
+    nby = BitmapBytePad(cm->width) * (long)cm->height;
+    pbits = (char *)xalloc(nby);
+    if (!pbits)
+	return BadAlloc;
+    /* zeroing the (pad) bits seems to help some ddx cursor handling */
+    bzero(pbits, nby);
+
+    ppix = (PixmapPtr)(*pScreen->CreatePixmap)(pScreen, cm->width,
+					       cm->height, 1);
+    pGC = GetScratchGC(1, pScreen);
+    if (!ppix || !pGC)
+    {
+	if (ppix)
+	    (*pScreen->DestroyPixmap)(ppix);
+	if (pGC)
+	    FreeScratchGC(pGC);
+	xfree(pbits);
+	return BadAlloc;
+    }
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = cm->width;
+    rect.height = cm->height;
+
+    /* fill the pixmap with 0 */
+    gcval[0].val = GXcopy;
+    gcval[1].val = 0;
+    gcval[2].ptr = (pointer)pfont;
+    dixChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont,
+		NULL, gcval);
+    ValidateGC((DrawablePtr)ppix, pGC);
+    (*pGC->ops->PolyFillRect)((DrawablePtr)ppix, pGC, 1, &rect);
+
+    /* draw the glyph */
+    gcval[0].val = 1;
+    dixChangeGC(NullClient, pGC, GCForeground, NULL, gcval);
+    ValidateGC((DrawablePtr)ppix, pGC);
+    (*pGC->ops->PolyText16)((DrawablePtr)ppix, pGC, cm->xhot, cm->yhot,
+			    1, (unsigned short *)char2b);
+    (*pScreen->GetImage)((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+			 XYPixmap, 1, pbits);
+    *ppbits = (unsigned char *)pbits;
+    FreeScratchGC(pGC);
+    (*pScreen->DestroyPixmap)(ppix);
+    return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph( pfont, ch, cm)
+    register FontPtr 	pfont;
+    unsigned		ch;
+    register CursorMetricPtr cm;
+{
+    CharInfoPtr 	pci;
+    unsigned long	nglyphs;
+    CARD8		chs[2];
+    FontEncoding	encoding;
+
+    chs[0] = ch >> 8;
+    chs[1] = ch;
+    encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+    if (encoding == Linear16Bit)
+    {
+	if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+	    return FALSE;
+    }
+    else
+    {
+	if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+	    return FALSE;
+	if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+	    return FALSE;
+    }
+    (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+    if (nglyphs == 0)
+	return FALSE;
+    cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+    cm->height = pci->metrics.descent + pci->metrics.ascent;
+    if (pci->metrics.leftSideBearing > 0)
+    {
+	cm->width += pci->metrics.leftSideBearing;
+	cm->xhot = 0;
+    }
+    else
+    {
+	cm->xhot = -pci->metrics.leftSideBearing;
+	if (pci->metrics.rightSideBearing < 0)
+	    cm->width -= pci->metrics.rightSideBearing;
+    }
+    if (pci->metrics.ascent < 0)
+    {
+	cm->height -= pci->metrics.ascent;
+	cm->yhot = 0;
+    }
+    else
+    {
+	cm->yhot = pci->metrics.ascent;
+	if (pci->metrics.descent < 0)
+	    cm->height -= pci->metrics.descent;
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
new file mode 100644
index 000000000..970d0bb4d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
@@ -0,0 +1,161 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyphstr.h"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.4 2001/01/21 21:19:39 tsi Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original glyphstr.h
+ * or symbols  will be redefined. The code here adds a field
+ * to _GlyphSet. This should be done by defining a new type
+ * and casting when appropriate.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include "renderproto.h"
+#include "../../render/picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1	0
+#define GlyphFormat4	1
+#define GlyphFormat8	2
+#define GlyphFormat16	3
+#define GlyphFormat32	4
+#define GlyphFormatNum	5
+
+typedef struct _Glyph {
+    CARD32	refcnt;
+    CARD32	size;	/* info + bitmap */
+    xGlyphInfo	info;
+    /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+    CARD32	signature;
+    GlyphPtr	glyph;
+    CARD16      corruptedGlyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph	((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+    CARD32	entries;
+    CARD32	size;
+    CARD32	rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+    GlyphRefPtr	    table;
+    GlyphHashSetPtr hashSet;
+    CARD32	    tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+    CARD32	    refcnt;
+    PictFormatPtr   format;
+    int		    fdepth;
+    GlyphHashRec    hash;
+    CARD32          remoteID;
+} GlyphSetRec, *GlyphSetPtr;
+
+typedef struct _GlyphList {
+    INT16	    xOff;
+    INT16	    yOff;
+    CARD8	    len;
+    PictFormatPtr   format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer   value,
+	      XID       gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
new file mode 100644
index 000000000..970d0bb4d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
@@ -0,0 +1,161 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXglyphstr.h"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.4 2001/01/21 21:19:39 tsi Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original glyphstr.h
+ * or symbols  will be redefined. The code here adds a field
+ * to _GlyphSet. This should be done by defining a new type
+ * and casting when appropriate.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include "renderproto.h"
+#include "../../render/picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1	0
+#define GlyphFormat4	1
+#define GlyphFormat8	2
+#define GlyphFormat16	3
+#define GlyphFormat32	4
+#define GlyphFormatNum	5
+
+typedef struct _Glyph {
+    CARD32	refcnt;
+    CARD32	size;	/* info + bitmap */
+    xGlyphInfo	info;
+    /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+    CARD32	signature;
+    GlyphPtr	glyph;
+    CARD16      corruptedGlyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph	((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+    CARD32	entries;
+    CARD32	size;
+    CARD32	rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+    GlyphRefPtr	    table;
+    GlyphHashSetPtr hashSet;
+    CARD32	    tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+    CARD32	    refcnt;
+    PictFormatPtr   format;
+    int		    fdepth;
+    GlyphHashRec    hash;
+    CARD32          remoteID;
+} GlyphSetRec, *GlyphSetPtr;
+
+typedef struct _GlyphList {
+    INT16	    xOff;
+    INT16	    yOff;
+    CARD8	    len;
+    PictFormatPtr   format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer   value,
+	      XID       gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.XF86.original
new file mode 100644
index 000000000..99f55e3eb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.XF86.original
@@ -0,0 +1,127 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.4 2001/01/21 21:19:39 tsi Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include "renderproto.h"
+#include "picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1	0
+#define GlyphFormat4	1
+#define GlyphFormat8	2
+#define GlyphFormat16	3
+#define GlyphFormat32	4
+#define GlyphFormatNum	5
+
+typedef struct _Glyph {
+    CARD32	refcnt;
+    CARD32	size;	/* info + bitmap */
+    xGlyphInfo	info;
+    /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+    CARD32	signature;
+    GlyphPtr	glyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph	((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+    CARD32	entries;
+    CARD32	size;
+    CARD32	rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+    GlyphRefPtr	    table;
+    GlyphHashSetPtr hashSet;
+    CARD32	    tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+    CARD32	    refcnt;
+    PictFormatPtr   format;
+    int		    fdepth;
+    GlyphHashRec    hash;
+} GlyphSetRec, *GlyphSetPtr;
+
+typedef struct _GlyphList {
+    INT16	    xOff;
+    INT16	    yOff;
+    CARD8	    len;
+    PictFormatPtr   format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer   value,
+	      XID       gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c
new file mode 100644
index 000000000..bd068170c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c
@@ -0,0 +1,938 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiexpose.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9 2001/12/14 20:00:22 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "Xprotostr.h"
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include "Xmd.h"
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+    machine-independent graphics exposure code.  any device that uses
+the region package can call this.
+*/
+
+#ifdef NXAGENT_SERVER
+
+#include "Windows.h"
+
+#endif
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25		/* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures 
+    generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination.  Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+     this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+     added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+		  pGC, srcx, srcy, width, height, dstx, dsty, plane)
+    register DrawablePtr	pSrcDrawable;
+    register DrawablePtr	pDstDrawable;
+    GCPtr 			pGC;
+    int 			srcx, srcy;
+    int 			width, height;
+    int 			dstx, dsty;
+    unsigned long		plane;
+{
+    register ScreenPtr pscr;
+    RegionPtr prgnSrcClip;	/* drawable-relative source clip */
+    RegionRec rgnSrcRec;
+    RegionPtr prgnDstClip;	/* drawable-relative dest clip */
+    RegionRec rgnDstRec;
+    BoxRec srcBox;		/* unclipped source */
+    RegionRec rgnExposed;	/* exposed region, calculated source-
+				   relative, made dst relative to
+				   intersect with visible parts of
+				   dest and send events to client, 
+				   and then screen relative to paint 
+				   the window background
+				*/
+    WindowPtr pSrcWin;
+    BoxRec expBox;
+    Bool extents;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    expBox.x1 = 0;
+    expBox.y1 = 0;
+    expBox.x2 = 0;
+    expBox.y2 = 0;
+
+#endif
+
+    /* This prevents warning about pscr not being used. */
+    pGC->pScreen = pscr = pGC->pScreen;
+
+    /* avoid work if we can */
+    if (!pGC->graphicsExposures &&
+	(pDstDrawable->type == DRAWABLE_PIXMAP) &&
+	((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+	 (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+	return NULL;
+	
+    srcBox.x1 = srcx;
+    srcBox.y1 = srcy;
+    srcBox.x2 = srcx+width;
+    srcBox.y2 = srcy+height;
+
+    if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+    {
+	BoxRec TsrcBox;
+
+	TsrcBox.x1 = srcx + pSrcDrawable->x;
+	TsrcBox.y1 = srcy + pSrcDrawable->y;
+	TsrcBox.x2 = TsrcBox.x1 + width;
+	TsrcBox.y2 = TsrcBox.y1 + height;
+	pSrcWin = (WindowPtr) pSrcDrawable;
+	if (pGC->subWindowMode == IncludeInferiors)
+ 	{
+	    prgnSrcClip = NotClippedByChildren (pSrcWin);
+	    if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+	    {
+		REGION_DESTROY(pscr, prgnSrcClip);
+		return NULL;
+	    }
+	}
+ 	else
+ 	{
+	    if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+		return NULL;
+	    prgnSrcClip = &rgnSrcRec;
+	    REGION_INIT(pscr, prgnSrcClip, NullBox, 0);
+	    REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnSrcClip,
+				-pSrcDrawable->x, -pSrcDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+	    (srcBox.x2 <= pSrcDrawable->width) &&
+ 	    (srcBox.y2 <= pSrcDrawable->height))
+	    return NULL;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pSrcDrawable->width;
+	box.y2 = pSrcDrawable->height;
+	prgnSrcClip = &rgnSrcRec;
+	REGION_INIT(pscr, prgnSrcClip, &box, 1);
+	pSrcWin = (WindowPtr)NULL;
+    }
+
+    if (pDstDrawable == pSrcDrawable)
+    {
+	prgnDstClip = prgnSrcClip;
+    }
+    else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+    {
+	if (pGC->subWindowMode == IncludeInferiors)
+	{
+	    prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+	}
+	else
+	{
+	    prgnDstClip = &rgnDstRec;
+	    REGION_INIT(pscr, prgnDstClip, NullBox, 0);
+	    REGION_COPY(pscr, prgnDstClip,
+				&((WindowPtr)pDstDrawable)->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnDstClip,
+				 -pDstDrawable->x, -pDstDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pDstDrawable->width;
+	box.y2 = pDstDrawable->height;
+	prgnDstClip = &rgnDstRec;
+	REGION_INIT(pscr, prgnDstClip, &box, 1);
+    }
+
+    /* drawable-relative source region */
+    REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+    /* now get the hidden parts of the source box*/
+    REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+    if (pSrcWin && pSrcWin->backStorage)
+    {
+	/*
+	 * Copy any areas from the source backing store. Modifies
+	 * rgnExposed.
+	 */
+	(* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+					      pDstDrawable,
+					      pGC,
+					      &rgnExposed,
+					      srcx, srcy,
+					      dstx, dsty,
+					      plane);
+    }
+    
+    /* move them over the destination */
+    REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+    /* intersect with visible areas of dest */
+    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+    /*
+     * If we have LOTS of rectangles, we decide to take the extents
+     * and force an exposure on that.  This should require much less
+     * work overall, on both client and server.  This is cheating, but
+     * isn't prohibited by the protocol ("spontaneous combustion" :-)
+     * for windows.
+     */
+    extents = pGC->graphicsExposures &&
+	      (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+	      (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+    if (pSrcWin)
+    {
+	RegionPtr	region;
+    	if (!(region = wClipShape (pSrcWin)))
+    	    region = wBoundingShape (pSrcWin);
+    	/*
+     	 * If you try to CopyArea the extents of a shaped window, compacting the
+     	 * exposed region will undo all our work!
+     	 */
+    	if (extents && pSrcWin && region &&
+    	    (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+	    	extents = FALSE;
+    }
+#endif
+    if (extents)
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+	REGION_RESET(pscr, &rgnExposed, &expBox);
+	/* need to clear out new areas of backing store */
+	if (pWin->backStorage)
+	    (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					 pWin,
+					 expBox.x1,
+					 expBox.y1,
+					 expBox.x2 - expBox.x1,
+					 expBox.y2 - expBox.y1,
+					 FALSE);
+    }
+    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+	(((WindowPtr)pDstDrawable)->backgroundState != None))
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	/* make the exposed area screen-relative */
+	REGION_TRANSLATE(pscr, &rgnExposed, 
+				 pDstDrawable->x, pDstDrawable->y);
+
+	if (extents)
+	{
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+	}
+	(*pWin->drawable.pScreen->PaintWindowBackground)(
+			(WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+	if (extents)
+	{
+	    REGION_RESET(pscr, &rgnExposed, &expBox);
+	}
+	else
+	    REGION_TRANSLATE(pscr, &rgnExposed,
+				     -pDstDrawable->x, -pDstDrawable->y);
+    }
+    if (prgnDstClip == &rgnDstRec)
+    {
+	REGION_UNINIT(pscr, prgnDstClip);
+    }
+    else if (prgnDstClip != prgnSrcClip)
+    {
+	REGION_DESTROY(pscr, prgnDstClip);
+    }
+
+    if (prgnSrcClip == &rgnSrcRec)
+    {
+	REGION_UNINIT(pscr, prgnSrcClip);
+    }
+    else
+    {
+	REGION_DESTROY(pscr, prgnSrcClip);
+    }
+
+    if (pGC->graphicsExposures)
+    {
+	/* don't look */
+	RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+	*exposed = rgnExposed;
+	return exposed;
+    }
+    else
+    {
+	REGION_UNINIT(pscr, &rgnExposed);
+	return NULL;
+    }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+    ClientPtr	client;
+    RegionPtr	pRgn;
+    XID		drawable;
+    int	major;
+    int	minor;
+{
+    if (pRgn && !REGION_NIL(pRgn))
+    {
+        xEvent *pEvent;
+	register xEvent *pe;
+	register BoxPtr pBox;
+	register int i;
+	int numRects;
+
+	numRects = REGION_NUM_RECTS(pRgn);
+	pBox = REGION_RECTS(pRgn);
+	if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+		return;
+	pe = pEvent;
+
+	for (i=1; i<=numRects; i++, pe++, pBox++)
+	{
+	    pe->u.u.type = GraphicsExpose;
+	    pe->u.graphicsExposure.drawable = drawable;
+	    pe->u.graphicsExposure.x = pBox->x1;
+	    pe->u.graphicsExposure.y = pBox->y1;
+	    pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+	    pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+	    pe->u.graphicsExposure.count = numRects - i;
+	    pe->u.graphicsExposure.majorEvent = major;
+	    pe->u.graphicsExposure.minorEvent = minor;
+	}
+	TryClientEvents(client, pEvent, numRects,
+			    (Mask)0, NoEventMask, NullGrab);
+	DEALLOCATE_LOCAL(pEvent);
+    }
+    else
+    {
+        xEvent event;
+	event.u.u.type = NoExpose;
+	event.u.noExposure.drawable = drawable;
+	event.u.noExposure.majorEvent = major;
+	event.u.noExposure.minorEvent = minor;
+	TryClientEvents(client, &event, 1,
+	    (Mask)0, NoEventMask, NullGrab);
+    }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+    WindowPtr pWin;
+    RegionPtr pRgn;
+    register int dx, dy;
+{
+    register BoxPtr pBox;
+    int numRects;
+    register xEvent *pEvent, *pe;
+    register int i;
+
+    pBox = REGION_RECTS(pRgn);
+    numRects = REGION_NUM_RECTS(pRgn);
+    if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+	return;
+
+    for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+    {
+	pe->u.u.type = Expose;
+	pe->u.expose.window = pWin->drawable.id;
+	pe->u.expose.x = pBox->x1 - dx;
+	pe->u.expose.y = pBox->y1 - dy;
+	pe->u.expose.width = pBox->x2 - pBox->x1;
+	pe->u.expose.height = pBox->y2 - pBox->y1;
+	pe->u.expose.count = i;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	int scrnum = pWin->drawable.pScreen->myNum;
+	int x = 0, y = 0;
+	XID realWin = 0;
+
+	if(!pWin->parent) {
+	    x = panoramiXdataPtr[scrnum].x;
+	    y = panoramiXdataPtr[scrnum].y;
+	    pWin = WindowTable[0];
+	    realWin = pWin->drawable.id;
+	} else if (scrnum) {
+	    PanoramiXRes *win;
+	    win = PanoramiXFindIDByScrnum(XRT_WINDOW, 
+			pWin->drawable.id, scrnum);
+	    if(!win) {
+		DEALLOCATE_LOCAL(pEvent);
+		return;
+	    }
+	    realWin = win->info[0].id;
+	    pWin = LookupIDByType(realWin, RT_WINDOW);
+	}
+	if(x || y || scrnum)
+	  for (i = 0; i < numRects; i++) {
+	      pEvent[i].u.expose.window = realWin;
+	      pEvent[i].u.expose.x += x;
+	      pEvent[i].u.expose.y += y;
+	  }
+    }
+#endif
+
+    DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+    DEALLOCATE_LOCAL(pEvent);
+}
+
+void 
+miWindowExposures(pWin, prgn, other_exposed)
+    WindowPtr pWin;
+    register RegionPtr prgn, other_exposed;
+{
+#ifdef NXAGENT_SERVER
+
+    int total;
+
+#endif
+    RegionPtr   exposures = prgn;
+    if (pWin->backStorage && prgn)
+	/*
+	 * in some cases, backing store will cause a different
+	 * region to be exposed than needs to be repainted
+	 * (like when a window is mapped).  RestoreAreas is
+	 * allowed to return a region other than prgn,
+	 * in which case this routine will free the resultant
+	 * region.  If exposures is null, then no events will
+	 * be sent to the client; if prgn is empty
+	 * no areas will be repainted.
+	 */
+	exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+    if ((prgn && !REGION_NIL(prgn)) || 
+	(exposures && !REGION_NIL(exposures)) || other_exposed)
+    {
+	RegionRec   expRec;
+	int	    clientInterested;
+
+	/*
+	 * Restore from backing-store FIRST.
+	 */
+	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+	if (other_exposed)
+	{
+	    if (exposures)
+	    {
+		REGION_UNION(pWin->drawable.pScreen, other_exposed,
+						  exposures,
+					          other_exposed);
+		if (exposures != prgn)
+		    REGION_DESTROY(pWin->drawable.pScreen, exposures);
+	    }
+	    exposures = other_exposed;
+	}
+#ifdef NXAGENT_SERVER
+
+        /*
+         * If the number of rectangles is greater
+         * than 4, let the function decide.
+         */
+
+        total = REGION_NUM_RECTS(exposures);
+
+        if (clientInterested && exposures && (total > RECTLIMIT ||
+                (total > 4 && nxagentExtentsPredicate(total) == 1)))
+#else
+	if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+#endif
+	{
+	    /*
+	     * If we have LOTS of rectangles, we decide to take the extents
+	     * and force an exposure on that.  This should require much less
+	     * work overall, on both client and server.  This is cheating, but
+	     * isn't prohibited by the protocol ("spontaneous combustion" :-).
+	     */
+	    BoxRec box;
+
+	    box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+	    if (exposures == prgn) {
+		exposures = &expRec;
+		REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+		REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+	    } else {
+		REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+		REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+	    }
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+	    /* need to clear out new areas of backing store, too */
+	    if (pWin->backStorage)
+		(void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					     pWin,
+					     box.x1 - pWin->drawable.x,
+					     box.y1 - pWin->drawable.y,
+					     box.x2 - box.x1,
+					     box.y2 - box.y1,
+					     FALSE);
+	}
+	if (prgn && !REGION_NIL(prgn))
+	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+	if (clientInterested && exposures && !REGION_NIL(exposures))
+	    miSendExposures(pWin, exposures,
+			    pWin->drawable.x, pWin->drawable.y);
+	if (exposures == &expRec)
+	{
+	    REGION_UNINIT( pWin->drawable.pScreen, exposures);
+	}
+	else if (exposures && exposures != prgn && exposures != other_exposed)
+	    REGION_DESTROY( pWin->drawable.pScreen, exposures);
+	if (prgn)
+	    REGION_EMPTY( pWin->drawable.pScreen, prgn);
+    }
+    else if (exposures && exposures != prgn)
+	REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+    this code is highly unlikely.  it is not haile selassie.
+
+    there is some hair here.  we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used.  it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr	screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+    pointer value,
+    XID id)
+{
+    GCPtr pGC = (GCPtr)value;
+    screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+    FreeGC (pGC, id);
+    numGCs--;
+    if (!numGCs)
+	ResType = 0;
+
+    return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+    int	status;
+
+    Bool usingScratchGC = FALSE;
+    WindowPtr pRoot;
+	
+#define FUNCTION	0
+#define FOREGROUND	1
+#define TILE		2
+#define FILLSTYLE	3
+#define ABSX		4
+#define ABSY		5
+#define CLIPMASK	6
+#define SUBWINDOW	7
+#define COUNT_BITS	8
+
+    ChangeGCVal gcval[7];
+    ChangeGCVal newValues [COUNT_BITS];
+
+    BITS32 gcmask, index, mask;
+    RegionRec prgnWin;
+    DDXPointRec oldCorner;
+    BoxRec box;
+    WindowPtr	pBgWin;
+    GCPtr pGC;
+    register int i;
+    register BoxPtr pbox;
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    register xRectangle *prect;
+    int numRects;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    prgnWin.extents.x1 = 0;
+    prgnWin.extents.y1 = 0;
+    prgnWin.extents.x2 = 0;
+    prgnWin.extents.y2 = 0;
+
+    prgnWin.data = NULL;
+
+    oldCorner.x = 0;
+    oldCorner.y = 0;
+
+#endif
+
+    gcmask = 0;
+
+    if (what == PW_BACKGROUND)
+    {
+	switch (pWin->backgroundState) {
+	case None:
+	    return;
+	case ParentRelative:
+	    (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+	    return;
+	case BackgroundPixel:
+	    newValues[FOREGROUND].val = pWin->background.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	    break;
+	case BackgroundPixmap:
+	    newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	    break;
+	}
+    }
+    else
+    {
+	if (pWin->borderIsPixel)
+	{
+	    newValues[FOREGROUND].val = pWin->border.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	}
+	else
+	{
+	    newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	}
+    }
+
+    prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+					 sizeof(xRectangle));
+    if (!prect)
+	return;
+
+    newValues[FUNCTION].val = GXcopy;
+    gcmask |= GCFunction | GCClipMask;
+
+    i = pScreen->myNum;
+    pRoot = WindowTable[i];
+
+    pBgWin = pWin;
+    if (what == PW_BORDER)
+    {
+	while (pBgWin->backgroundState == ParentRelative)
+	    pBgWin = pBgWin->parent;
+    }
+
+    if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+	(pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+    {
+	usingScratchGC = TRUE;
+	pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+	if (!pGC)
+	{
+	    DEALLOCATE_LOCAL(prect);
+	    return;
+	}
+	/*
+	 * mash the clip list so we can paint the border by
+	 * mangling the window in place, pretending it
+	 * spans the entire screen
+	 */
+	if (what == PW_BORDER)
+	{
+	    prgnWin = pWin->clipList;
+	    oldCorner.x = pWin->drawable.x;
+	    oldCorner.y = pWin->drawable.y;
+	    pWin->drawable.x = pWin->drawable.y = 0;
+	    box.x1 = 0;
+	    box.y1 = 0;
+	    box.x2 = pScreen->width;
+	    box.y2 = pScreen->height;
+	    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    newValues[ABSX].val = pBgWin->drawable.x;
+	    newValues[ABSY].val = pBgWin->drawable.y;
+	}
+	else
+	{
+	    newValues[ABSX].val = 0;
+	    newValues[ABSY].val = 0;
+	}
+    } else {
+	/*
+	 * draw the background to the root window
+	 */
+	if (screenContext[i] == (GCPtr)NULL)
+	{
+	    if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+		return;
+	    screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+					(XID *)NULL, &status);
+	    if (!screenContext[i])
+		return;
+	    numGCs++;
+	    if (!AddResource(FakeClientID(0), ResType,
+			     (pointer)screenContext[i]))
+	        return;
+	}
+	pGC = screenContext[i];
+	newValues[SUBWINDOW].val = IncludeInferiors;
+	newValues[ABSX].val = pBgWin->drawable.x;
+	newValues[ABSY].val = pBgWin->drawable.y;
+	gcmask |= GCSubwindowMode;
+	pWin = pRoot;
+    }
+    
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+    mask = gcmask;
+    gcmask = 0;
+    i = 0;
+    while (mask) {
+    	index = lowbit (mask);
+	mask &= ~index;
+	switch (index) {
+	case GCFunction:
+	    if (pGC->alu != newValues[FUNCTION].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FUNCTION].val;
+	    }
+	    break;
+	case GCTileStipXOrigin:
+	    if ( pGC->patOrg.x != newValues[ABSX].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSX].val;
+	    }
+	    break;
+	case GCTileStipYOrigin:
+	    if ( pGC->patOrg.y != newValues[ABSY].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSY].val;
+	    }
+	    break;
+	case GCClipMask:
+	    if ( pGC->clientClipType != CT_NONE) {
+		gcmask |= index;
+		gcval[i++].val = CT_NONE;
+	    }
+	    break;
+	case GCSubwindowMode:
+	    if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[SUBWINDOW].val;
+	    }
+	    break;
+	case GCTile:
+	    if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ 	    {
+		gcmask |= index;
+		gcval[i++].ptr = newValues[TILE].ptr;
+	    }
+	    break;
+	case GCFillStyle:
+	    if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FILLSTYLE].val;
+	    }
+	    break;
+	case GCForeground:
+	    if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FOREGROUND].val;
+	    }
+	    break;
+	}
+    }
+
+    if (gcmask)
+        dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+    if (pWin->drawable.serialNumber != pGC->serialNumber)
+	ValidateGC((DrawablePtr)pWin, pGC);
+
+    numRects = REGION_NUM_RECTS(prgn);
+    pbox = REGION_RECTS(prgn);
+    for (i= numRects; --i >= 0; pbox++, prect++)
+    {
+	prect->x = pbox->x1 - pWin->drawable.x;
+	prect->y = pbox->y1 - pWin->drawable.y;
+	prect->width = pbox->x2 - pbox->x1;
+	prect->height = pbox->y2 - pbox->y1;
+    }
+    prect -= numRects;
+    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+    DEALLOCATE_LOCAL(prect);
+
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+    if (usingScratchGC)
+    {
+	if (what == PW_BORDER)
+	{
+	    REGION_UNINIT(pScreen, &pWin->clipList);
+	    pWin->clipList = prgnWin;
+	    pWin->drawable.x = oldCorner.x;
+	    pWin->drawable.y = oldCorner.y;
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	}
+	FreeScratchGC(pGC);
+    }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC.  Useful when we have a scratch drawable and need to initialize 
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+    DrawablePtr	pDraw;
+    GCPtr	pGC;
+{
+    XID fg = pGC->fgPixel;
+    XID bg = pGC->bgPixel;
+    xRectangle rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = pDraw->width;
+    rect.height = pDraw->height;
+    DoChangeGC(pGC, GCForeground, &bg, 0);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+    DoChangeGC(pGC, GCForeground, &fg, 0);
+    ValidateGC(pDraw, pGC);
+}
+
+#endif /* NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.NX.original
new file mode 100644
index 000000000..bd068170c
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.NX.original
@@ -0,0 +1,938 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiexpose.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9 2001/12/14 20:00:22 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "Xprotostr.h"
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include "Xmd.h"
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+    machine-independent graphics exposure code.  any device that uses
+the region package can call this.
+*/
+
+#ifdef NXAGENT_SERVER
+
+#include "Windows.h"
+
+#endif
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25		/* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures 
+    generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination.  Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+     this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+     added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+		  pGC, srcx, srcy, width, height, dstx, dsty, plane)
+    register DrawablePtr	pSrcDrawable;
+    register DrawablePtr	pDstDrawable;
+    GCPtr 			pGC;
+    int 			srcx, srcy;
+    int 			width, height;
+    int 			dstx, dsty;
+    unsigned long		plane;
+{
+    register ScreenPtr pscr;
+    RegionPtr prgnSrcClip;	/* drawable-relative source clip */
+    RegionRec rgnSrcRec;
+    RegionPtr prgnDstClip;	/* drawable-relative dest clip */
+    RegionRec rgnDstRec;
+    BoxRec srcBox;		/* unclipped source */
+    RegionRec rgnExposed;	/* exposed region, calculated source-
+				   relative, made dst relative to
+				   intersect with visible parts of
+				   dest and send events to client, 
+				   and then screen relative to paint 
+				   the window background
+				*/
+    WindowPtr pSrcWin;
+    BoxRec expBox;
+    Bool extents;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    expBox.x1 = 0;
+    expBox.y1 = 0;
+    expBox.x2 = 0;
+    expBox.y2 = 0;
+
+#endif
+
+    /* This prevents warning about pscr not being used. */
+    pGC->pScreen = pscr = pGC->pScreen;
+
+    /* avoid work if we can */
+    if (!pGC->graphicsExposures &&
+	(pDstDrawable->type == DRAWABLE_PIXMAP) &&
+	((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+	 (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+	return NULL;
+	
+    srcBox.x1 = srcx;
+    srcBox.y1 = srcy;
+    srcBox.x2 = srcx+width;
+    srcBox.y2 = srcy+height;
+
+    if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+    {
+	BoxRec TsrcBox;
+
+	TsrcBox.x1 = srcx + pSrcDrawable->x;
+	TsrcBox.y1 = srcy + pSrcDrawable->y;
+	TsrcBox.x2 = TsrcBox.x1 + width;
+	TsrcBox.y2 = TsrcBox.y1 + height;
+	pSrcWin = (WindowPtr) pSrcDrawable;
+	if (pGC->subWindowMode == IncludeInferiors)
+ 	{
+	    prgnSrcClip = NotClippedByChildren (pSrcWin);
+	    if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+	    {
+		REGION_DESTROY(pscr, prgnSrcClip);
+		return NULL;
+	    }
+	}
+ 	else
+ 	{
+	    if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+		return NULL;
+	    prgnSrcClip = &rgnSrcRec;
+	    REGION_INIT(pscr, prgnSrcClip, NullBox, 0);
+	    REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnSrcClip,
+				-pSrcDrawable->x, -pSrcDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+	    (srcBox.x2 <= pSrcDrawable->width) &&
+ 	    (srcBox.y2 <= pSrcDrawable->height))
+	    return NULL;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pSrcDrawable->width;
+	box.y2 = pSrcDrawable->height;
+	prgnSrcClip = &rgnSrcRec;
+	REGION_INIT(pscr, prgnSrcClip, &box, 1);
+	pSrcWin = (WindowPtr)NULL;
+    }
+
+    if (pDstDrawable == pSrcDrawable)
+    {
+	prgnDstClip = prgnSrcClip;
+    }
+    else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+    {
+	if (pGC->subWindowMode == IncludeInferiors)
+	{
+	    prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+	}
+	else
+	{
+	    prgnDstClip = &rgnDstRec;
+	    REGION_INIT(pscr, prgnDstClip, NullBox, 0);
+	    REGION_COPY(pscr, prgnDstClip,
+				&((WindowPtr)pDstDrawable)->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnDstClip,
+				 -pDstDrawable->x, -pDstDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pDstDrawable->width;
+	box.y2 = pDstDrawable->height;
+	prgnDstClip = &rgnDstRec;
+	REGION_INIT(pscr, prgnDstClip, &box, 1);
+    }
+
+    /* drawable-relative source region */
+    REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+    /* now get the hidden parts of the source box*/
+    REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+    if (pSrcWin && pSrcWin->backStorage)
+    {
+	/*
+	 * Copy any areas from the source backing store. Modifies
+	 * rgnExposed.
+	 */
+	(* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+					      pDstDrawable,
+					      pGC,
+					      &rgnExposed,
+					      srcx, srcy,
+					      dstx, dsty,
+					      plane);
+    }
+    
+    /* move them over the destination */
+    REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+    /* intersect with visible areas of dest */
+    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+    /*
+     * If we have LOTS of rectangles, we decide to take the extents
+     * and force an exposure on that.  This should require much less
+     * work overall, on both client and server.  This is cheating, but
+     * isn't prohibited by the protocol ("spontaneous combustion" :-)
+     * for windows.
+     */
+    extents = pGC->graphicsExposures &&
+	      (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+	      (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+    if (pSrcWin)
+    {
+	RegionPtr	region;
+    	if (!(region = wClipShape (pSrcWin)))
+    	    region = wBoundingShape (pSrcWin);
+    	/*
+     	 * If you try to CopyArea the extents of a shaped window, compacting the
+     	 * exposed region will undo all our work!
+     	 */
+    	if (extents && pSrcWin && region &&
+    	    (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+	    	extents = FALSE;
+    }
+#endif
+    if (extents)
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+	REGION_RESET(pscr, &rgnExposed, &expBox);
+	/* need to clear out new areas of backing store */
+	if (pWin->backStorage)
+	    (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					 pWin,
+					 expBox.x1,
+					 expBox.y1,
+					 expBox.x2 - expBox.x1,
+					 expBox.y2 - expBox.y1,
+					 FALSE);
+    }
+    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+	(((WindowPtr)pDstDrawable)->backgroundState != None))
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	/* make the exposed area screen-relative */
+	REGION_TRANSLATE(pscr, &rgnExposed, 
+				 pDstDrawable->x, pDstDrawable->y);
+
+	if (extents)
+	{
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+	}
+	(*pWin->drawable.pScreen->PaintWindowBackground)(
+			(WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+	if (extents)
+	{
+	    REGION_RESET(pscr, &rgnExposed, &expBox);
+	}
+	else
+	    REGION_TRANSLATE(pscr, &rgnExposed,
+				     -pDstDrawable->x, -pDstDrawable->y);
+    }
+    if (prgnDstClip == &rgnDstRec)
+    {
+	REGION_UNINIT(pscr, prgnDstClip);
+    }
+    else if (prgnDstClip != prgnSrcClip)
+    {
+	REGION_DESTROY(pscr, prgnDstClip);
+    }
+
+    if (prgnSrcClip == &rgnSrcRec)
+    {
+	REGION_UNINIT(pscr, prgnSrcClip);
+    }
+    else
+    {
+	REGION_DESTROY(pscr, prgnSrcClip);
+    }
+
+    if (pGC->graphicsExposures)
+    {
+	/* don't look */
+	RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+	*exposed = rgnExposed;
+	return exposed;
+    }
+    else
+    {
+	REGION_UNINIT(pscr, &rgnExposed);
+	return NULL;
+    }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+    ClientPtr	client;
+    RegionPtr	pRgn;
+    XID		drawable;
+    int	major;
+    int	minor;
+{
+    if (pRgn && !REGION_NIL(pRgn))
+    {
+        xEvent *pEvent;
+	register xEvent *pe;
+	register BoxPtr pBox;
+	register int i;
+	int numRects;
+
+	numRects = REGION_NUM_RECTS(pRgn);
+	pBox = REGION_RECTS(pRgn);
+	if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+		return;
+	pe = pEvent;
+
+	for (i=1; i<=numRects; i++, pe++, pBox++)
+	{
+	    pe->u.u.type = GraphicsExpose;
+	    pe->u.graphicsExposure.drawable = drawable;
+	    pe->u.graphicsExposure.x = pBox->x1;
+	    pe->u.graphicsExposure.y = pBox->y1;
+	    pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+	    pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+	    pe->u.graphicsExposure.count = numRects - i;
+	    pe->u.graphicsExposure.majorEvent = major;
+	    pe->u.graphicsExposure.minorEvent = minor;
+	}
+	TryClientEvents(client, pEvent, numRects,
+			    (Mask)0, NoEventMask, NullGrab);
+	DEALLOCATE_LOCAL(pEvent);
+    }
+    else
+    {
+        xEvent event;
+	event.u.u.type = NoExpose;
+	event.u.noExposure.drawable = drawable;
+	event.u.noExposure.majorEvent = major;
+	event.u.noExposure.minorEvent = minor;
+	TryClientEvents(client, &event, 1,
+	    (Mask)0, NoEventMask, NullGrab);
+    }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+    WindowPtr pWin;
+    RegionPtr pRgn;
+    register int dx, dy;
+{
+    register BoxPtr pBox;
+    int numRects;
+    register xEvent *pEvent, *pe;
+    register int i;
+
+    pBox = REGION_RECTS(pRgn);
+    numRects = REGION_NUM_RECTS(pRgn);
+    if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+	return;
+
+    for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+    {
+	pe->u.u.type = Expose;
+	pe->u.expose.window = pWin->drawable.id;
+	pe->u.expose.x = pBox->x1 - dx;
+	pe->u.expose.y = pBox->y1 - dy;
+	pe->u.expose.width = pBox->x2 - pBox->x1;
+	pe->u.expose.height = pBox->y2 - pBox->y1;
+	pe->u.expose.count = i;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	int scrnum = pWin->drawable.pScreen->myNum;
+	int x = 0, y = 0;
+	XID realWin = 0;
+
+	if(!pWin->parent) {
+	    x = panoramiXdataPtr[scrnum].x;
+	    y = panoramiXdataPtr[scrnum].y;
+	    pWin = WindowTable[0];
+	    realWin = pWin->drawable.id;
+	} else if (scrnum) {
+	    PanoramiXRes *win;
+	    win = PanoramiXFindIDByScrnum(XRT_WINDOW, 
+			pWin->drawable.id, scrnum);
+	    if(!win) {
+		DEALLOCATE_LOCAL(pEvent);
+		return;
+	    }
+	    realWin = win->info[0].id;
+	    pWin = LookupIDByType(realWin, RT_WINDOW);
+	}
+	if(x || y || scrnum)
+	  for (i = 0; i < numRects; i++) {
+	      pEvent[i].u.expose.window = realWin;
+	      pEvent[i].u.expose.x += x;
+	      pEvent[i].u.expose.y += y;
+	  }
+    }
+#endif
+
+    DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+    DEALLOCATE_LOCAL(pEvent);
+}
+
+void 
+miWindowExposures(pWin, prgn, other_exposed)
+    WindowPtr pWin;
+    register RegionPtr prgn, other_exposed;
+{
+#ifdef NXAGENT_SERVER
+
+    int total;
+
+#endif
+    RegionPtr   exposures = prgn;
+    if (pWin->backStorage && prgn)
+	/*
+	 * in some cases, backing store will cause a different
+	 * region to be exposed than needs to be repainted
+	 * (like when a window is mapped).  RestoreAreas is
+	 * allowed to return a region other than prgn,
+	 * in which case this routine will free the resultant
+	 * region.  If exposures is null, then no events will
+	 * be sent to the client; if prgn is empty
+	 * no areas will be repainted.
+	 */
+	exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+    if ((prgn && !REGION_NIL(prgn)) || 
+	(exposures && !REGION_NIL(exposures)) || other_exposed)
+    {
+	RegionRec   expRec;
+	int	    clientInterested;
+
+	/*
+	 * Restore from backing-store FIRST.
+	 */
+	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+	if (other_exposed)
+	{
+	    if (exposures)
+	    {
+		REGION_UNION(pWin->drawable.pScreen, other_exposed,
+						  exposures,
+					          other_exposed);
+		if (exposures != prgn)
+		    REGION_DESTROY(pWin->drawable.pScreen, exposures);
+	    }
+	    exposures = other_exposed;
+	}
+#ifdef NXAGENT_SERVER
+
+        /*
+         * If the number of rectangles is greater
+         * than 4, let the function decide.
+         */
+
+        total = REGION_NUM_RECTS(exposures);
+
+        if (clientInterested && exposures && (total > RECTLIMIT ||
+                (total > 4 && nxagentExtentsPredicate(total) == 1)))
+#else
+	if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+#endif
+	{
+	    /*
+	     * If we have LOTS of rectangles, we decide to take the extents
+	     * and force an exposure on that.  This should require much less
+	     * work overall, on both client and server.  This is cheating, but
+	     * isn't prohibited by the protocol ("spontaneous combustion" :-).
+	     */
+	    BoxRec box;
+
+	    box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+	    if (exposures == prgn) {
+		exposures = &expRec;
+		REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+		REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+	    } else {
+		REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+		REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+	    }
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+	    /* need to clear out new areas of backing store, too */
+	    if (pWin->backStorage)
+		(void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					     pWin,
+					     box.x1 - pWin->drawable.x,
+					     box.y1 - pWin->drawable.y,
+					     box.x2 - box.x1,
+					     box.y2 - box.y1,
+					     FALSE);
+	}
+	if (prgn && !REGION_NIL(prgn))
+	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+	if (clientInterested && exposures && !REGION_NIL(exposures))
+	    miSendExposures(pWin, exposures,
+			    pWin->drawable.x, pWin->drawable.y);
+	if (exposures == &expRec)
+	{
+	    REGION_UNINIT( pWin->drawable.pScreen, exposures);
+	}
+	else if (exposures && exposures != prgn && exposures != other_exposed)
+	    REGION_DESTROY( pWin->drawable.pScreen, exposures);
+	if (prgn)
+	    REGION_EMPTY( pWin->drawable.pScreen, prgn);
+    }
+    else if (exposures && exposures != prgn)
+	REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+    this code is highly unlikely.  it is not haile selassie.
+
+    there is some hair here.  we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used.  it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr	screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+    pointer value,
+    XID id)
+{
+    GCPtr pGC = (GCPtr)value;
+    screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+    FreeGC (pGC, id);
+    numGCs--;
+    if (!numGCs)
+	ResType = 0;
+
+    return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+    int	status;
+
+    Bool usingScratchGC = FALSE;
+    WindowPtr pRoot;
+	
+#define FUNCTION	0
+#define FOREGROUND	1
+#define TILE		2
+#define FILLSTYLE	3
+#define ABSX		4
+#define ABSY		5
+#define CLIPMASK	6
+#define SUBWINDOW	7
+#define COUNT_BITS	8
+
+    ChangeGCVal gcval[7];
+    ChangeGCVal newValues [COUNT_BITS];
+
+    BITS32 gcmask, index, mask;
+    RegionRec prgnWin;
+    DDXPointRec oldCorner;
+    BoxRec box;
+    WindowPtr	pBgWin;
+    GCPtr pGC;
+    register int i;
+    register BoxPtr pbox;
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    register xRectangle *prect;
+    int numRects;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    prgnWin.extents.x1 = 0;
+    prgnWin.extents.y1 = 0;
+    prgnWin.extents.x2 = 0;
+    prgnWin.extents.y2 = 0;
+
+    prgnWin.data = NULL;
+
+    oldCorner.x = 0;
+    oldCorner.y = 0;
+
+#endif
+
+    gcmask = 0;
+
+    if (what == PW_BACKGROUND)
+    {
+	switch (pWin->backgroundState) {
+	case None:
+	    return;
+	case ParentRelative:
+	    (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+	    return;
+	case BackgroundPixel:
+	    newValues[FOREGROUND].val = pWin->background.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	    break;
+	case BackgroundPixmap:
+	    newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	    break;
+	}
+    }
+    else
+    {
+	if (pWin->borderIsPixel)
+	{
+	    newValues[FOREGROUND].val = pWin->border.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	}
+	else
+	{
+	    newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	}
+    }
+
+    prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+					 sizeof(xRectangle));
+    if (!prect)
+	return;
+
+    newValues[FUNCTION].val = GXcopy;
+    gcmask |= GCFunction | GCClipMask;
+
+    i = pScreen->myNum;
+    pRoot = WindowTable[i];
+
+    pBgWin = pWin;
+    if (what == PW_BORDER)
+    {
+	while (pBgWin->backgroundState == ParentRelative)
+	    pBgWin = pBgWin->parent;
+    }
+
+    if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+	(pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+    {
+	usingScratchGC = TRUE;
+	pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+	if (!pGC)
+	{
+	    DEALLOCATE_LOCAL(prect);
+	    return;
+	}
+	/*
+	 * mash the clip list so we can paint the border by
+	 * mangling the window in place, pretending it
+	 * spans the entire screen
+	 */
+	if (what == PW_BORDER)
+	{
+	    prgnWin = pWin->clipList;
+	    oldCorner.x = pWin->drawable.x;
+	    oldCorner.y = pWin->drawable.y;
+	    pWin->drawable.x = pWin->drawable.y = 0;
+	    box.x1 = 0;
+	    box.y1 = 0;
+	    box.x2 = pScreen->width;
+	    box.y2 = pScreen->height;
+	    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    newValues[ABSX].val = pBgWin->drawable.x;
+	    newValues[ABSY].val = pBgWin->drawable.y;
+	}
+	else
+	{
+	    newValues[ABSX].val = 0;
+	    newValues[ABSY].val = 0;
+	}
+    } else {
+	/*
+	 * draw the background to the root window
+	 */
+	if (screenContext[i] == (GCPtr)NULL)
+	{
+	    if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+		return;
+	    screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+					(XID *)NULL, &status);
+	    if (!screenContext[i])
+		return;
+	    numGCs++;
+	    if (!AddResource(FakeClientID(0), ResType,
+			     (pointer)screenContext[i]))
+	        return;
+	}
+	pGC = screenContext[i];
+	newValues[SUBWINDOW].val = IncludeInferiors;
+	newValues[ABSX].val = pBgWin->drawable.x;
+	newValues[ABSY].val = pBgWin->drawable.y;
+	gcmask |= GCSubwindowMode;
+	pWin = pRoot;
+    }
+    
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+    mask = gcmask;
+    gcmask = 0;
+    i = 0;
+    while (mask) {
+    	index = lowbit (mask);
+	mask &= ~index;
+	switch (index) {
+	case GCFunction:
+	    if (pGC->alu != newValues[FUNCTION].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FUNCTION].val;
+	    }
+	    break;
+	case GCTileStipXOrigin:
+	    if ( pGC->patOrg.x != newValues[ABSX].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSX].val;
+	    }
+	    break;
+	case GCTileStipYOrigin:
+	    if ( pGC->patOrg.y != newValues[ABSY].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSY].val;
+	    }
+	    break;
+	case GCClipMask:
+	    if ( pGC->clientClipType != CT_NONE) {
+		gcmask |= index;
+		gcval[i++].val = CT_NONE;
+	    }
+	    break;
+	case GCSubwindowMode:
+	    if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[SUBWINDOW].val;
+	    }
+	    break;
+	case GCTile:
+	    if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ 	    {
+		gcmask |= index;
+		gcval[i++].ptr = newValues[TILE].ptr;
+	    }
+	    break;
+	case GCFillStyle:
+	    if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FILLSTYLE].val;
+	    }
+	    break;
+	case GCForeground:
+	    if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FOREGROUND].val;
+	    }
+	    break;
+	}
+    }
+
+    if (gcmask)
+        dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+    if (pWin->drawable.serialNumber != pGC->serialNumber)
+	ValidateGC((DrawablePtr)pWin, pGC);
+
+    numRects = REGION_NUM_RECTS(prgn);
+    pbox = REGION_RECTS(prgn);
+    for (i= numRects; --i >= 0; pbox++, prect++)
+    {
+	prect->x = pbox->x1 - pWin->drawable.x;
+	prect->y = pbox->y1 - pWin->drawable.y;
+	prect->width = pbox->x2 - pbox->x1;
+	prect->height = pbox->y2 - pbox->y1;
+    }
+    prect -= numRects;
+    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+    DEALLOCATE_LOCAL(prect);
+
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+    if (usingScratchGC)
+    {
+	if (what == PW_BORDER)
+	{
+	    REGION_UNINIT(pScreen, &pWin->clipList);
+	    pWin->clipList = prgnWin;
+	    pWin->drawable.x = oldCorner.x;
+	    pWin->drawable.y = oldCorner.y;
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	}
+	FreeScratchGC(pGC);
+    }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC.  Useful when we have a scratch drawable and need to initialize 
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+    DrawablePtr	pDraw;
+    GCPtr	pGC;
+{
+    XID fg = pGC->fgPixel;
+    XID bg = pGC->bgPixel;
+    xRectangle rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = pDraw->width;
+    rect.height = pDraw->height;
+    DoChangeGC(pGC, GCForeground, &bg, 0);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+    DoChangeGC(pGC, GCForeground, &fg, 0);
+    ValidateGC(pDraw, pGC);
+}
+
+#endif /* NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.XF86.original
new file mode 100644
index 000000000..ca896b9e0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiexpose.c.XF86.original
@@ -0,0 +1,873 @@
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9 2001/12/14 20:00:22 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "Xprotostr.h"
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include "Xmd.h"
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+    machine-independent graphics exposure code.  any device that uses
+the region package can call this.
+*/
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25		/* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures 
+    generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination.  Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+     this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+     added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+		  pGC, srcx, srcy, width, height, dstx, dsty, plane)
+    register DrawablePtr	pSrcDrawable;
+    register DrawablePtr	pDstDrawable;
+    GCPtr 			pGC;
+    int 			srcx, srcy;
+    int 			width, height;
+    int 			dstx, dsty;
+    unsigned long		plane;
+{
+    register ScreenPtr pscr;
+    RegionPtr prgnSrcClip;	/* drawable-relative source clip */
+    RegionRec rgnSrcRec;
+    RegionPtr prgnDstClip;	/* drawable-relative dest clip */
+    RegionRec rgnDstRec;
+    BoxRec srcBox;		/* unclipped source */
+    RegionRec rgnExposed;	/* exposed region, calculated source-
+				   relative, made dst relative to
+				   intersect with visible parts of
+				   dest and send events to client, 
+				   and then screen relative to paint 
+				   the window background
+				*/
+    WindowPtr pSrcWin;
+    BoxRec expBox;
+    Bool extents;
+
+    /* This prevents warning about pscr not being used. */
+    pGC->pScreen = pscr = pGC->pScreen;
+
+    /* avoid work if we can */
+    if (!pGC->graphicsExposures &&
+	(pDstDrawable->type == DRAWABLE_PIXMAP) &&
+	((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+	 (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+	return NULL;
+	
+    srcBox.x1 = srcx;
+    srcBox.y1 = srcy;
+    srcBox.x2 = srcx+width;
+    srcBox.y2 = srcy+height;
+
+    if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+    {
+	BoxRec TsrcBox;
+
+	TsrcBox.x1 = srcx + pSrcDrawable->x;
+	TsrcBox.y1 = srcy + pSrcDrawable->y;
+	TsrcBox.x2 = TsrcBox.x1 + width;
+	TsrcBox.y2 = TsrcBox.y1 + height;
+	pSrcWin = (WindowPtr) pSrcDrawable;
+	if (pGC->subWindowMode == IncludeInferiors)
+ 	{
+	    prgnSrcClip = NotClippedByChildren (pSrcWin);
+	    if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+	    {
+		REGION_DESTROY(pscr, prgnSrcClip);
+		return NULL;
+	    }
+	}
+ 	else
+ 	{
+	    if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+		return NULL;
+	    prgnSrcClip = &rgnSrcRec;
+	    REGION_INIT(pscr, prgnSrcClip, NullBox, 0);
+	    REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnSrcClip,
+				-pSrcDrawable->x, -pSrcDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+	    (srcBox.x2 <= pSrcDrawable->width) &&
+ 	    (srcBox.y2 <= pSrcDrawable->height))
+	    return NULL;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pSrcDrawable->width;
+	box.y2 = pSrcDrawable->height;
+	prgnSrcClip = &rgnSrcRec;
+	REGION_INIT(pscr, prgnSrcClip, &box, 1);
+	pSrcWin = (WindowPtr)NULL;
+    }
+
+    if (pDstDrawable == pSrcDrawable)
+    {
+	prgnDstClip = prgnSrcClip;
+    }
+    else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+    {
+	if (pGC->subWindowMode == IncludeInferiors)
+	{
+	    prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+	}
+	else
+	{
+	    prgnDstClip = &rgnDstRec;
+	    REGION_INIT(pscr, prgnDstClip, NullBox, 0);
+	    REGION_COPY(pscr, prgnDstClip,
+				&((WindowPtr)pDstDrawable)->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnDstClip,
+				 -pDstDrawable->x, -pDstDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pDstDrawable->width;
+	box.y2 = pDstDrawable->height;
+	prgnDstClip = &rgnDstRec;
+	REGION_INIT(pscr, prgnDstClip, &box, 1);
+    }
+
+    /* drawable-relative source region */
+    REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+    /* now get the hidden parts of the source box*/
+    REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+    if (pSrcWin && pSrcWin->backStorage)
+    {
+	/*
+	 * Copy any areas from the source backing store. Modifies
+	 * rgnExposed.
+	 */
+	(* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+					      pDstDrawable,
+					      pGC,
+					      &rgnExposed,
+					      srcx, srcy,
+					      dstx, dsty,
+					      plane);
+    }
+    
+    /* move them over the destination */
+    REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+    /* intersect with visible areas of dest */
+    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+    /*
+     * If we have LOTS of rectangles, we decide to take the extents
+     * and force an exposure on that.  This should require much less
+     * work overall, on both client and server.  This is cheating, but
+     * isn't prohibited by the protocol ("spontaneous combustion" :-)
+     * for windows.
+     */
+    extents = pGC->graphicsExposures &&
+	      (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+	      (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+    if (pSrcWin)
+    {
+	RegionPtr	region;
+    	if (!(region = wClipShape (pSrcWin)))
+    	    region = wBoundingShape (pSrcWin);
+    	/*
+     	 * If you try to CopyArea the extents of a shaped window, compacting the
+     	 * exposed region will undo all our work!
+     	 */
+    	if (extents && pSrcWin && region &&
+    	    (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+	    	extents = FALSE;
+    }
+#endif
+    if (extents)
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+	REGION_RESET(pscr, &rgnExposed, &expBox);
+	/* need to clear out new areas of backing store */
+	if (pWin->backStorage)
+	    (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					 pWin,
+					 expBox.x1,
+					 expBox.y1,
+					 expBox.x2 - expBox.x1,
+					 expBox.y2 - expBox.y1,
+					 FALSE);
+    }
+    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+	(((WindowPtr)pDstDrawable)->backgroundState != None))
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	/* make the exposed area screen-relative */
+	REGION_TRANSLATE(pscr, &rgnExposed, 
+				 pDstDrawable->x, pDstDrawable->y);
+
+	if (extents)
+	{
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+	}
+	(*pWin->drawable.pScreen->PaintWindowBackground)(
+			(WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+	if (extents)
+	{
+	    REGION_RESET(pscr, &rgnExposed, &expBox);
+	}
+	else
+	    REGION_TRANSLATE(pscr, &rgnExposed,
+				     -pDstDrawable->x, -pDstDrawable->y);
+    }
+    if (prgnDstClip == &rgnDstRec)
+    {
+	REGION_UNINIT(pscr, prgnDstClip);
+    }
+    else if (prgnDstClip != prgnSrcClip)
+    {
+	REGION_DESTROY(pscr, prgnDstClip);
+    }
+
+    if (prgnSrcClip == &rgnSrcRec)
+    {
+	REGION_UNINIT(pscr, prgnSrcClip);
+    }
+    else
+    {
+	REGION_DESTROY(pscr, prgnSrcClip);
+    }
+
+    if (pGC->graphicsExposures)
+    {
+	/* don't look */
+	RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+	*exposed = rgnExposed;
+	return exposed;
+    }
+    else
+    {
+	REGION_UNINIT(pscr, &rgnExposed);
+	return NULL;
+    }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+    ClientPtr	client;
+    RegionPtr	pRgn;
+    XID		drawable;
+    int	major;
+    int	minor;
+{
+    if (pRgn && !REGION_NIL(pRgn))
+    {
+        xEvent *pEvent;
+	register xEvent *pe;
+	register BoxPtr pBox;
+	register int i;
+	int numRects;
+
+	numRects = REGION_NUM_RECTS(pRgn);
+	pBox = REGION_RECTS(pRgn);
+	if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+		return;
+	pe = pEvent;
+
+	for (i=1; i<=numRects; i++, pe++, pBox++)
+	{
+	    pe->u.u.type = GraphicsExpose;
+	    pe->u.graphicsExposure.drawable = drawable;
+	    pe->u.graphicsExposure.x = pBox->x1;
+	    pe->u.graphicsExposure.y = pBox->y1;
+	    pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+	    pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+	    pe->u.graphicsExposure.count = numRects - i;
+	    pe->u.graphicsExposure.majorEvent = major;
+	    pe->u.graphicsExposure.minorEvent = minor;
+	}
+	TryClientEvents(client, pEvent, numRects,
+			    (Mask)0, NoEventMask, NullGrab);
+	DEALLOCATE_LOCAL(pEvent);
+    }
+    else
+    {
+        xEvent event;
+	event.u.u.type = NoExpose;
+	event.u.noExposure.drawable = drawable;
+	event.u.noExposure.majorEvent = major;
+	event.u.noExposure.minorEvent = minor;
+	TryClientEvents(client, &event, 1,
+	    (Mask)0, NoEventMask, NullGrab);
+    }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+    WindowPtr pWin;
+    RegionPtr pRgn;
+    register int dx, dy;
+{
+    register BoxPtr pBox;
+    int numRects;
+    register xEvent *pEvent, *pe;
+    register int i;
+
+    pBox = REGION_RECTS(pRgn);
+    numRects = REGION_NUM_RECTS(pRgn);
+    if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+	return;
+
+    for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+    {
+	pe->u.u.type = Expose;
+	pe->u.expose.window = pWin->drawable.id;
+	pe->u.expose.x = pBox->x1 - dx;
+	pe->u.expose.y = pBox->y1 - dy;
+	pe->u.expose.width = pBox->x2 - pBox->x1;
+	pe->u.expose.height = pBox->y2 - pBox->y1;
+	pe->u.expose.count = i;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	int scrnum = pWin->drawable.pScreen->myNum;
+	int x = 0, y = 0;
+	XID realWin = 0;
+
+	if(!pWin->parent) {
+	    x = panoramiXdataPtr[scrnum].x;
+	    y = panoramiXdataPtr[scrnum].y;
+	    pWin = WindowTable[0];
+	    realWin = pWin->drawable.id;
+	} else if (scrnum) {
+	    PanoramiXRes *win;
+	    win = PanoramiXFindIDByScrnum(XRT_WINDOW, 
+			pWin->drawable.id, scrnum);
+	    if(!win) {
+		DEALLOCATE_LOCAL(pEvent);
+		return;
+	    }
+	    realWin = win->info[0].id;
+	    pWin = LookupIDByType(realWin, RT_WINDOW);
+	}
+	if(x || y || scrnum)
+	  for (i = 0; i < numRects; i++) {
+	      pEvent[i].u.expose.window = realWin;
+	      pEvent[i].u.expose.x += x;
+	      pEvent[i].u.expose.y += y;
+	  }
+    }
+#endif
+
+    DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+    DEALLOCATE_LOCAL(pEvent);
+}
+
+void 
+miWindowExposures(pWin, prgn, other_exposed)
+    WindowPtr pWin;
+    register RegionPtr prgn, other_exposed;
+{
+    RegionPtr   exposures = prgn;
+    if (pWin->backStorage && prgn)
+	/*
+	 * in some cases, backing store will cause a different
+	 * region to be exposed than needs to be repainted
+	 * (like when a window is mapped).  RestoreAreas is
+	 * allowed to return a region other than prgn,
+	 * in which case this routine will free the resultant
+	 * region.  If exposures is null, then no events will
+	 * be sent to the client; if prgn is empty
+	 * no areas will be repainted.
+	 */
+	exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+    if ((prgn && !REGION_NIL(prgn)) || 
+	(exposures && !REGION_NIL(exposures)) || other_exposed)
+    {
+	RegionRec   expRec;
+	int	    clientInterested;
+
+	/*
+	 * Restore from backing-store FIRST.
+	 */
+	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+	if (other_exposed)
+	{
+	    if (exposures)
+	    {
+		REGION_UNION(pWin->drawable.pScreen, other_exposed,
+						  exposures,
+					          other_exposed);
+		if (exposures != prgn)
+		    REGION_DESTROY(pWin->drawable.pScreen, exposures);
+	    }
+	    exposures = other_exposed;
+	}
+	if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+	{
+	    /*
+	     * If we have LOTS of rectangles, we decide to take the extents
+	     * and force an exposure on that.  This should require much less
+	     * work overall, on both client and server.  This is cheating, but
+	     * isn't prohibited by the protocol ("spontaneous combustion" :-).
+	     */
+	    BoxRec box;
+
+	    box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+	    if (exposures == prgn) {
+		exposures = &expRec;
+		REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+		REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+	    } else {
+		REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+		REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+	    }
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+	    /* need to clear out new areas of backing store, too */
+	    if (pWin->backStorage)
+		(void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					     pWin,
+					     box.x1 - pWin->drawable.x,
+					     box.y1 - pWin->drawable.y,
+					     box.x2 - box.x1,
+					     box.y2 - box.y1,
+					     FALSE);
+	}
+	if (prgn && !REGION_NIL(prgn))
+	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+	if (clientInterested && exposures && !REGION_NIL(exposures))
+	    miSendExposures(pWin, exposures,
+			    pWin->drawable.x, pWin->drawable.y);
+	if (exposures == &expRec)
+	{
+	    REGION_UNINIT( pWin->drawable.pScreen, exposures);
+	}
+	else if (exposures && exposures != prgn && exposures != other_exposed)
+	    REGION_DESTROY( pWin->drawable.pScreen, exposures);
+	if (prgn)
+	    REGION_EMPTY( pWin->drawable.pScreen, prgn);
+    }
+    else if (exposures && exposures != prgn)
+	REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+    this code is highly unlikely.  it is not haile selassie.
+
+    there is some hair here.  we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used.  it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr	screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+    pointer value,
+    XID id)
+{
+    GCPtr pGC = (GCPtr)value;
+    screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+    FreeGC (pGC, id);
+    numGCs--;
+    if (!numGCs)
+	ResType = 0;
+
+    return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+    int	status;
+
+    Bool usingScratchGC = FALSE;
+    WindowPtr pRoot;
+	
+#define FUNCTION	0
+#define FOREGROUND	1
+#define TILE		2
+#define FILLSTYLE	3
+#define ABSX		4
+#define ABSY		5
+#define CLIPMASK	6
+#define SUBWINDOW	7
+#define COUNT_BITS	8
+
+    ChangeGCVal gcval[7];
+    ChangeGCVal newValues [COUNT_BITS];
+
+    BITS32 gcmask, index, mask;
+    RegionRec prgnWin;
+    DDXPointRec oldCorner;
+    BoxRec box;
+    WindowPtr	pBgWin;
+    GCPtr pGC;
+    register int i;
+    register BoxPtr pbox;
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    register xRectangle *prect;
+    int numRects;
+
+    gcmask = 0;
+
+    if (what == PW_BACKGROUND)
+    {
+	switch (pWin->backgroundState) {
+	case None:
+	    return;
+	case ParentRelative:
+	    (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+	    return;
+	case BackgroundPixel:
+	    newValues[FOREGROUND].val = pWin->background.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	    break;
+	case BackgroundPixmap:
+	    newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	    break;
+	}
+    }
+    else
+    {
+	if (pWin->borderIsPixel)
+	{
+	    newValues[FOREGROUND].val = pWin->border.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	}
+	else
+	{
+	    newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	}
+    }
+
+    prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+					 sizeof(xRectangle));
+    if (!prect)
+	return;
+
+    newValues[FUNCTION].val = GXcopy;
+    gcmask |= GCFunction | GCClipMask;
+
+    i = pScreen->myNum;
+    pRoot = WindowTable[i];
+
+    pBgWin = pWin;
+    if (what == PW_BORDER)
+    {
+	while (pBgWin->backgroundState == ParentRelative)
+	    pBgWin = pBgWin->parent;
+    }
+
+    if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+	(pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+    {
+	usingScratchGC = TRUE;
+	pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+	if (!pGC)
+	{
+	    DEALLOCATE_LOCAL(prect);
+	    return;
+	}
+	/*
+	 * mash the clip list so we can paint the border by
+	 * mangling the window in place, pretending it
+	 * spans the entire screen
+	 */
+	if (what == PW_BORDER)
+	{
+	    prgnWin = pWin->clipList;
+	    oldCorner.x = pWin->drawable.x;
+	    oldCorner.y = pWin->drawable.y;
+	    pWin->drawable.x = pWin->drawable.y = 0;
+	    box.x1 = 0;
+	    box.y1 = 0;
+	    box.x2 = pScreen->width;
+	    box.y2 = pScreen->height;
+	    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    newValues[ABSX].val = pBgWin->drawable.x;
+	    newValues[ABSY].val = pBgWin->drawable.y;
+	}
+	else
+	{
+	    newValues[ABSX].val = 0;
+	    newValues[ABSY].val = 0;
+	}
+    } else {
+	/*
+	 * draw the background to the root window
+	 */
+	if (screenContext[i] == (GCPtr)NULL)
+	{
+	    if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+		return;
+	    screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+					(XID *)NULL, &status);
+	    if (!screenContext[i])
+		return;
+	    numGCs++;
+	    if (!AddResource(FakeClientID(0), ResType,
+			     (pointer)screenContext[i]))
+	        return;
+	}
+	pGC = screenContext[i];
+	newValues[SUBWINDOW].val = IncludeInferiors;
+	newValues[ABSX].val = pBgWin->drawable.x;
+	newValues[ABSY].val = pBgWin->drawable.y;
+	gcmask |= GCSubwindowMode;
+	pWin = pRoot;
+    }
+    
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+    mask = gcmask;
+    gcmask = 0;
+    i = 0;
+    while (mask) {
+    	index = lowbit (mask);
+	mask &= ~index;
+	switch (index) {
+	case GCFunction:
+	    if (pGC->alu != newValues[FUNCTION].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FUNCTION].val;
+	    }
+	    break;
+	case GCTileStipXOrigin:
+	    if ( pGC->patOrg.x != newValues[ABSX].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSX].val;
+	    }
+	    break;
+	case GCTileStipYOrigin:
+	    if ( pGC->patOrg.y != newValues[ABSY].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSY].val;
+	    }
+	    break;
+	case GCClipMask:
+	    if ( pGC->clientClipType != CT_NONE) {
+		gcmask |= index;
+		gcval[i++].val = CT_NONE;
+	    }
+	    break;
+	case GCSubwindowMode:
+	    if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[SUBWINDOW].val;
+	    }
+	    break;
+	case GCTile:
+	    if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ 	    {
+		gcmask |= index;
+		gcval[i++].ptr = newValues[TILE].ptr;
+	    }
+	    break;
+	case GCFillStyle:
+	    if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FILLSTYLE].val;
+	    }
+	    break;
+	case GCForeground:
+	    if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FOREGROUND].val;
+	    }
+	    break;
+	}
+    }
+
+    if (gcmask)
+        dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+    if (pWin->drawable.serialNumber != pGC->serialNumber)
+	ValidateGC((DrawablePtr)pWin, pGC);
+
+    numRects = REGION_NUM_RECTS(prgn);
+    pbox = REGION_RECTS(prgn);
+    for (i= numRects; --i >= 0; pbox++, prect++)
+    {
+	prect->x = pbox->x1 - pWin->drawable.x;
+	prect->y = pbox->y1 - pWin->drawable.y;
+	prect->width = pbox->x2 - pbox->x1;
+	prect->height = pbox->y2 - pbox->y1;
+    }
+    prect -= numRects;
+    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+    DEALLOCATE_LOCAL(prect);
+
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+    if (usingScratchGC)
+    {
+	if (what == PW_BORDER)
+	{
+	    REGION_UNINIT(pScreen, &pWin->clipList);
+	    pWin->clipList = prgnWin;
+	    pWin->drawable.x = oldCorner.x;
+	    pWin->drawable.y = oldCorner.y;
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	}
+	FreeScratchGC(pGC);
+    }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC.  Useful when we have a scratch drawable and need to initialize 
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+    DrawablePtr	pDraw;
+    GCPtr	pGC;
+{
+    XID fg = pGC->fgPixel;
+    XID bg = pGC->bgPixel;
+    xRectangle rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = pDraw->width;
+    rect.height = pDraw->height;
+    DoChangeGC(pGC, GCForeground, &bg, 0);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+    DoChangeGC(pGC, GCForeground, &fg, 0);
+    ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
new file mode 100644
index 000000000..2521ae5c7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
@@ -0,0 +1,322 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiglyph.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.6 2000/12/05 03:13:31 keithp Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+void
+miGlyphExtents (int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs,
+		BoxPtr		extents)
+{
+    int		x1, x2, y1, y2;
+    int		n;
+    GlyphPtr	glyph;
+    int		x, y;
+ 
+    x = 0;
+    y = 0;
+    extents->x1 = MAXSHORT;
+    extents->x2 = MINSHORT;
+    extents->y1 = MAXSHORT;
+    extents->y2 = MINSHORT;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+	    if (x1 < extents->x1)
+		extents->x1 = x1;
+	    if (x2 > extents->x2)
+		extents->x2 = x2;
+	    if (y1 < extents->y1)
+		extents->y1 = y1;
+	    if (y2 > extents->y2)
+		extents->y2 = y2;
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+    PixmapPtr	pPixmap = 0;
+    PicturePtr	pPicture;
+    PixmapPtr   pMaskPixmap = 0;
+    PicturePtr  pMask;
+    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    int		width = 0, height = 0;
+    int		x, y;
+    int		xDst = list->xOff, yDst = list->yOff;
+    int		n;
+    GlyphPtr	glyph;
+    int		error;
+    BoxRec	extents;
+    CARD32	component_alpha;
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * Get rid of the warning.
+     */
+
+    extents.x1 = 0;
+    extents.y1 = 0;
+
+    #endif
+
+    if (maskFormat)
+    {
+	GCPtr	    pGC;
+	xRectangle  rect;
+
+        #ifdef NXAGENT_SERVER
+
+        if (nxagentGlyphsExtents != NullBox)
+        {
+          memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
+        }
+        else
+        {
+          nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+          miGlyphExtents (nlist, list, glyphs, &extents);
+
+          memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
+        }
+
+        #else
+
+        miGlyphExtents (nlist, list, glyphs, &extents);
+
+        #endif
+
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+	    return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+	pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+
+	if (!pMaskPixmap)
+	    return;
+
+	component_alpha = NeedsComponent(maskFormat->format);
+	pMask = CreatePicture (0, &pMaskPixmap->drawable,
+			       maskFormat, CPComponentAlpha, &component_alpha,
+			       serverClient, &error);
+
+	if (!pMask)
+	{
+	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    return;
+	}
+	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+	ValidateGC (&pMaskPixmap->drawable, pGC);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+	FreeScratchGC (pGC);
+	x = -extents.x1;
+	y = -extents.y1;
+    }
+    else
+    {
+	pMask = pDst;
+	x = 0;
+	y = 0;
+    }
+    pPicture = 0;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    if (!pPicture)
+	    {
+		pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, 
+						  list->format->depth,
+						  list->format->depth, 
+						  0, (pointer) (glyph + 1));
+		if (!pPixmap)
+		    return;
+		component_alpha = NeedsComponent(list->format->format);
+		pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+					  CPComponentAlpha, &component_alpha, 
+					  serverClient, &error);
+		if (!pPicture)
+		{
+		    FreeScratchPixmapHeader (pPixmap);
+		    return;
+		}
+	    }
+	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
+					    glyph->info.width, glyph->info.height,
+					    0, 0, -1, (pointer) (glyph + 1));
+
+            #ifdef NXAGENT_SERVER
+
+            /*
+             * The following line fixes a problem with glyphs that appeared
+             * as clipped. It was a side effect due the validate function
+             * "ValidatePicture" that makes a check on the Drawable serial
+             * number instead of the picture serial number, failing thus
+             * the clip mask update.
+             */
+
+            pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
+
+            #endif
+
+	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    if (maskFormat)
+	    {
+		CompositePicture (PictOpAdd,
+				  pPicture,
+				  None,
+				  pMask,
+				  0, 0,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    else
+	    {
+		CompositePicture (op,
+				  pSrc,
+				  pPicture,
+				  pDst,
+				  xSrc + (x - glyph->info.x) - xDst,
+				  ySrc + (y - glyph->info.y) - yDst,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+
+	list++;
+	if (pPicture)
+	{
+	    FreeScratchPixmapHeader (pPixmap);
+	    FreePicture ((pointer) pPicture, 0);
+	    pPicture = 0;
+	    pPixmap = 0;
+	}
+    }
+    if (maskFormat)
+    {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture (op,
+			  pSrc,
+			  pMask,
+			  pDst,
+			  xSrc + x - xDst,
+			  ySrc + y - yDst,
+			  0, 0,
+			  x, y,
+			  width, height);
+
+	FreePicture ((pointer) pMask, (XID) 0);
+	(*pScreen->DestroyPixmap) (pMaskPixmap);
+    }
+
+}
+
+#endif /* NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
new file mode 100644
index 000000000..2521ae5c7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
@@ -0,0 +1,322 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiglyph.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.6 2000/12/05 03:13:31 keithp Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+void
+miGlyphExtents (int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs,
+		BoxPtr		extents)
+{
+    int		x1, x2, y1, y2;
+    int		n;
+    GlyphPtr	glyph;
+    int		x, y;
+ 
+    x = 0;
+    y = 0;
+    extents->x1 = MAXSHORT;
+    extents->x2 = MINSHORT;
+    extents->y1 = MAXSHORT;
+    extents->y2 = MINSHORT;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+	    if (x1 < extents->x1)
+		extents->x1 = x1;
+	    if (x2 > extents->x2)
+		extents->x2 = x2;
+	    if (y1 < extents->y1)
+		extents->y1 = y1;
+	    if (y2 > extents->y2)
+		extents->y2 = y2;
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+    PixmapPtr	pPixmap = 0;
+    PicturePtr	pPicture;
+    PixmapPtr   pMaskPixmap = 0;
+    PicturePtr  pMask;
+    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    int		width = 0, height = 0;
+    int		x, y;
+    int		xDst = list->xOff, yDst = list->yOff;
+    int		n;
+    GlyphPtr	glyph;
+    int		error;
+    BoxRec	extents;
+    CARD32	component_alpha;
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * Get rid of the warning.
+     */
+
+    extents.x1 = 0;
+    extents.y1 = 0;
+
+    #endif
+
+    if (maskFormat)
+    {
+	GCPtr	    pGC;
+	xRectangle  rect;
+
+        #ifdef NXAGENT_SERVER
+
+        if (nxagentGlyphsExtents != NullBox)
+        {
+          memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
+        }
+        else
+        {
+          nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+          miGlyphExtents (nlist, list, glyphs, &extents);
+
+          memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
+        }
+
+        #else
+
+        miGlyphExtents (nlist, list, glyphs, &extents);
+
+        #endif
+
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+	    return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+	pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+
+	if (!pMaskPixmap)
+	    return;
+
+	component_alpha = NeedsComponent(maskFormat->format);
+	pMask = CreatePicture (0, &pMaskPixmap->drawable,
+			       maskFormat, CPComponentAlpha, &component_alpha,
+			       serverClient, &error);
+
+	if (!pMask)
+	{
+	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    return;
+	}
+	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+	ValidateGC (&pMaskPixmap->drawable, pGC);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+	FreeScratchGC (pGC);
+	x = -extents.x1;
+	y = -extents.y1;
+    }
+    else
+    {
+	pMask = pDst;
+	x = 0;
+	y = 0;
+    }
+    pPicture = 0;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    if (!pPicture)
+	    {
+		pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, 
+						  list->format->depth,
+						  list->format->depth, 
+						  0, (pointer) (glyph + 1));
+		if (!pPixmap)
+		    return;
+		component_alpha = NeedsComponent(list->format->format);
+		pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+					  CPComponentAlpha, &component_alpha, 
+					  serverClient, &error);
+		if (!pPicture)
+		{
+		    FreeScratchPixmapHeader (pPixmap);
+		    return;
+		}
+	    }
+	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
+					    glyph->info.width, glyph->info.height,
+					    0, 0, -1, (pointer) (glyph + 1));
+
+            #ifdef NXAGENT_SERVER
+
+            /*
+             * The following line fixes a problem with glyphs that appeared
+             * as clipped. It was a side effect due the validate function
+             * "ValidatePicture" that makes a check on the Drawable serial
+             * number instead of the picture serial number, failing thus
+             * the clip mask update.
+             */
+
+            pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
+
+            #endif
+
+	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    if (maskFormat)
+	    {
+		CompositePicture (PictOpAdd,
+				  pPicture,
+				  None,
+				  pMask,
+				  0, 0,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    else
+	    {
+		CompositePicture (op,
+				  pSrc,
+				  pPicture,
+				  pDst,
+				  xSrc + (x - glyph->info.x) - xDst,
+				  ySrc + (y - glyph->info.y) - yDst,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+
+	list++;
+	if (pPicture)
+	{
+	    FreeScratchPixmapHeader (pPixmap);
+	    FreePicture ((pointer) pPicture, 0);
+	    pPicture = 0;
+	    pPixmap = 0;
+	}
+    }
+    if (maskFormat)
+    {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture (op,
+			  pSrc,
+			  pMask,
+			  pDst,
+			  xSrc + x - xDst,
+			  ySrc + y - yDst,
+			  0, 0,
+			  x, y,
+			  width, height);
+
+	FreePicture ((pointer) pMask, (XID) 0);
+	(*pScreen->DestroyPixmap) (pMaskPixmap);
+    }
+
+}
+
+#endif /* NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.XF86.original
new file mode 100644
index 000000000..00b6764d6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.XF86.original
@@ -0,0 +1,239 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.6 2000/12/05 03:13:31 keithp Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+void
+miGlyphExtents (int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs,
+		BoxPtr		extents)
+{
+    int		x1, x2, y1, y2;
+    int		n;
+    GlyphPtr	glyph;
+    int		x, y;
+    
+    x = 0;
+    y = 0;
+    extents->x1 = MAXSHORT;
+    extents->x2 = MINSHORT;
+    extents->y1 = MAXSHORT;
+    extents->y2 = MINSHORT;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+	    if (x1 < extents->x1)
+		extents->x1 = x1;
+	    if (x2 > extents->x2)
+		extents->x2 = x2;
+	    if (y1 < extents->y1)
+		extents->y1 = y1;
+	    if (y2 > extents->y2)
+		extents->y2 = y2;
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+    PixmapPtr	pPixmap = 0;
+    PicturePtr	pPicture;
+    PixmapPtr   pMaskPixmap = 0;
+    PicturePtr  pMask;
+    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    int		width = 0, height = 0;
+    int		x, y;
+    int		xDst = list->xOff, yDst = list->yOff;
+    int		n;
+    GlyphPtr	glyph;
+    int		error;
+    BoxRec	extents;
+    CARD32	component_alpha;
+    
+    if (maskFormat)
+    {
+	GCPtr	    pGC;
+	xRectangle  rect;
+	
+	miGlyphExtents (nlist, list, glyphs, &extents);
+	
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+	    return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+	pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+	if (!pMaskPixmap)
+	    return;
+	component_alpha = NeedsComponent(maskFormat->format);
+	pMask = CreatePicture (0, &pMaskPixmap->drawable,
+			       maskFormat, CPComponentAlpha, &component_alpha,
+			       serverClient, &error);
+	if (!pMask)
+	{
+	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    return;
+	}
+	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+	ValidateGC (&pMaskPixmap->drawable, pGC);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+	FreeScratchGC (pGC);
+	x = -extents.x1;
+	y = -extents.y1;
+    }
+    else
+    {
+	pMask = pDst;
+	x = 0;
+	y = 0;
+    }
+    pPicture = 0;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    if (!pPicture)
+	    {
+		pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, 
+						  list->format->depth,
+						  list->format->depth, 
+						  0, (pointer) (glyph + 1));
+		if (!pPixmap)
+		    return;
+		component_alpha = NeedsComponent(list->format->format);
+		pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+					  CPComponentAlpha, &component_alpha, 
+					  serverClient, &error);
+		if (!pPicture)
+		{
+		    FreeScratchPixmapHeader (pPixmap);
+		    return;
+		}
+	    }
+	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
+					    glyph->info.width, glyph->info.height,
+					    0, 0, -1, (pointer) (glyph + 1));
+	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    if (maskFormat)
+	    {
+		CompositePicture (PictOpAdd,
+				  pPicture,
+				  None,
+				  pMask,
+				  0, 0,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    else
+	    {
+		CompositePicture (op,
+				  pSrc,
+				  pPicture,
+				  pDst,
+				  xSrc + (x - glyph->info.x) - xDst,
+				  ySrc + (y - glyph->info.y) - yDst,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+	list++;
+	if (pPicture)
+	{
+	    FreeScratchPixmapHeader (pPixmap);
+	    FreePicture ((pointer) pPicture, 0);
+	    pPicture = 0;
+	    pPixmap = 0;
+	}
+    }
+    if (maskFormat)
+    {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture (op,
+			  pSrc,
+			  pMask,
+			  pDst,
+			  xSrc + x - xDst,
+			  ySrc + y - yDst,
+			  0, 0,
+			  x, y,
+			  width, height);
+	FreePicture ((pointer) pMask, (XID) 0);
+	(*pScreen->DestroyPixmap) (pMaskPixmap);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c
new file mode 100644
index 000000000..7d0a99572
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c
@@ -0,0 +1,204 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmitrap.c"
+
+#else
+
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.9 2002/11/05 23:39:16 keithp Exp $
+ *
+ * Copyright � 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr	    pScreen, 
+		      PicturePtr    pDst,
+		      PictFormatPtr pPictFormat,
+		      CARD16	    width,
+		      CARD16	    height)
+{
+    PixmapPtr	    pPixmap;
+    PicturePtr	    pPicture;
+    GCPtr	    pGC;
+    int		    error;
+    xRectangle	    rect;
+
+    if (width > 32767 || height > 32767)
+	return 0;
+
+    if (!pPictFormat)
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	if (!pPictFormat)
+	    return 0;
+    }
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 
+					pPictFormat->depth);
+    if (!pPixmap)
+	return 0;
+    pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+    if (!pGC)
+    {
+	(*pScreen->DestroyPixmap) (pPixmap);
+	return 0;
+    }
+    ValidateGC (&pPixmap->drawable, pGC);
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = width;
+    rect.height = height;
+    (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+    FreeScratchGC (pGC);
+    pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+			      0, 0, serverClient, &error);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+    xFixed	    dx = l->p2.x - l->p1.x;
+    xFixed_32_32    ex = (xFixed_32_32) (y - l->p1.y) * dx;
+    xFixed	    dy = l->p2.y - l->p1.y;
+    if (ceil)
+	ex += (dy - 1);
+    return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+    box->y1 = MAXSHORT;
+    box->y2 = MINSHORT;
+    box->x1 = MAXSHORT;
+    box->x2 = MINSHORT;
+    for (; ntrap; ntrap--, traps++)
+    {
+	INT16 x1, y1, x2, y2;
+
+	if (!xTrapezoidValid(traps))
+	    continue;
+	y1 = xFixedToInt (traps->top);
+	if (y1 < box->y1)
+	    box->y1 = y1;
+	
+	y2 = xFixedToInt (xFixedCeil (traps->bottom));
+	if (y2 > box->y2)
+	    box->y2 = y2;
+	
+	x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+			       miLineFixedX (&traps->left, traps->bottom, FALSE)));
+	if (x1 < box->x1)
+	    box->x1 = x1;
+	
+	x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+					   miLineFixedX (&traps->right, traps->bottom, TRUE))));
+	if (x2 > box->x2)
+	    box->x2 = x2;
+    }
+}
+
+void
+miTrapezoids (CARD8	    op,
+	      PicturePtr    pSrc,
+	      PicturePtr    pDst,
+	      PictFormatPtr maskFormat,
+	      INT16	    xSrc,
+	      INT16	    ySrc,
+	      int	    ntrap,
+	      xTrapezoid    *traps)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture = 0;
+    BoxRec		bounds;
+    INT16		xDst, yDst;
+    INT16		xRel, yRel;
+    
+    xDst = traps[0].left.p1.x >> 16;
+    yDst = traps[0].left.p1.y >> 16;
+    
+    if (maskFormat)
+    {
+	miTrapezoidBounds (ntrap, traps, &bounds);
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+	    return;
+	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					 bounds.x2 - bounds.x1,
+					 bounds.y2 - bounds.y1);
+	if (!pPicture)
+	    return;
+    }
+    for (; ntrap; ntrap--, traps++)
+    {
+	if (!xTrapezoidValid(traps))
+	    continue;
+	if (!maskFormat)
+	{
+	    miTrapezoidBounds (1, traps, &bounds);
+	    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+		continue;
+	    pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					     bounds.x2 - bounds.x1,
+					     bounds.y2 - bounds.y1);
+	    if (!pPicture)
+		continue;
+	}
+	(*ps->RasterizeTrapezoid) (pPicture, traps, 
+				   -bounds.x1, -bounds.y1);
+	if (!maskFormat)
+	{
+	    xRel = bounds.x1 + xSrc - xDst;
+	    yRel = bounds.y1 + ySrc - yDst;
+	    CompositePicture (op, pSrc, pPicture, pDst,
+			      xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			      bounds.x2 - bounds.x1,
+			      bounds.y2 - bounds.y1);
+	    FreePicture (pPicture, 0);
+	}
+    }
+    if (maskFormat)
+    {
+	xRel = bounds.x1 + xSrc - xDst;
+	yRel = bounds.y1 + ySrc - yDst;
+	CompositePicture (op, pSrc, pPicture, pDst,
+			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			  bounds.x2 - bounds.x1,
+			  bounds.y2 - bounds.y1);
+	FreePicture (pPicture, 0);
+    }
+}
+
+#endif /* NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.NX.original
new file mode 100644
index 000000000..7d0a99572
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.NX.original
@@ -0,0 +1,204 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmitrap.c"
+
+#else
+
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.9 2002/11/05 23:39:16 keithp Exp $
+ *
+ * Copyright � 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr	    pScreen, 
+		      PicturePtr    pDst,
+		      PictFormatPtr pPictFormat,
+		      CARD16	    width,
+		      CARD16	    height)
+{
+    PixmapPtr	    pPixmap;
+    PicturePtr	    pPicture;
+    GCPtr	    pGC;
+    int		    error;
+    xRectangle	    rect;
+
+    if (width > 32767 || height > 32767)
+	return 0;
+
+    if (!pPictFormat)
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	if (!pPictFormat)
+	    return 0;
+    }
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 
+					pPictFormat->depth);
+    if (!pPixmap)
+	return 0;
+    pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+    if (!pGC)
+    {
+	(*pScreen->DestroyPixmap) (pPixmap);
+	return 0;
+    }
+    ValidateGC (&pPixmap->drawable, pGC);
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = width;
+    rect.height = height;
+    (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+    FreeScratchGC (pGC);
+    pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+			      0, 0, serverClient, &error);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+    xFixed	    dx = l->p2.x - l->p1.x;
+    xFixed_32_32    ex = (xFixed_32_32) (y - l->p1.y) * dx;
+    xFixed	    dy = l->p2.y - l->p1.y;
+    if (ceil)
+	ex += (dy - 1);
+    return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+    box->y1 = MAXSHORT;
+    box->y2 = MINSHORT;
+    box->x1 = MAXSHORT;
+    box->x2 = MINSHORT;
+    for (; ntrap; ntrap--, traps++)
+    {
+	INT16 x1, y1, x2, y2;
+
+	if (!xTrapezoidValid(traps))
+	    continue;
+	y1 = xFixedToInt (traps->top);
+	if (y1 < box->y1)
+	    box->y1 = y1;
+	
+	y2 = xFixedToInt (xFixedCeil (traps->bottom));
+	if (y2 > box->y2)
+	    box->y2 = y2;
+	
+	x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+			       miLineFixedX (&traps->left, traps->bottom, FALSE)));
+	if (x1 < box->x1)
+	    box->x1 = x1;
+	
+	x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+					   miLineFixedX (&traps->right, traps->bottom, TRUE))));
+	if (x2 > box->x2)
+	    box->x2 = x2;
+    }
+}
+
+void
+miTrapezoids (CARD8	    op,
+	      PicturePtr    pSrc,
+	      PicturePtr    pDst,
+	      PictFormatPtr maskFormat,
+	      INT16	    xSrc,
+	      INT16	    ySrc,
+	      int	    ntrap,
+	      xTrapezoid    *traps)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture = 0;
+    BoxRec		bounds;
+    INT16		xDst, yDst;
+    INT16		xRel, yRel;
+    
+    xDst = traps[0].left.p1.x >> 16;
+    yDst = traps[0].left.p1.y >> 16;
+    
+    if (maskFormat)
+    {
+	miTrapezoidBounds (ntrap, traps, &bounds);
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+	    return;
+	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					 bounds.x2 - bounds.x1,
+					 bounds.y2 - bounds.y1);
+	if (!pPicture)
+	    return;
+    }
+    for (; ntrap; ntrap--, traps++)
+    {
+	if (!xTrapezoidValid(traps))
+	    continue;
+	if (!maskFormat)
+	{
+	    miTrapezoidBounds (1, traps, &bounds);
+	    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+		continue;
+	    pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					     bounds.x2 - bounds.x1,
+					     bounds.y2 - bounds.y1);
+	    if (!pPicture)
+		continue;
+	}
+	(*ps->RasterizeTrapezoid) (pPicture, traps, 
+				   -bounds.x1, -bounds.y1);
+	if (!maskFormat)
+	{
+	    xRel = bounds.x1 + xSrc - xDst;
+	    yRel = bounds.y1 + ySrc - yDst;
+	    CompositePicture (op, pSrc, pPicture, pDst,
+			      xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			      bounds.x2 - bounds.x1,
+			      bounds.y2 - bounds.y1);
+	    FreePicture (pPicture, 0);
+	}
+    }
+    if (maskFormat)
+    {
+	xRel = bounds.x1 + xSrc - xDst;
+	yRel = bounds.y1 + ySrc - yDst;
+	CompositePicture (op, pSrc, pPicture, pDst,
+			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			  bounds.x2 - bounds.x1,
+			  bounds.y2 - bounds.y1);
+	FreePicture (pPicture, 0);
+    }
+}
+
+#endif /* NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.XF86.original
new file mode 100644
index 000000000..7f592ccd4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmitrap.c.XF86.original
@@ -0,0 +1,196 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.9 2002/11/05 23:39:16 keithp Exp $
+ *
+ * Copyright � 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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 "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr	    pScreen, 
+		      PicturePtr    pDst,
+		      PictFormatPtr pPictFormat,
+		      CARD16	    width,
+		      CARD16	    height)
+{
+    PixmapPtr	    pPixmap;
+    PicturePtr	    pPicture;
+    GCPtr	    pGC;
+    int		    error;
+    xRectangle	    rect;
+
+    if (width > 32767 || height > 32767)
+	return 0;
+
+    if (!pPictFormat)
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	if (!pPictFormat)
+	    return 0;
+    }
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 
+					pPictFormat->depth);
+    if (!pPixmap)
+	return 0;
+    pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+    if (!pGC)
+    {
+	(*pScreen->DestroyPixmap) (pPixmap);
+	return 0;
+    }
+    ValidateGC (&pPixmap->drawable, pGC);
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = width;
+    rect.height = height;
+    (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+    FreeScratchGC (pGC);
+    pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+			      0, 0, serverClient, &error);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+    xFixed	    dx = l->p2.x - l->p1.x;
+    xFixed_32_32    ex = (xFixed_32_32) (y - l->p1.y) * dx;
+    xFixed	    dy = l->p2.y - l->p1.y;
+    if (ceil)
+	ex += (dy - 1);
+    return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+    box->y1 = MAXSHORT;
+    box->y2 = MINSHORT;
+    box->x1 = MAXSHORT;
+    box->x2 = MINSHORT;
+    for (; ntrap; ntrap--, traps++)
+    {
+	INT16 x1, y1, x2, y2;
+
+	if (!xTrapezoidValid(traps))
+	    continue;
+	y1 = xFixedToInt (traps->top);
+	if (y1 < box->y1)
+	    box->y1 = y1;
+	
+	y2 = xFixedToInt (xFixedCeil (traps->bottom));
+	if (y2 > box->y2)
+	    box->y2 = y2;
+	
+	x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+			       miLineFixedX (&traps->left, traps->bottom, FALSE)));
+	if (x1 < box->x1)
+	    box->x1 = x1;
+	
+	x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+					   miLineFixedX (&traps->right, traps->bottom, TRUE))));
+	if (x2 > box->x2)
+	    box->x2 = x2;
+    }
+}
+
+void
+miTrapezoids (CARD8	    op,
+	      PicturePtr    pSrc,
+	      PicturePtr    pDst,
+	      PictFormatPtr maskFormat,
+	      INT16	    xSrc,
+	      INT16	    ySrc,
+	      int	    ntrap,
+	      xTrapezoid    *traps)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture = 0;
+    BoxRec		bounds;
+    INT16		xDst, yDst;
+    INT16		xRel, yRel;
+    
+    xDst = traps[0].left.p1.x >> 16;
+    yDst = traps[0].left.p1.y >> 16;
+    
+    if (maskFormat)
+    {
+	miTrapezoidBounds (ntrap, traps, &bounds);
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+	    return;
+	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					 bounds.x2 - bounds.x1,
+					 bounds.y2 - bounds.y1);
+	if (!pPicture)
+	    return;
+    }
+    for (; ntrap; ntrap--, traps++)
+    {
+	if (!xTrapezoidValid(traps))
+	    continue;
+	if (!maskFormat)
+	{
+	    miTrapezoidBounds (1, traps, &bounds);
+	    if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+		continue;
+	    pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					     bounds.x2 - bounds.x1,
+					     bounds.y2 - bounds.y1);
+	    if (!pPicture)
+		continue;
+	}
+	(*ps->RasterizeTrapezoid) (pPicture, traps, 
+				   -bounds.x1, -bounds.y1);
+	if (!maskFormat)
+	{
+	    xRel = bounds.x1 + xSrc - xDst;
+	    yRel = bounds.y1 + ySrc - yDst;
+	    CompositePicture (op, pSrc, pPicture, pDst,
+			      xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			      bounds.x2 - bounds.x1,
+			      bounds.y2 - bounds.y1);
+	    FreePicture (pPicture, 0);
+	}
+    }
+    if (maskFormat)
+    {
+	xRel = bounds.x1 + xSrc - xDst;
+	yRel = bounds.y1 + ySrc - yDst;
+	CompositePicture (op, pSrc, pPicture, pDst,
+			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			  bounds.x2 - bounds.x1,
+			  bounds.y2 - bounds.y1);
+	FreePicture (pPicture, 0);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c
new file mode 100644
index 000000000..ea2e7df28
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c
@@ -0,0 +1,1205 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiwindow.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.7 2001/12/14 20:00:28 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#include "X.h"
+#include "miscstruct.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void 
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+    WindowPtr pWin;
+    int x,y;
+    int w,h;
+    Bool generateExposures;
+{
+    BoxRec box;
+    RegionRec	reg;
+    RegionPtr pBSReg = NullRegion;
+    ScreenPtr	pScreen;
+    BoxPtr  extents;
+    int	    x1, y1, x2, y2;
+
+    /* compute everything using ints to avoid overflow */
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;	
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    extents = &pWin->clipList.extents;
+    
+    /* clip the resulting rectangle to the window clipList extents.  This
+     * makes sure that the result will fit in a box, given that the
+     * screen is < 32768 on a side.
+     */
+
+    if (x1 < extents->x1)
+	x1 = extents->x1;
+    if (x2 > extents->x2)
+	x2 = extents->x2;
+    if (y1 < extents->y1)
+	y1 = extents->y1;
+    if (y2 > extents->y2)
+	y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1)
+    {
+	x2 = x1 = 0;
+	y2 = y1 = 0;
+    }
+
+    box.x1 = x1;
+    box.x2 = x2;
+    box.y1 = y1;
+    box.y2 = y2;
+
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &reg, &box, 1);
+    if (pWin->backStorage)
+    {
+	/*
+	 * If the window has backing-store on, call through the
+	 * ClearToBackground vector to handle the special semantics
+	 * (i.e. things backing store is to be cleared out and
+	 * an Expose event is to be generated for those areas in backing
+	 * store if generateExposures is TRUE).
+	 */
+	pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+						 generateExposures);
+    }
+
+    REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+    if (generateExposures)
+	(*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+    else if (pWin->backgroundState != None)
+        (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+    REGION_UNINIT(pScreen, &reg);
+    if (pBSReg)
+	REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ *	Check all the inferiors of a window for coverage by saveUnder
+ *	windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ *	This code is very inefficient.
+ *
+ * Results:
+ *	TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+    register WindowPtr	pParent,	/* Parent to check */
+    WindowPtr		pFirst,		/* first reconfigured window */
+    RegionPtr		pRegion)	/* Initial area obscured by saveUnder */
+{
+    register WindowPtr	pChild;		/* Current child */
+    register ScreenPtr	pScreen;	/* Screen to use */
+    RegionRec		SubRegion;	/* Area of children obscured */
+    Bool		res = FALSE;	/* result */
+    Bool		subInited=FALSE;/* SubRegion initialized */
+
+    pScreen = pParent->drawable.pScreen;
+    if ( (pChild = pParent->firstChild) )
+    {
+	/*
+	 * build region above first changed window
+	 */
+
+	for (; pChild != pFirst; pChild = pChild->nextSib)
+	    if (pChild->viewable && pChild->saveUnder)
+		REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	
+	/*
+	 * check region below and including first changed window
+	 */
+
+	for (; pChild; pChild = pChild->nextSib)
+	{
+	    if (pChild->viewable)
+	    {
+		/*
+		 * don't save under nephew/niece windows;
+		 * use a separate region
+		 */
+
+		if (pChild->firstChild)
+		{
+		    if (!subInited)
+		    {
+			REGION_INIT(pScreen, &SubRegion, NullBox, 0);
+			subInited = TRUE;
+		    }
+		    REGION_COPY(pScreen, &SubRegion, pRegion);
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     &SubRegion);
+		}
+		else
+		{
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     pRegion);
+		}
+
+		if (pChild->saveUnder)
+		    REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	    }
+	}
+
+	if (subInited)
+	    REGION_UNINIT(pScreen, &SubRegion);
+    }
+
+    /*
+     * Check the state of this window.	DIX save unders are
+     * enabled for viewable windows with some client expressing
+     * exposure interest and which intersect the save under region
+     */
+
+    if (pParent->viewable && 
+	((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+	REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+	RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen, 
+					&pParent->borderSize)) != rgnOUT)
+    {
+	if (!pParent->DIXsaveUnder)
+	{
+	    pParent->DIXsaveUnder = TRUE;
+	    (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+	}
+    }
+    else
+    {
+	if (pParent->DIXsaveUnder)
+	{
+	    res = TRUE;
+	    pParent->DIXsaveUnder = FALSE;
+	}
+    }
+    return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ *	Change the save-under state of a tree of windows. Called when
+ *	a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *	
+ * Results:
+ *	TRUE if any windows need to have backing-store removed (which
+ *	means that PostChangeSaveUnder needs to be called later to 
+ *	finish the job).
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+    register WindowPtr	pWin;
+    WindowPtr		first;		/* First window to check.
+					 * Used when pWin was restacked */
+{
+    RegionRec	rgn;	/* Area obscured by saveUnder windows */
+    register ScreenPtr pScreen;
+    Bool	res;
+
+    if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+	return FALSE;
+    numSaveUndersViewable += deltaSaveUndersViewable;
+    deltaSaveUndersViewable = 0;
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &rgn, NullBox, 1);
+    res = miCheckSubSaveUnder (pWin->parent,
+			       pWin->saveUnder ? first : pWin->nextSib,
+			       &rgn);
+    REGION_UNINIT(pScreen, &rgn);
+    return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ *	Actually turn backing-store off for those windows that no longer
+ *	need to have it on.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ *	windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+    WindowPtr		pWin;
+    WindowPtr		pFirst;
+{
+    register WindowPtr pParent, pChild;
+    ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+    if (!(pParent = pWin->parent))
+	return;
+    ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+    if (!pParent->DIXsaveUnder &&
+	(pParent->backingStore == NotUseful) && pParent->backStorage)
+	(*ChangeWindowAttributes)(pParent, CWBackingStore);
+    if (!(pChild = pFirst))
+	return;
+    while (1)
+    {
+	if (!pChild->DIXsaveUnder &&
+	    (pChild->backingStore == NotUseful) && pChild->backStorage)
+	    (*ChangeWindowAttributes)(pChild, CWBackingStore);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib)
+	{
+	    pChild = pChild->parent;
+	    if (pChild == pParent)
+		return;
+	}
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMarkWindow(pWin)
+    register WindowPtr pWin;
+{
+    register ValidatePtr val;
+
+    if (pWin->valdata)
+	return;
+    val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+    val->before.oldAbsCorner.x = pWin->drawable.x;
+    val->before.oldAbsCorner.y = pWin->drawable.y;
+    val->before.borderVisible = NullRegion;
+    val->before.resized = FALSE;
+    pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+    WindowPtr pWin;
+    WindowPtr pFirst;
+    WindowPtr *ppLayerWin;
+{
+    register BoxPtr box;
+    register WindowPtr pChild, pLast;
+    Bool anyMarked = FALSE;
+    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+    ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+
+    /* single layered systems are easy */
+    if (ppLayerWin) *ppLayerWin = pWin;
+
+    if (pWin == pFirst)
+    {
+	/* Blindly mark pWin and all of its inferiors.	 This is a slight
+	 * overkill if there are mapped windows that outside pWin's border,
+	 * but it's better than wasting time on RectIn checks.
+	 */
+	pChild = pWin;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		(* MarkWindow)(pChild);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pWin))
+		pChild = pChild->parent;
+	    if (pChild == pWin)
+		break;
+	    pChild = pChild->nextSib;
+	}
+	anyMarked = TRUE;
+	pFirst = pFirst->nextSib;
+    }
+    if ( (pChild = pFirst) )
+    {
+	box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+	pLast = pChild->parent->lastChild;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+		{
+		    (* MarkWindow)(pChild);
+		    anyMarked = TRUE;
+		    if (pChild->firstChild)
+		    {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pLast))
+		pChild = pChild->parent;
+	    if (pChild == pLast)
+		break;
+	    pChild = pChild->nextSib;
+	}
+    }
+    if (anyMarked)
+	(* MarkWindow)(pWin->parent);
+    return anyMarked;
+}
+
+/*****
+ *  miHandleValidateExposures(pWin)
+ *    starting at pWin, draw background in any windows that have exposure
+ *    regions, translate the regions, restore any backing store,
+ *    and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+    WindowPtr pWin;
+{
+    register WindowPtr pChild;
+    register ValidatePtr val;
+    ScreenPtr pScreen;
+    WindowExposuresProcPtr WindowExposures;
+
+    pScreen = pWin->drawable.pScreen;
+
+    pChild = pWin;
+    WindowExposures = pChild->drawable.pScreen->WindowExposures;
+    while (1)
+    {
+	if ( (val = pChild->valdata) )
+	{
+	    if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+		(*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+						    &val->after.borderExposed,
+						    PW_BORDER);
+	    REGION_UNINIT(pScreen, &val->after.borderExposed);
+	    (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+	    REGION_UNINIT(pScreen, &val->after.exposed);
+	    xfree(val);
+	    pChild->valdata = (ValidatePtr)NULL;
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+    register WindowPtr pWin;
+    int x,y;
+    WindowPtr pNextSib;
+    VTKind kind;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    short bw;
+    RegionPtr oldRegion = NULL;
+    DDXPointRec oldpt;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+    Bool dosave = FALSE;
+#endif
+    WindowPtr pLayerWin;
+
+    /* if this is a root window, can't be moved */
+    if (!(pParent = pWin->parent))
+       return ;
+    pScreen = pWin->drawable.pScreen;
+    bw = wBorderWidth (pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable)
+    {
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    }
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, windowToValidate, (WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+	    REGION_DESTROY(pScreen, oldRegion);
+	    /* XXX need to retile border if ParentRelative origin */
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+    register WindowPtr	pWin,
+    pointer		value) /* must conform to VisitWindowProcPtr */
+{
+    register ScreenPtr	pScreen;
+    RegionPtr	pValid = (RegionPtr)value;
+
+    if (pWin->valdata)
+    {
+	pScreen = pWin->drawable.pScreen;
+	/*
+	 * compute exposed regions of this window
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+			&pWin->clipList, pValid);
+	/*
+	 * compute exposed regions of the border
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->borderClip, &pWin->winSize);
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->valdata->after.borderExposed, pValid);
+	return WT_WALKCHILDREN;
+    }
+    return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+    register WindowPtr pWin;
+    int x,y;
+    unsigned int w, h;
+    WindowPtr pSib;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    unsigned short width = pWin->drawable.width,
+		   height = pWin->drawable.height;
+    short oldx = pWin->drawable.x,
+	  oldy = pWin->drawable.y;
+    int bw = wBorderWidth (pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr pFirstChange;
+    register WindowPtr pChild;
+    RegionPtr	gravitate[StaticGravity + 1];
+    register unsigned g;
+    int		nx, ny;		/* destination x,y */
+    int		newx, newy;	/* new inner window position */
+    RegionPtr	pRegion = NULL;
+    RegionPtr	destClip;	/* portions of destination already written */
+    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
+    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
+    RegionPtr	bsExposed = NullRegion;	    /* backing store exposures */
+    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
+    Bool	moved = FALSE;	/* window position changed */
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pScreen = pWin->drawable.pScreen;
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable)
+    {
+	anyMarked = FALSE;
+	/*
+	 * save the visible region of the window
+	 */
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+	/*
+	 * categorize child windows into regions to be moved
+	 */
+	for (g = 0; g <= StaticGravity; g++)
+	    gravitate[g] = (RegionPtr) NULL;
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	{
+	    g = pChild->winGravity;
+	    if (g != UnmapGravity)
+	    {
+		if (!gravitate[g])
+		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_UNION(pScreen, gravitate[g],
+				   gravitate[g], &pChild->borderClip);
+	    }
+	    else
+	    {
+		UnmapWindow(pChild, TRUE);
+		anyMarked = TRUE;
+	    }
+	}
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
+						       &pLayerWin);
+
+	oldWinClip = NULL;
+	if (pWin->bitGravity != ForgetGravity)
+	{
+	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+	}
+	/*
+	 * if the window is changing size, borderExposed
+	 * can't be computed correctly without some help.
+	 */
+	if (pWin->drawable.height > h || pWin->drawable.width > w)
+	    shrunk = TRUE;
+
+	if (newx != oldx || newy != oldy)
+	    moved = TRUE;
+
+	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+	    HasBorder (pWin))
+	{
+	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+	    /* for tiled borders, we punt and draw the whole thing */
+	    if (pWin->borderIsPixel || !moved)
+	    {
+		if (shrunk || moved)
+		    REGION_SUBTRACT(pScreen, borderVisible,
+					  &pWin->borderClip,
+					  &pWin->winSize);
+		else
+		    REGION_COPY(pScreen, borderVisible,
+					    &pWin->borderClip);
+	    }
+	}
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    dw = (int)w - (int)width;
+    dh = (int)h - (int)height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	pRegion = REGION_CREATE(pScreen, NullBox, 1);
+	if (pWin->backStorage)
+	    REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						(WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						(WindowPtr *)NULL);
+
+	if (pWin->valdata)
+	{
+	    pWin->valdata->before.resized = TRUE;
+	    pWin->valdata->before.borderVisible = borderVisible;
+	}
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+	/*
+	 * the entire window is trashed unless bitGravity
+	 * recovers portions of it
+	 */
+	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+    }
+
+    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pRegion = &pWin->clipList; /* a convenient empty region */
+	if (pWin->bitGravity == ForgetGravity)
+	    bsExposed = (*pScreen->TranslateBackingStore)
+				(pWin, 0, 0, NullRegion, oldx, oldy);
+	else
+	{
+	    bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+	}
+    }
+
+    if (WasViewable)
+    {
+	/* avoid the border */
+	if (HasBorder (pWin))
+	{
+	    int	offx, offy, dx, dy;
+
+	    /* kruft to avoid double translates for each gravity */
+	    offx = 0;
+	    offy = 0;
+	    for (g = 0; g <= StaticGravity; g++)
+	    {
+		if (!gravitate[g])
+		    continue;
+
+		/* align winSize to gravitate[g].
+		 * winSize is in new coordinates,
+		 * gravitate[g] is still in old coordinates */
+		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+		
+		dx = (oldx - nx) - offx;
+		dy = (oldy - ny) - offy;
+		if (dx || dy)
+		{
+		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+		    offx += dx;
+		    offy += dy;
+		}
+		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+				 &pWin->winSize);
+	    }
+	    /* get winSize back where it belongs */
+	    if (offx || offy)
+		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+	}
+	/*
+	 * add screen bits to the appropriate bucket
+	 */
+
+	if (oldWinClip)
+	{
+	    /*
+	     * clip to new clipList
+	     */
+	    REGION_COPY(pScreen, pRegion, oldWinClip);
+	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+	    /*
+	     * don't step on any gravity bits which will be copied after this
+	     * region.	Note -- this assumes that the regions will be copied
+	     * in gravity order.
+	     */
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+	    {
+		if (gravitate[g])
+		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+					gravitate[g]);
+	    }
+	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate[g])
+		gravitate[g] = oldWinClip;
+	    else
+	    {
+		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+		REGION_DESTROY(pScreen, oldWinClip);
+	    }
+	}
+
+	/*
+	 * move the bits on the screen
+	 */
+
+	destClip = NULL;
+
+	for (g = 0; g <= StaticGravity; g++)
+	{
+	    if (!gravitate[g])
+		continue;
+
+	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+	    oldpt.x = oldx + (x - nx);
+	    oldpt.y = oldy + (y - ny);
+
+	    /* Note that gravitate[g] is *translated* by CopyWindow */
+
+	    /* only copy the remaining useful bits */
+
+	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+	    /* clip to not overwrite already copied areas */
+
+	    if (destClip) {
+		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+	    }
+
+	    /* and move those bits */
+
+	    if (oldpt.x != x || oldpt.y != y)
+		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+
+	    /* remove any overwritten bits from the remaining useful bits */
+
+	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+	    /*
+	     * recompute exposed regions of child windows
+	     */
+	
+	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	    {
+		if (pChild->winGravity != g)
+		    continue;
+		REGION_INTERSECT(pScreen, pRegion,
+				       &pChild->borderClip, gravitate[g]);
+		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+	    }
+
+	    /*
+	     * remove the successfully copied regions of the
+	     * window from its exposed region
+	     */
+
+	    if (g == pWin->bitGravity)
+		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+				     &pWin->valdata->after.exposed, gravitate[g]);
+	    if (!destClip)
+		destClip = gravitate[g];
+	    else
+	    {
+		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+		REGION_DESTROY(pScreen, gravitate[g]);
+	    }
+	}
+
+	REGION_DESTROY(pScreen, oldRegion);
+	REGION_DESTROY(pScreen, pRegion);
+	if (destClip)
+	    REGION_DESTROY(pScreen, destClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	{
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+					  VTOther);
+    }
+    else if (bsExposed)
+    {
+	(*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+	REGION_DESTROY(pScreen, bsExposed);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+    WindowPtr pWin;
+{
+    return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ *    The border/window shape has changed.  Recompute winSize/borderSize
+ *    and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+    register WindowPtr	pWin;
+{
+    Bool	WasViewable = (Bool)(pWin->viewable);
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    Bool	anyMarked = FALSE;
+    RegionPtr	pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr   pLayerWin;
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						      &pLayerWin);
+	if (pWin->valdata)
+	{
+	    if (HasBorder (pWin))
+	    {
+		RegionPtr	borderVisible;
+
+		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	    pWin->valdata->before.resized = TRUE;
+	}
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pWin->backStorage)
+	{
+	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+	}
+
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						(WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pOldClip = &pWin->clipList; /* a convenient empty region */
+	bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, 0, 0, pOldClip,
+			      pWin->drawable.x, pWin->drawable.y);
+#ifdef NXAGENT_SERVER
+
+        /*
+         * We got a few, rare, segfaults here after having
+         * started using the backing store. It may be a
+         * different bug but miChangeSaveUnder() calls mi-
+         * CheckSubSaveUnder() that, in turn, can change
+         * the backing store attribute of the window. This
+         * means that we may try to destroy the region
+         * even if it was not created at the beginning of
+         * this function as, at the time, the backing store
+         * was off. miCheckSubSaveUnder() appear to get a
+         * pointer to the parent, so maybe doesn't change
+         * the attribute of the window itself. This is to
+         * be better investigated.
+         */
+
+        if (WasViewable && pOldClip)
+            REGION_DESTROY(pScreen, pOldClip);
+#else
+	if (WasViewable)
+	    REGION_DESTROY(pScreen, pOldClip);
+#endif
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+    
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+    }
+    if (WasViewable)
+    {
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+    CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+    register WindowPtr pWin;
+    unsigned int width;
+{
+    WindowPtr pParent;
+    int oldwidth;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    oldwidth = wBorderWidth (pWin);
+    if (oldwidth == width)
+	return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    pParent = pWin->parent;
+    if (WasViewable && width < oldwidth)
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+    pWin->borderWidth = width;
+    SetBorderSize (pWin);
+
+    if (WasViewable)
+    {
+	if (width > oldwidth)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+	    /*
+	     * save the old border visible region to correctly compute
+	     * borderExposed.
+	     */
+	    if (pWin->valdata && HadBorder)
+	    {
+		RegionPtr   borderVisible;
+		borderVisible = REGION_CREATE(pScreen, NULL, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+					  VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+    WindowPtr pChild;
+    WindowPtr pWin;
+    Bool fromConfigure;
+{
+    if ((pChild != pWin) || fromConfigure)
+    {
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+	if (pChild->drawable.pScreen->ClipNotify)
+	    (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+    }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+    ScreenPtr pScreen;
+    WindowPtr pChild;
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+    {
+	if (pChild->drawable.depth == depth)
+	    REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+	if (pChild->firstChild)
+	    miSegregateChildren(pChild, pReg, depth);
+    }
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.NX.original
new file mode 100644
index 000000000..ea2e7df28
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.NX.original
@@ -0,0 +1,1205 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXmiwindow.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.7 2001/12/14 20:00:28 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#include "X.h"
+#include "miscstruct.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void 
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+    WindowPtr pWin;
+    int x,y;
+    int w,h;
+    Bool generateExposures;
+{
+    BoxRec box;
+    RegionRec	reg;
+    RegionPtr pBSReg = NullRegion;
+    ScreenPtr	pScreen;
+    BoxPtr  extents;
+    int	    x1, y1, x2, y2;
+
+    /* compute everything using ints to avoid overflow */
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;	
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    extents = &pWin->clipList.extents;
+    
+    /* clip the resulting rectangle to the window clipList extents.  This
+     * makes sure that the result will fit in a box, given that the
+     * screen is < 32768 on a side.
+     */
+
+    if (x1 < extents->x1)
+	x1 = extents->x1;
+    if (x2 > extents->x2)
+	x2 = extents->x2;
+    if (y1 < extents->y1)
+	y1 = extents->y1;
+    if (y2 > extents->y2)
+	y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1)
+    {
+	x2 = x1 = 0;
+	y2 = y1 = 0;
+    }
+
+    box.x1 = x1;
+    box.x2 = x2;
+    box.y1 = y1;
+    box.y2 = y2;
+
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &reg, &box, 1);
+    if (pWin->backStorage)
+    {
+	/*
+	 * If the window has backing-store on, call through the
+	 * ClearToBackground vector to handle the special semantics
+	 * (i.e. things backing store is to be cleared out and
+	 * an Expose event is to be generated for those areas in backing
+	 * store if generateExposures is TRUE).
+	 */
+	pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+						 generateExposures);
+    }
+
+    REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+    if (generateExposures)
+	(*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+    else if (pWin->backgroundState != None)
+        (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+    REGION_UNINIT(pScreen, &reg);
+    if (pBSReg)
+	REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ *	Check all the inferiors of a window for coverage by saveUnder
+ *	windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ *	This code is very inefficient.
+ *
+ * Results:
+ *	TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+    register WindowPtr	pParent,	/* Parent to check */
+    WindowPtr		pFirst,		/* first reconfigured window */
+    RegionPtr		pRegion)	/* Initial area obscured by saveUnder */
+{
+    register WindowPtr	pChild;		/* Current child */
+    register ScreenPtr	pScreen;	/* Screen to use */
+    RegionRec		SubRegion;	/* Area of children obscured */
+    Bool		res = FALSE;	/* result */
+    Bool		subInited=FALSE;/* SubRegion initialized */
+
+    pScreen = pParent->drawable.pScreen;
+    if ( (pChild = pParent->firstChild) )
+    {
+	/*
+	 * build region above first changed window
+	 */
+
+	for (; pChild != pFirst; pChild = pChild->nextSib)
+	    if (pChild->viewable && pChild->saveUnder)
+		REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	
+	/*
+	 * check region below and including first changed window
+	 */
+
+	for (; pChild; pChild = pChild->nextSib)
+	{
+	    if (pChild->viewable)
+	    {
+		/*
+		 * don't save under nephew/niece windows;
+		 * use a separate region
+		 */
+
+		if (pChild->firstChild)
+		{
+		    if (!subInited)
+		    {
+			REGION_INIT(pScreen, &SubRegion, NullBox, 0);
+			subInited = TRUE;
+		    }
+		    REGION_COPY(pScreen, &SubRegion, pRegion);
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     &SubRegion);
+		}
+		else
+		{
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     pRegion);
+		}
+
+		if (pChild->saveUnder)
+		    REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	    }
+	}
+
+	if (subInited)
+	    REGION_UNINIT(pScreen, &SubRegion);
+    }
+
+    /*
+     * Check the state of this window.	DIX save unders are
+     * enabled for viewable windows with some client expressing
+     * exposure interest and which intersect the save under region
+     */
+
+    if (pParent->viewable && 
+	((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+	REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+	RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen, 
+					&pParent->borderSize)) != rgnOUT)
+    {
+	if (!pParent->DIXsaveUnder)
+	{
+	    pParent->DIXsaveUnder = TRUE;
+	    (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+	}
+    }
+    else
+    {
+	if (pParent->DIXsaveUnder)
+	{
+	    res = TRUE;
+	    pParent->DIXsaveUnder = FALSE;
+	}
+    }
+    return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ *	Change the save-under state of a tree of windows. Called when
+ *	a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *	
+ * Results:
+ *	TRUE if any windows need to have backing-store removed (which
+ *	means that PostChangeSaveUnder needs to be called later to 
+ *	finish the job).
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+    register WindowPtr	pWin;
+    WindowPtr		first;		/* First window to check.
+					 * Used when pWin was restacked */
+{
+    RegionRec	rgn;	/* Area obscured by saveUnder windows */
+    register ScreenPtr pScreen;
+    Bool	res;
+
+    if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+	return FALSE;
+    numSaveUndersViewable += deltaSaveUndersViewable;
+    deltaSaveUndersViewable = 0;
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &rgn, NullBox, 1);
+    res = miCheckSubSaveUnder (pWin->parent,
+			       pWin->saveUnder ? first : pWin->nextSib,
+			       &rgn);
+    REGION_UNINIT(pScreen, &rgn);
+    return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ *	Actually turn backing-store off for those windows that no longer
+ *	need to have it on.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ *	windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+    WindowPtr		pWin;
+    WindowPtr		pFirst;
+{
+    register WindowPtr pParent, pChild;
+    ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+    if (!(pParent = pWin->parent))
+	return;
+    ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+    if (!pParent->DIXsaveUnder &&
+	(pParent->backingStore == NotUseful) && pParent->backStorage)
+	(*ChangeWindowAttributes)(pParent, CWBackingStore);
+    if (!(pChild = pFirst))
+	return;
+    while (1)
+    {
+	if (!pChild->DIXsaveUnder &&
+	    (pChild->backingStore == NotUseful) && pChild->backStorage)
+	    (*ChangeWindowAttributes)(pChild, CWBackingStore);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib)
+	{
+	    pChild = pChild->parent;
+	    if (pChild == pParent)
+		return;
+	}
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMarkWindow(pWin)
+    register WindowPtr pWin;
+{
+    register ValidatePtr val;
+
+    if (pWin->valdata)
+	return;
+    val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+    val->before.oldAbsCorner.x = pWin->drawable.x;
+    val->before.oldAbsCorner.y = pWin->drawable.y;
+    val->before.borderVisible = NullRegion;
+    val->before.resized = FALSE;
+    pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+    WindowPtr pWin;
+    WindowPtr pFirst;
+    WindowPtr *ppLayerWin;
+{
+    register BoxPtr box;
+    register WindowPtr pChild, pLast;
+    Bool anyMarked = FALSE;
+    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+    ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+
+    /* single layered systems are easy */
+    if (ppLayerWin) *ppLayerWin = pWin;
+
+    if (pWin == pFirst)
+    {
+	/* Blindly mark pWin and all of its inferiors.	 This is a slight
+	 * overkill if there are mapped windows that outside pWin's border,
+	 * but it's better than wasting time on RectIn checks.
+	 */
+	pChild = pWin;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		(* MarkWindow)(pChild);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pWin))
+		pChild = pChild->parent;
+	    if (pChild == pWin)
+		break;
+	    pChild = pChild->nextSib;
+	}
+	anyMarked = TRUE;
+	pFirst = pFirst->nextSib;
+    }
+    if ( (pChild = pFirst) )
+    {
+	box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+	pLast = pChild->parent->lastChild;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+		{
+		    (* MarkWindow)(pChild);
+		    anyMarked = TRUE;
+		    if (pChild->firstChild)
+		    {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pLast))
+		pChild = pChild->parent;
+	    if (pChild == pLast)
+		break;
+	    pChild = pChild->nextSib;
+	}
+    }
+    if (anyMarked)
+	(* MarkWindow)(pWin->parent);
+    return anyMarked;
+}
+
+/*****
+ *  miHandleValidateExposures(pWin)
+ *    starting at pWin, draw background in any windows that have exposure
+ *    regions, translate the regions, restore any backing store,
+ *    and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+    WindowPtr pWin;
+{
+    register WindowPtr pChild;
+    register ValidatePtr val;
+    ScreenPtr pScreen;
+    WindowExposuresProcPtr WindowExposures;
+
+    pScreen = pWin->drawable.pScreen;
+
+    pChild = pWin;
+    WindowExposures = pChild->drawable.pScreen->WindowExposures;
+    while (1)
+    {
+	if ( (val = pChild->valdata) )
+	{
+	    if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+		(*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+						    &val->after.borderExposed,
+						    PW_BORDER);
+	    REGION_UNINIT(pScreen, &val->after.borderExposed);
+	    (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+	    REGION_UNINIT(pScreen, &val->after.exposed);
+	    xfree(val);
+	    pChild->valdata = (ValidatePtr)NULL;
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+    register WindowPtr pWin;
+    int x,y;
+    WindowPtr pNextSib;
+    VTKind kind;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    short bw;
+    RegionPtr oldRegion = NULL;
+    DDXPointRec oldpt;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+    Bool dosave = FALSE;
+#endif
+    WindowPtr pLayerWin;
+
+    /* if this is a root window, can't be moved */
+    if (!(pParent = pWin->parent))
+       return ;
+    pScreen = pWin->drawable.pScreen;
+    bw = wBorderWidth (pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable)
+    {
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    }
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, windowToValidate, (WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+	    REGION_DESTROY(pScreen, oldRegion);
+	    /* XXX need to retile border if ParentRelative origin */
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+    register WindowPtr	pWin,
+    pointer		value) /* must conform to VisitWindowProcPtr */
+{
+    register ScreenPtr	pScreen;
+    RegionPtr	pValid = (RegionPtr)value;
+
+    if (pWin->valdata)
+    {
+	pScreen = pWin->drawable.pScreen;
+	/*
+	 * compute exposed regions of this window
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+			&pWin->clipList, pValid);
+	/*
+	 * compute exposed regions of the border
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->borderClip, &pWin->winSize);
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->valdata->after.borderExposed, pValid);
+	return WT_WALKCHILDREN;
+    }
+    return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+    register WindowPtr pWin;
+    int x,y;
+    unsigned int w, h;
+    WindowPtr pSib;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    unsigned short width = pWin->drawable.width,
+		   height = pWin->drawable.height;
+    short oldx = pWin->drawable.x,
+	  oldy = pWin->drawable.y;
+    int bw = wBorderWidth (pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr pFirstChange;
+    register WindowPtr pChild;
+    RegionPtr	gravitate[StaticGravity + 1];
+    register unsigned g;
+    int		nx, ny;		/* destination x,y */
+    int		newx, newy;	/* new inner window position */
+    RegionPtr	pRegion = NULL;
+    RegionPtr	destClip;	/* portions of destination already written */
+    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
+    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
+    RegionPtr	bsExposed = NullRegion;	    /* backing store exposures */
+    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
+    Bool	moved = FALSE;	/* window position changed */
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pScreen = pWin->drawable.pScreen;
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable)
+    {
+	anyMarked = FALSE;
+	/*
+	 * save the visible region of the window
+	 */
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+	/*
+	 * categorize child windows into regions to be moved
+	 */
+	for (g = 0; g <= StaticGravity; g++)
+	    gravitate[g] = (RegionPtr) NULL;
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	{
+	    g = pChild->winGravity;
+	    if (g != UnmapGravity)
+	    {
+		if (!gravitate[g])
+		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_UNION(pScreen, gravitate[g],
+				   gravitate[g], &pChild->borderClip);
+	    }
+	    else
+	    {
+		UnmapWindow(pChild, TRUE);
+		anyMarked = TRUE;
+	    }
+	}
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
+						       &pLayerWin);
+
+	oldWinClip = NULL;
+	if (pWin->bitGravity != ForgetGravity)
+	{
+	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+	}
+	/*
+	 * if the window is changing size, borderExposed
+	 * can't be computed correctly without some help.
+	 */
+	if (pWin->drawable.height > h || pWin->drawable.width > w)
+	    shrunk = TRUE;
+
+	if (newx != oldx || newy != oldy)
+	    moved = TRUE;
+
+	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+	    HasBorder (pWin))
+	{
+	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+	    /* for tiled borders, we punt and draw the whole thing */
+	    if (pWin->borderIsPixel || !moved)
+	    {
+		if (shrunk || moved)
+		    REGION_SUBTRACT(pScreen, borderVisible,
+					  &pWin->borderClip,
+					  &pWin->winSize);
+		else
+		    REGION_COPY(pScreen, borderVisible,
+					    &pWin->borderClip);
+	    }
+	}
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    dw = (int)w - (int)width;
+    dh = (int)h - (int)height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	pRegion = REGION_CREATE(pScreen, NullBox, 1);
+	if (pWin->backStorage)
+	    REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						(WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						(WindowPtr *)NULL);
+
+	if (pWin->valdata)
+	{
+	    pWin->valdata->before.resized = TRUE;
+	    pWin->valdata->before.borderVisible = borderVisible;
+	}
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+	/*
+	 * the entire window is trashed unless bitGravity
+	 * recovers portions of it
+	 */
+	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+    }
+
+    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pRegion = &pWin->clipList; /* a convenient empty region */
+	if (pWin->bitGravity == ForgetGravity)
+	    bsExposed = (*pScreen->TranslateBackingStore)
+				(pWin, 0, 0, NullRegion, oldx, oldy);
+	else
+	{
+	    bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+	}
+    }
+
+    if (WasViewable)
+    {
+	/* avoid the border */
+	if (HasBorder (pWin))
+	{
+	    int	offx, offy, dx, dy;
+
+	    /* kruft to avoid double translates for each gravity */
+	    offx = 0;
+	    offy = 0;
+	    for (g = 0; g <= StaticGravity; g++)
+	    {
+		if (!gravitate[g])
+		    continue;
+
+		/* align winSize to gravitate[g].
+		 * winSize is in new coordinates,
+		 * gravitate[g] is still in old coordinates */
+		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+		
+		dx = (oldx - nx) - offx;
+		dy = (oldy - ny) - offy;
+		if (dx || dy)
+		{
+		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+		    offx += dx;
+		    offy += dy;
+		}
+		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+				 &pWin->winSize);
+	    }
+	    /* get winSize back where it belongs */
+	    if (offx || offy)
+		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+	}
+	/*
+	 * add screen bits to the appropriate bucket
+	 */
+
+	if (oldWinClip)
+	{
+	    /*
+	     * clip to new clipList
+	     */
+	    REGION_COPY(pScreen, pRegion, oldWinClip);
+	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+	    /*
+	     * don't step on any gravity bits which will be copied after this
+	     * region.	Note -- this assumes that the regions will be copied
+	     * in gravity order.
+	     */
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+	    {
+		if (gravitate[g])
+		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+					gravitate[g]);
+	    }
+	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate[g])
+		gravitate[g] = oldWinClip;
+	    else
+	    {
+		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+		REGION_DESTROY(pScreen, oldWinClip);
+	    }
+	}
+
+	/*
+	 * move the bits on the screen
+	 */
+
+	destClip = NULL;
+
+	for (g = 0; g <= StaticGravity; g++)
+	{
+	    if (!gravitate[g])
+		continue;
+
+	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+	    oldpt.x = oldx + (x - nx);
+	    oldpt.y = oldy + (y - ny);
+
+	    /* Note that gravitate[g] is *translated* by CopyWindow */
+
+	    /* only copy the remaining useful bits */
+
+	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+	    /* clip to not overwrite already copied areas */
+
+	    if (destClip) {
+		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+	    }
+
+	    /* and move those bits */
+
+	    if (oldpt.x != x || oldpt.y != y)
+		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+
+	    /* remove any overwritten bits from the remaining useful bits */
+
+	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+	    /*
+	     * recompute exposed regions of child windows
+	     */
+	
+	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	    {
+		if (pChild->winGravity != g)
+		    continue;
+		REGION_INTERSECT(pScreen, pRegion,
+				       &pChild->borderClip, gravitate[g]);
+		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+	    }
+
+	    /*
+	     * remove the successfully copied regions of the
+	     * window from its exposed region
+	     */
+
+	    if (g == pWin->bitGravity)
+		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+				     &pWin->valdata->after.exposed, gravitate[g]);
+	    if (!destClip)
+		destClip = gravitate[g];
+	    else
+	    {
+		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+		REGION_DESTROY(pScreen, gravitate[g]);
+	    }
+	}
+
+	REGION_DESTROY(pScreen, oldRegion);
+	REGION_DESTROY(pScreen, pRegion);
+	if (destClip)
+	    REGION_DESTROY(pScreen, destClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	{
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+					  VTOther);
+    }
+    else if (bsExposed)
+    {
+	(*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+	REGION_DESTROY(pScreen, bsExposed);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+    WindowPtr pWin;
+{
+    return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ *    The border/window shape has changed.  Recompute winSize/borderSize
+ *    and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+    register WindowPtr	pWin;
+{
+    Bool	WasViewable = (Bool)(pWin->viewable);
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    Bool	anyMarked = FALSE;
+    RegionPtr	pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr   pLayerWin;
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						      &pLayerWin);
+	if (pWin->valdata)
+	{
+	    if (HasBorder (pWin))
+	    {
+		RegionPtr	borderVisible;
+
+		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	    pWin->valdata->before.resized = TRUE;
+	}
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pWin->backStorage)
+	{
+	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+	}
+
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						(WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pOldClip = &pWin->clipList; /* a convenient empty region */
+	bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, 0, 0, pOldClip,
+			      pWin->drawable.x, pWin->drawable.y);
+#ifdef NXAGENT_SERVER
+
+        /*
+         * We got a few, rare, segfaults here after having
+         * started using the backing store. It may be a
+         * different bug but miChangeSaveUnder() calls mi-
+         * CheckSubSaveUnder() that, in turn, can change
+         * the backing store attribute of the window. This
+         * means that we may try to destroy the region
+         * even if it was not created at the beginning of
+         * this function as, at the time, the backing store
+         * was off. miCheckSubSaveUnder() appear to get a
+         * pointer to the parent, so maybe doesn't change
+         * the attribute of the window itself. This is to
+         * be better investigated.
+         */
+
+        if (WasViewable && pOldClip)
+            REGION_DESTROY(pScreen, pOldClip);
+#else
+	if (WasViewable)
+	    REGION_DESTROY(pScreen, pOldClip);
+#endif
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+    
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+    }
+    if (WasViewable)
+    {
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+    CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+    register WindowPtr pWin;
+    unsigned int width;
+{
+    WindowPtr pParent;
+    int oldwidth;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    oldwidth = wBorderWidth (pWin);
+    if (oldwidth == width)
+	return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    pParent = pWin->parent;
+    if (WasViewable && width < oldwidth)
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+    pWin->borderWidth = width;
+    SetBorderSize (pWin);
+
+    if (WasViewable)
+    {
+	if (width > oldwidth)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+	    /*
+	     * save the old border visible region to correctly compute
+	     * borderExposed.
+	     */
+	    if (pWin->valdata && HadBorder)
+	    {
+		RegionPtr   borderVisible;
+		borderVisible = REGION_CREATE(pScreen, NULL, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+					  VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+    WindowPtr pChild;
+    WindowPtr pWin;
+    Bool fromConfigure;
+{
+    if ((pChild != pWin) || fromConfigure)
+    {
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+	if (pChild->drawable.pScreen->ClipNotify)
+	    (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+    }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+    ScreenPtr pScreen;
+    WindowPtr pChild;
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+    {
+	if (pChild->drawable.depth == depth)
+	    REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+	if (pChild->firstChild)
+	    miSegregateChildren(pChild, pReg, depth);
+    }
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.XF86.original
new file mode 100644
index 000000000..fbced41c6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiwindow.c.XF86.original
@@ -0,0 +1,1176 @@
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.7 2001/12/14 20:00:28 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#include "X.h"
+#include "miscstruct.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void 
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+    WindowPtr pWin;
+    int x,y;
+    int w,h;
+    Bool generateExposures;
+{
+    BoxRec box;
+    RegionRec	reg;
+    RegionPtr pBSReg = NullRegion;
+    ScreenPtr	pScreen;
+    BoxPtr  extents;
+    int	    x1, y1, x2, y2;
+
+    /* compute everything using ints to avoid overflow */
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;	
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    extents = &pWin->clipList.extents;
+    
+    /* clip the resulting rectangle to the window clipList extents.  This
+     * makes sure that the result will fit in a box, given that the
+     * screen is < 32768 on a side.
+     */
+
+    if (x1 < extents->x1)
+	x1 = extents->x1;
+    if (x2 > extents->x2)
+	x2 = extents->x2;
+    if (y1 < extents->y1)
+	y1 = extents->y1;
+    if (y2 > extents->y2)
+	y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1)
+    {
+	x2 = x1 = 0;
+	y2 = y1 = 0;
+    }
+
+    box.x1 = x1;
+    box.x2 = x2;
+    box.y1 = y1;
+    box.y2 = y2;
+
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &reg, &box, 1);
+    if (pWin->backStorage)
+    {
+	/*
+	 * If the window has backing-store on, call through the
+	 * ClearToBackground vector to handle the special semantics
+	 * (i.e. things backing store is to be cleared out and
+	 * an Expose event is to be generated for those areas in backing
+	 * store if generateExposures is TRUE).
+	 */
+	pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+						 generateExposures);
+    }
+
+    REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+    if (generateExposures)
+	(*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+    else if (pWin->backgroundState != None)
+        (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+    REGION_UNINIT(pScreen, &reg);
+    if (pBSReg)
+	REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ *	Check all the inferiors of a window for coverage by saveUnder
+ *	windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ *	This code is very inefficient.
+ *
+ * Results:
+ *	TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+    register WindowPtr	pParent,	/* Parent to check */
+    WindowPtr		pFirst,		/* first reconfigured window */
+    RegionPtr		pRegion)	/* Initial area obscured by saveUnder */
+{
+    register WindowPtr	pChild;		/* Current child */
+    register ScreenPtr	pScreen;	/* Screen to use */
+    RegionRec		SubRegion;	/* Area of children obscured */
+    Bool		res = FALSE;	/* result */
+    Bool		subInited=FALSE;/* SubRegion initialized */
+
+    pScreen = pParent->drawable.pScreen;
+    if ( (pChild = pParent->firstChild) )
+    {
+	/*
+	 * build region above first changed window
+	 */
+
+	for (; pChild != pFirst; pChild = pChild->nextSib)
+	    if (pChild->viewable && pChild->saveUnder)
+		REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	
+	/*
+	 * check region below and including first changed window
+	 */
+
+	for (; pChild; pChild = pChild->nextSib)
+	{
+	    if (pChild->viewable)
+	    {
+		/*
+		 * don't save under nephew/niece windows;
+		 * use a separate region
+		 */
+
+		if (pChild->firstChild)
+		{
+		    if (!subInited)
+		    {
+			REGION_INIT(pScreen, &SubRegion, NullBox, 0);
+			subInited = TRUE;
+		    }
+		    REGION_COPY(pScreen, &SubRegion, pRegion);
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     &SubRegion);
+		}
+		else
+		{
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     pRegion);
+		}
+
+		if (pChild->saveUnder)
+		    REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	    }
+	}
+
+	if (subInited)
+	    REGION_UNINIT(pScreen, &SubRegion);
+    }
+
+    /*
+     * Check the state of this window.	DIX save unders are
+     * enabled for viewable windows with some client expressing
+     * exposure interest and which intersect the save under region
+     */
+
+    if (pParent->viewable && 
+	((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+	REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+	RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen, 
+					&pParent->borderSize)) != rgnOUT)
+    {
+	if (!pParent->DIXsaveUnder)
+	{
+	    pParent->DIXsaveUnder = TRUE;
+	    (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+	}
+    }
+    else
+    {
+	if (pParent->DIXsaveUnder)
+	{
+	    res = TRUE;
+	    pParent->DIXsaveUnder = FALSE;
+	}
+    }
+    return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ *	Change the save-under state of a tree of windows. Called when
+ *	a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *	
+ * Results:
+ *	TRUE if any windows need to have backing-store removed (which
+ *	means that PostChangeSaveUnder needs to be called later to 
+ *	finish the job).
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+    register WindowPtr	pWin;
+    WindowPtr		first;		/* First window to check.
+					 * Used when pWin was restacked */
+{
+    RegionRec	rgn;	/* Area obscured by saveUnder windows */
+    register ScreenPtr pScreen;
+    Bool	res;
+
+    if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+	return FALSE;
+    numSaveUndersViewable += deltaSaveUndersViewable;
+    deltaSaveUndersViewable = 0;
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &rgn, NullBox, 1);
+    res = miCheckSubSaveUnder (pWin->parent,
+			       pWin->saveUnder ? first : pWin->nextSib,
+			       &rgn);
+    REGION_UNINIT(pScreen, &rgn);
+    return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ *	Actually turn backing-store off for those windows that no longer
+ *	need to have it on.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ *	windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+    WindowPtr		pWin;
+    WindowPtr		pFirst;
+{
+    register WindowPtr pParent, pChild;
+    ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+    if (!(pParent = pWin->parent))
+	return;
+    ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+    if (!pParent->DIXsaveUnder &&
+	(pParent->backingStore == NotUseful) && pParent->backStorage)
+	(*ChangeWindowAttributes)(pParent, CWBackingStore);
+    if (!(pChild = pFirst))
+	return;
+    while (1)
+    {
+	if (!pChild->DIXsaveUnder &&
+	    (pChild->backingStore == NotUseful) && pChild->backStorage)
+	    (*ChangeWindowAttributes)(pChild, CWBackingStore);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib)
+	{
+	    pChild = pChild->parent;
+	    if (pChild == pParent)
+		return;
+	}
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMarkWindow(pWin)
+    register WindowPtr pWin;
+{
+    register ValidatePtr val;
+
+    if (pWin->valdata)
+	return;
+    val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+    val->before.oldAbsCorner.x = pWin->drawable.x;
+    val->before.oldAbsCorner.y = pWin->drawable.y;
+    val->before.borderVisible = NullRegion;
+    val->before.resized = FALSE;
+    pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+    WindowPtr pWin;
+    WindowPtr pFirst;
+    WindowPtr *ppLayerWin;
+{
+    register BoxPtr box;
+    register WindowPtr pChild, pLast;
+    Bool anyMarked = FALSE;
+    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+    ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+
+    /* single layered systems are easy */
+    if (ppLayerWin) *ppLayerWin = pWin;
+
+    if (pWin == pFirst)
+    {
+	/* Blindly mark pWin and all of its inferiors.	 This is a slight
+	 * overkill if there are mapped windows that outside pWin's border,
+	 * but it's better than wasting time on RectIn checks.
+	 */
+	pChild = pWin;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		(* MarkWindow)(pChild);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pWin))
+		pChild = pChild->parent;
+	    if (pChild == pWin)
+		break;
+	    pChild = pChild->nextSib;
+	}
+	anyMarked = TRUE;
+	pFirst = pFirst->nextSib;
+    }
+    if ( (pChild = pFirst) )
+    {
+	box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+	pLast = pChild->parent->lastChild;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+		{
+		    (* MarkWindow)(pChild);
+		    anyMarked = TRUE;
+		    if (pChild->firstChild)
+		    {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pLast))
+		pChild = pChild->parent;
+	    if (pChild == pLast)
+		break;
+	    pChild = pChild->nextSib;
+	}
+    }
+    if (anyMarked)
+	(* MarkWindow)(pWin->parent);
+    return anyMarked;
+}
+
+/*****
+ *  miHandleValidateExposures(pWin)
+ *    starting at pWin, draw background in any windows that have exposure
+ *    regions, translate the regions, restore any backing store,
+ *    and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+    WindowPtr pWin;
+{
+    register WindowPtr pChild;
+    register ValidatePtr val;
+    ScreenPtr pScreen;
+    WindowExposuresProcPtr WindowExposures;
+
+    pScreen = pWin->drawable.pScreen;
+
+    pChild = pWin;
+    WindowExposures = pChild->drawable.pScreen->WindowExposures;
+    while (1)
+    {
+	if ( (val = pChild->valdata) )
+	{
+	    if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+		(*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+						    &val->after.borderExposed,
+						    PW_BORDER);
+	    REGION_UNINIT(pScreen, &val->after.borderExposed);
+	    (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+	    REGION_UNINIT(pScreen, &val->after.exposed);
+	    xfree(val);
+	    pChild->valdata = (ValidatePtr)NULL;
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+    register WindowPtr pWin;
+    int x,y;
+    WindowPtr pNextSib;
+    VTKind kind;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    short bw;
+    RegionPtr oldRegion = NULL;
+    DDXPointRec oldpt;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+    Bool dosave = FALSE;
+#endif
+    WindowPtr pLayerWin;
+
+    /* if this is a root window, can't be moved */
+    if (!(pParent = pWin->parent))
+       return ;
+    pScreen = pWin->drawable.pScreen;
+    bw = wBorderWidth (pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable)
+    {
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    }
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, windowToValidate, (WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+	    REGION_DESTROY(pScreen, oldRegion);
+	    /* XXX need to retile border if ParentRelative origin */
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+    register WindowPtr	pWin,
+    pointer		value) /* must conform to VisitWindowProcPtr */
+{
+    register ScreenPtr	pScreen;
+    RegionPtr	pValid = (RegionPtr)value;
+
+    if (pWin->valdata)
+    {
+	pScreen = pWin->drawable.pScreen;
+	/*
+	 * compute exposed regions of this window
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+			&pWin->clipList, pValid);
+	/*
+	 * compute exposed regions of the border
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->borderClip, &pWin->winSize);
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->valdata->after.borderExposed, pValid);
+	return WT_WALKCHILDREN;
+    }
+    return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+    register WindowPtr pWin;
+    int x,y;
+    unsigned int w, h;
+    WindowPtr pSib;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    unsigned short width = pWin->drawable.width,
+		   height = pWin->drawable.height;
+    short oldx = pWin->drawable.x,
+	  oldy = pWin->drawable.y;
+    int bw = wBorderWidth (pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr pFirstChange;
+    register WindowPtr pChild;
+    RegionPtr	gravitate[StaticGravity + 1];
+    register unsigned g;
+    int		nx, ny;		/* destination x,y */
+    int		newx, newy;	/* new inner window position */
+    RegionPtr	pRegion = NULL;
+    RegionPtr	destClip;	/* portions of destination already written */
+    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
+    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
+    RegionPtr	bsExposed = NullRegion;	    /* backing store exposures */
+    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
+    Bool	moved = FALSE;	/* window position changed */
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pScreen = pWin->drawable.pScreen;
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable)
+    {
+	anyMarked = FALSE;
+	/*
+	 * save the visible region of the window
+	 */
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+	/*
+	 * categorize child windows into regions to be moved
+	 */
+	for (g = 0; g <= StaticGravity; g++)
+	    gravitate[g] = (RegionPtr) NULL;
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	{
+	    g = pChild->winGravity;
+	    if (g != UnmapGravity)
+	    {
+		if (!gravitate[g])
+		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_UNION(pScreen, gravitate[g],
+				   gravitate[g], &pChild->borderClip);
+	    }
+	    else
+	    {
+		UnmapWindow(pChild, TRUE);
+		anyMarked = TRUE;
+	    }
+	}
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
+						       &pLayerWin);
+
+	oldWinClip = NULL;
+	if (pWin->bitGravity != ForgetGravity)
+	{
+	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+	}
+	/*
+	 * if the window is changing size, borderExposed
+	 * can't be computed correctly without some help.
+	 */
+	if (pWin->drawable.height > h || pWin->drawable.width > w)
+	    shrunk = TRUE;
+
+	if (newx != oldx || newy != oldy)
+	    moved = TRUE;
+
+	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+	    HasBorder (pWin))
+	{
+	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+	    /* for tiled borders, we punt and draw the whole thing */
+	    if (pWin->borderIsPixel || !moved)
+	    {
+		if (shrunk || moved)
+		    REGION_SUBTRACT(pScreen, borderVisible,
+					  &pWin->borderClip,
+					  &pWin->winSize);
+		else
+		    REGION_COPY(pScreen, borderVisible,
+					    &pWin->borderClip);
+	    }
+	}
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    dw = (int)w - (int)width;
+    dh = (int)h - (int)height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	pRegion = REGION_CREATE(pScreen, NullBox, 1);
+	if (pWin->backStorage)
+	    REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						(WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						(WindowPtr *)NULL);
+
+	if (pWin->valdata)
+	{
+	    pWin->valdata->before.resized = TRUE;
+	    pWin->valdata->before.borderVisible = borderVisible;
+	}
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+	/*
+	 * the entire window is trashed unless bitGravity
+	 * recovers portions of it
+	 */
+	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+    }
+
+    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pRegion = &pWin->clipList; /* a convenient empty region */
+	if (pWin->bitGravity == ForgetGravity)
+	    bsExposed = (*pScreen->TranslateBackingStore)
+				(pWin, 0, 0, NullRegion, oldx, oldy);
+	else
+	{
+	    bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+	}
+    }
+
+    if (WasViewable)
+    {
+	/* avoid the border */
+	if (HasBorder (pWin))
+	{
+	    int	offx, offy, dx, dy;
+
+	    /* kruft to avoid double translates for each gravity */
+	    offx = 0;
+	    offy = 0;
+	    for (g = 0; g <= StaticGravity; g++)
+	    {
+		if (!gravitate[g])
+		    continue;
+
+		/* align winSize to gravitate[g].
+		 * winSize is in new coordinates,
+		 * gravitate[g] is still in old coordinates */
+		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+		
+		dx = (oldx - nx) - offx;
+		dy = (oldy - ny) - offy;
+		if (dx || dy)
+		{
+		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+		    offx += dx;
+		    offy += dy;
+		}
+		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+				 &pWin->winSize);
+	    }
+	    /* get winSize back where it belongs */
+	    if (offx || offy)
+		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+	}
+	/*
+	 * add screen bits to the appropriate bucket
+	 */
+
+	if (oldWinClip)
+	{
+	    /*
+	     * clip to new clipList
+	     */
+	    REGION_COPY(pScreen, pRegion, oldWinClip);
+	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+	    /*
+	     * don't step on any gravity bits which will be copied after this
+	     * region.	Note -- this assumes that the regions will be copied
+	     * in gravity order.
+	     */
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+	    {
+		if (gravitate[g])
+		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+					gravitate[g]);
+	    }
+	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate[g])
+		gravitate[g] = oldWinClip;
+	    else
+	    {
+		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+		REGION_DESTROY(pScreen, oldWinClip);
+	    }
+	}
+
+	/*
+	 * move the bits on the screen
+	 */
+
+	destClip = NULL;
+
+	for (g = 0; g <= StaticGravity; g++)
+	{
+	    if (!gravitate[g])
+		continue;
+
+	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+	    oldpt.x = oldx + (x - nx);
+	    oldpt.y = oldy + (y - ny);
+
+	    /* Note that gravitate[g] is *translated* by CopyWindow */
+
+	    /* only copy the remaining useful bits */
+
+	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+	    /* clip to not overwrite already copied areas */
+
+	    if (destClip) {
+		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+	    }
+
+	    /* and move those bits */
+
+	    if (oldpt.x != x || oldpt.y != y)
+		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+
+	    /* remove any overwritten bits from the remaining useful bits */
+
+	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+	    /*
+	     * recompute exposed regions of child windows
+	     */
+	
+	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	    {
+		if (pChild->winGravity != g)
+		    continue;
+		REGION_INTERSECT(pScreen, pRegion,
+				       &pChild->borderClip, gravitate[g]);
+		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+	    }
+
+	    /*
+	     * remove the successfully copied regions of the
+	     * window from its exposed region
+	     */
+
+	    if (g == pWin->bitGravity)
+		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+				     &pWin->valdata->after.exposed, gravitate[g]);
+	    if (!destClip)
+		destClip = gravitate[g];
+	    else
+	    {
+		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+		REGION_DESTROY(pScreen, gravitate[g]);
+	    }
+	}
+
+	REGION_DESTROY(pScreen, oldRegion);
+	REGION_DESTROY(pScreen, pRegion);
+	if (destClip)
+	    REGION_DESTROY(pScreen, destClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	{
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+					  VTOther);
+    }
+    else if (bsExposed)
+    {
+	(*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+	REGION_DESTROY(pScreen, bsExposed);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+    WindowPtr pWin;
+{
+    return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ *    The border/window shape has changed.  Recompute winSize/borderSize
+ *    and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+    register WindowPtr	pWin;
+{
+    Bool	WasViewable = (Bool)(pWin->viewable);
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    Bool	anyMarked = FALSE;
+    RegionPtr	pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr   pLayerWin;
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						      &pLayerWin);
+	if (pWin->valdata)
+	{
+	    if (HasBorder (pWin))
+	    {
+		RegionPtr	borderVisible;
+
+		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	    pWin->valdata->before.resized = TRUE;
+	}
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pWin->backStorage)
+	{
+	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+	}
+
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						(WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pOldClip = &pWin->clipList; /* a convenient empty region */
+	bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, 0, 0, pOldClip,
+			      pWin->drawable.x, pWin->drawable.y);
+	if (WasViewable)
+	    REGION_DESTROY(pScreen, pOldClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+    
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+    }
+    if (WasViewable)
+    {
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+    CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+    register WindowPtr pWin;
+    unsigned int width;
+{
+    WindowPtr pParent;
+    int oldwidth;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    oldwidth = wBorderWidth (pWin);
+    if (oldwidth == width)
+	return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    pParent = pWin->parent;
+    if (WasViewable && width < oldwidth)
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+    pWin->borderWidth = width;
+    SetBorderSize (pWin);
+
+    if (WasViewable)
+    {
+	if (width > oldwidth)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+	    /*
+	     * save the old border visible region to correctly compute
+	     * borderExposed.
+	     */
+	    if (pWin->valdata && HadBorder)
+	    {
+		RegionPtr   borderVisible;
+		borderVisible = REGION_CREATE(pScreen, NULL, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+					  VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+    WindowPtr pChild;
+    WindowPtr pWin;
+    Bool fromConfigure;
+{
+    if ((pChild != pWin) || fromConfigure)
+    {
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+	if (pChild->drawable.pScreen->ClipNotify)
+	    (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+    }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+    ScreenPtr pScreen;
+    WindowPtr pChild;
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+    {
+	if (pChild->drawable.depth == depth)
+	    REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+	if (pChild->firstChild)
+	    miSegregateChildren(pChild, pReg, depth);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
new file mode 100644
index 000000000..64ba970c9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -0,0 +1,1512 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXpicture.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.30 2003/01/26 16:40:43 eich Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "NXpicturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
+
+int		PictureScreenPrivateIndex = -1;
+int		PictureWindowPrivateIndex;
+int		PictureGeneration;
+RESTYPE		PictureType;
+RESTYPE		PictFormatType;
+RESTYPE		GlyphSetType;
+int		PictureCmapPolicy = PictureCmapPolicyDefault;
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+    ScreenPtr		pScreen = pWindow->drawable.pScreen;
+    PicturePtr		pPicture;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool		ret;
+
+    while ((pPicture = GetPictureWindow(pWindow)))
+    {
+	SetPictureWindow(pWindow, pPicture->pNext);
+	if (pPicture->id)
+	    FreeResource (pPicture->id, PictureType);
+	FreePicture ((pointer) pPicture, pPicture->id);
+    }
+    pScreen->DestroyWindow = ps->DestroyWindow;
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool                ret;
+    int			n;
+
+    pScreen->CloseScreen = ps->CloseScreen;
+    ret = (*pScreen->CloseScreen) (index, pScreen);
+    PictureResetFilters (pScreen);
+    for (n = 0; n < ps->nformats; n++)
+	if (ps->formats[n].type == PictTypeIndexed)
+	    (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+    SetPictureScreen(pScreen, 0);
+    xfree (ps->formats);
+    xfree (ps);
+    return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+    ScreenPtr		pScreen = pColormap->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    pScreen->StoreColors = ps->StoreColors;
+    (*pScreen->StoreColors) (pColormap, ndef, pdef);
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+    {
+	PictFormatPtr	format = ps->formats;
+	int		nformats = ps->nformats;
+
+	while (nformats--)
+	{
+	    if (format->type == PictTypeIndexed &&
+		format->index.pColormap == pColormap)
+	    {
+		(*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+		break;
+	    }
+	    format++;
+	}
+    }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    int		d, v;
+    DepthPtr	pDepth;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	for (v = 0; v < pDepth->numVids; v++)
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+    }
+    return 0;
+}
+
+typedef struct _formatInit {
+    CARD32  format;
+    CARD8   depth;
+} FormatInitRec, *FormatInitPtr;
+
+static int
+addFormat (FormatInitRec    formats[256],
+	   int		    nformat,
+	   CARD32	    format,
+	   CARD8	    depth)
+{
+    int	n;
+
+    for (n = 0; n < nformat; n++)
+	if (formats[n].format == format && formats[n].depth == depth)
+	    return nformat;
+    formats[nformat].format = format;
+    formats[nformat].depth = depth;
+    return ++nformat;
+}
+
+#define Mask(n)	((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+#ifdef NXAGENT_SERVER
+    int             nformats, f, n;
+#else
+    int             nformats, f;
+#endif
+    PictFormatPtr   pFormats;
+    FormatInitRec   formats[1024];
+    CARD32	    format;
+    CARD8	    depth;
+    VisualPtr	    pVisual;
+    int		    v;
+    int		    bpp;
+    int		    type;
+    int		    r, g, b;
+    int		    d;
+    DepthPtr	    pDepth;
+
+    nformats = 0;
+    /* formats required by protocol */
+    formats[nformats].format = PICT_a1;
+    formats[nformats].depth = 1;
+    nformats++;
+    formats[nformats].format = PICT_a8;
+    formats[nformats].depth = 8;
+    nformats++;
+    formats[nformats].format = PICT_a4;
+    formats[nformats].depth = 4;
+    nformats++;
+    formats[nformats].format = PICT_a8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+    formats[nformats].format = PICT_x8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+
+    /* now look through the depths and visuals adding other formats */
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = &pScreen->visuals[v];
+	depth = visualDepth (pScreen, pVisual);
+	if (!depth)
+	    continue;
+    	bpp = BitsPerPixel (depth);
+	switch (pVisual->class) {
+	case DirectColor:
+	case TrueColor:
+	    r = Ones (pVisual->redMask);
+	    g = Ones (pVisual->greenMask);
+	    b = Ones (pVisual->blueMask);
+	    type = PICT_TYPE_OTHER;
+	    /*
+	     * Current rendering code supports only two direct formats,
+	     * fields must be packed together at the bottom of the pixel
+	     * and must be either RGB or BGR
+	     */
+	    if (pVisual->offsetBlue == 0 &&
+		pVisual->offsetGreen == b &&
+		pVisual->offsetRed == b + g)
+	    {
+		type = PICT_TYPE_ARGB;
+	    }
+	    else if (pVisual->offsetRed == 0 &&
+		     pVisual->offsetGreen == r && 
+		     pVisual->offsetBlue == r + g)
+	    {
+		type = PICT_TYPE_ABGR;
+	    }
+	    if (type != PICT_TYPE_OTHER)
+	    {
+		format = PICT_FORMAT(bpp, type, 0, r, g, b);
+		nformats = addFormat (formats, nformats, format, depth);
+	    }
+	    break;
+	case StaticColor:
+	case PseudoColor:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	case StaticGray:
+	case GrayScale:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	}
+    }
+    /*
+     * Walk supported depths and add useful Direct formats
+     */
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	bpp = BitsPerPixel (pDepth->depth);
+	format = 0;
+	switch (bpp) {
+	case 16:
+	    /* depth 12 formats */
+	    if (pDepth->depth >= 12)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x4b4g4r4, pDepth->depth);
+	    }
+	    /* depth 15 formats */
+	    if (pDepth->depth >= 15)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x1b5g5r5, pDepth->depth);
+	    }
+	    /* depth 16 formats */
+	    if (pDepth->depth >= 16) 
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_a1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a1b5g5r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_r5g6b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b5g6r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4b4g4r4, pDepth->depth);
+	    }
+	    break;
+	case 24:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b8g8r8, pDepth->depth);
+	    }
+	    break;
+	case 32:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x8r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x8b8g8r8, pDepth->depth);
+	    }
+	    break;
+	}
+    }
+    
+
+    pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+    if (!pFormats)
+	return 0;
+    memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+#ifdef NXAGENT_SERVER
+    for (f = 0, n = 0; n < nformats; n++)
+    {
+        pFormats[f].id = FakeClientID (0);
+        pFormats[f].depth = formats[n].depth;
+        format = formats[n].format;
+        pFormats[f].format = format;
+#else
+    for (f = 0; f < nformats; f++)
+    {
+        pFormats[f].id = FakeClientID (0);
+        pFormats[f].depth = formats[f].depth;
+        format = formats[f].format;
+        pFormats[f].format = format;
+#endif
+	switch (PICT_FORMAT_TYPE(format)) {
+	case PICT_TYPE_ARGB:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = (PICT_FORMAT_G(format) + 
+				      PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_B(format);
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = 0;
+	    break;
+
+	case PICT_TYPE_ABGR:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = (PICT_FORMAT_G(format) + 
+				       PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_R(format);
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = 0;
+	    break;
+
+	case PICT_TYPE_A:
+	    pFormats[f].type = PictTypeDirect;
+
+	    pFormats[f].direct.alpha = 0;
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+	    /* remaining fields already set to zero */
+	    break;
+	    
+	case PICT_TYPE_COLOR:
+	case PICT_TYPE_GRAY:
+	    pFormats[f].type = PictTypeIndexed;
+	    pFormats[f].index.pVisual = &pScreen->visuals[PICT_FORMAT_VIS(format)];
+	    break;
+	}
+
+#ifdef NXAGENT_SERVER
+        if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+        {
+          f++;
+        }
+        else
+        {
+          memset(&pFormats[f], '\0', sizeof(PictFormatRec));
+        } 
+    }
+    *nformatp = f;
+#else
+    }
+    *nformatp = nformats;
+#endif
+    return pFormats;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return FALSE;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->type == PictTypeIndexed && !format->index.pColormap)
+	{
+	    if (format->index.pVisual->vid == pScreen->rootVisual)
+		format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+								       RT_COLORMAP);
+	    else
+	    {
+		if (CreateColormap (FakeClientID (0), pScreen,
+				    format->index.pVisual,
+				    &format->index.pColormap, AllocNone,
+				    0) != Success)
+		{
+		    return FALSE;
+		}
+	    }
+	    if (!(*ps->InitIndexed) (pScreen, format))
+		return FALSE;
+	}
+	format++;
+    }
+    return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+    int	    s;
+
+    for (s = 0; s < screenInfo.numScreens; s++)
+    {
+	if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+	    return FALSE;
+	(void) AnimCurInit (screenInfo.screens[s]);
+    }
+
+    return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return FALSE;
+    ps->subpixel = subpixel;
+    return TRUE;
+    
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return SubPixelUnknown;
+    return ps->subpixel;
+}
+    
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+    int			type;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    switch (pVisual->class) {
+    case StaticGray:
+    case GrayScale:
+    case StaticColor:
+    case PseudoColor:
+	type = PictTypeIndexed;
+	break;
+    case TrueColor:
+	type = PictTypeDirect;
+	break;
+    case DirectColor:
+    default:
+	return 0;
+    }
+    while (nformat--)
+    {
+	if (format->depth == depth && format->type == type)
+	{
+	    if (type == PictTypeIndexed)
+	    {
+		if (format->index.pVisual == pVisual)
+		    return format;
+	    }
+	    else
+	    {
+		if (format->direct.redMask << format->direct.red == 
+		    pVisual->redMask &&
+		    format->direct.greenMask << format->direct.green == 
+		    pVisual->greenMask &&
+		    format->direct.blueMask << format->direct.blue == 
+		    pVisual->blueMask)
+		{
+		    return format;
+		}
+	    }
+	}
+	format++;
+    }
+    return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->depth == depth && format->format == (f & 0xffffff))
+	    return format;
+	format++;
+    }
+    return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+    if ( strcmp (name, "default" ) == 0)
+	return PictureCmapPolicyDefault;
+    else if ( strcmp (name, "mono" ) == 0)
+	return PictureCmapPolicyMono;
+    else if ( strcmp (name, "gray" ) == 0)
+	return PictureCmapPolicyGray;
+    else if ( strcmp (name, "color" ) == 0)
+	return PictureCmapPolicyColor;
+    else if ( strcmp (name, "all" ) == 0)
+	return PictureCmapPolicyAll;
+    else
+	return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+    PictureScreenPtr	ps;
+    int			n;
+    CARD32		type, a, r, g, b;
+    
+    if (PictureGeneration != serverGeneration)
+    {
+	PictureType = CreateNewResourceType (FreePicture);
+	if (!PictureType)
+	    return FALSE;
+	PictFormatType = CreateNewResourceType (FreePictFormat);
+	if (!PictFormatType)
+	    return FALSE;
+	GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+	if (!GlyphSetType)
+	    return FALSE;
+	PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+	if (PictureScreenPrivateIndex < 0)
+	    return FALSE;
+	PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+	PictureGeneration = serverGeneration;
+#ifdef XResExtension
+	RegisterResourceName (PictureType, "PICTURE");
+	RegisterResourceName (PictFormatType, "PICTFORMAT");
+	RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+    }
+    if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+	return FALSE;
+    
+    if (!formats)
+    {
+	formats = PictureCreateDefaultFormats (pScreen, &nformats);
+	if (!formats)
+	    return FALSE;
+    }
+    for (n = 0; n < nformats; n++)
+    {
+	if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+	{
+	    xfree (formats);
+	    return FALSE;
+	}
+	if (formats[n].type == PictTypeIndexed)
+	{
+	    if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+		type = PICT_TYPE_COLOR;
+	    else
+		type = PICT_TYPE_GRAY;
+	    a = r = g = b = 0;
+	}
+	else
+	{
+	    if ((formats[n].direct.redMask|
+		 formats[n].direct.blueMask|
+		 formats[n].direct.greenMask) == 0)
+		type = PICT_TYPE_A;
+	    else if (formats[n].direct.red > formats[n].direct.blue)
+		type = PICT_TYPE_ARGB;
+	    else
+		type = PICT_TYPE_ABGR;
+	    a = Ones (formats[n].direct.alphaMask);
+	    r = Ones (formats[n].direct.redMask);
+	    g = Ones (formats[n].direct.greenMask);
+	    b = Ones (formats[n].direct.blueMask);
+	}
+	formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+    }
+    ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+    if (!ps)
+    {
+	xfree (formats);
+	return FALSE;
+    }
+    SetPictureScreen(pScreen, ps);
+    if (!GlyphInit (pScreen))
+    {
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    ps->totalPictureSize = sizeof (PictureRec);
+    ps->PicturePrivateSizes = 0;
+    ps->PicturePrivateLen = 0;
+    
+    ps->formats = formats;
+    ps->fallback = formats;
+    ps->nformats = nformats;
+    
+    ps->filters = 0;
+    ps->nfilters = 0;
+    ps->filterAliases = 0;
+    ps->nfilterAliases = 0;
+
+    ps->subpixel = SubPixelUnknown;
+
+    ps->CloseScreen = pScreen->CloseScreen;
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    pScreen->CloseScreen = PictureCloseScreen;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (!PictureSetDefaultFilters (pScreen))
+    {
+	PictureResetFilters (pScreen);
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr    pPicture)
+{
+    pPicture->refcnt = 1;
+    pPicture->repeat = 0;
+    pPicture->graphicsExposures = FALSE;
+    pPicture->subWindowMode = ClipByChildren;
+    pPicture->polyEdge = PolyEdgeSharp;
+    pPicture->polyMode = PolyModePrecise;
+    pPicture->freeCompClip = FALSE;
+    pPicture->clientClipType = CT_NONE;
+    pPicture->componentAlpha = FALSE;
+
+    pPicture->alphaMap = 0;
+    pPicture->alphaOrigin.x = 0;
+    pPicture->alphaOrigin.y = 0;
+
+    pPicture->clipOrigin.x = 0;
+    pPicture->clipOrigin.y = 0;
+    pPicture->clientClip = 0;
+
+    pPicture->transform = 0;
+
+    pPicture->dither = None;
+    pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+    pPicture->filter_params = 0;
+    pPicture->filter_nparams = 0;
+
+    pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+    pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture;
+    char		*ptr;
+    DevUnion		*ppriv;
+    unsigned int    	*sizes;
+    unsigned int    	size;
+    int			i;
+
+    pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+    if (!pPicture)
+	return 0;
+    ppriv = (DevUnion *)(pPicture + 1);
+    pPicture->devPrivates = ppriv;
+    sizes = ps->PicturePrivateSizes;
+    ptr = (char *)(ppriv + ps->PicturePrivateLen);
+    for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return pPicture;
+}
+
+/*
+ * Let picture always point to the virtual pixmap.
+ * For sure this is not the best way to deal with
+ * the virtual frame-buffer.
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		vmask,
+	       XID		*vlist,
+	       ClientPtr	client,
+	       int		*error)
+{
+    PicturePtr		pPicture;
+    PictureScreenPtr	ps = GetPictureScreen(pDrawable->pScreen);
+
+    pPicture = AllocatePicture (pDrawable->pScreen);
+    if (!pPicture)
+    {
+	*error = BadAlloc;
+	return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pDrawable = pDrawable;
+    pPicture->pFormat = pFormat;
+    pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+    if (pDrawable->type == DRAWABLE_PIXMAP)
+    {
+        #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+        pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
+
+        #endif
+
+	++((PixmapPtr)pDrawable)->refcnt;
+	pPicture->pNext = 0;
+    }
+    else
+    {
+	pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+	SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+    }
+
+    SetPictureToDefaults (pPicture);
+    
+    if (vmask)
+	*error = ChangePicture (pPicture, vmask, vlist, 0, client);
+    else
+	*error = Success;
+    if (*error == Success)
+	*error = (*ps->CreatePicture) (pPicture);
+    if (*error != Success)
+    {
+	FreePicture (pPicture, (XID) 0);
+	pPicture = 0;
+    }
+    return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    BITS32		index2;
+    int			error = 0;
+    BITS32		maskQ;
+    
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    maskQ = vmask;
+    while (vmask && !error)
+    {
+	index2 = (BITS32) lowbit (vmask);
+	vmask &= ~index2;
+	pPicture->stateChanges |= index2;
+	switch (index2)
+	{
+	case CPRepeat:
+	    {
+		unsigned int	newr;
+		newr = NEXT_VAL(unsigned int);
+		if (newr <= xTrue)
+		    pPicture->repeat = newr;
+		else
+		{
+		    client->errorValue = newr;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPAlphaMap:
+	    {
+		PicturePtr  pAlpha;
+		
+		if (vlist)
+		{
+		    Picture	pid = NEXT_VAL(Picture);
+
+		    if (pid == None)
+			pAlpha = 0;
+		    else
+		    {
+			pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+								     pid, 
+								     PictureType, 
+								     SecurityWriteAccess|SecurityReadAccess);
+			if (!pAlpha)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+			if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+			{
+			    client->errorValue = pid;
+			    error = BadMatch;
+			    break;
+			}
+		    }
+		}
+		else
+		    pAlpha = NEXT_PTR(PicturePtr);
+		if (!error)
+		{
+		    if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+			pAlpha->refcnt++;
+		    if (pPicture->alphaMap)
+			FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+		    pPicture->alphaMap = pAlpha;
+		}
+	    }
+	    break;
+	case CPAlphaXOrigin:
+	    pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPAlphaYOrigin:
+	    pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipXOrigin:
+	    pPicture->clipOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPClipYOrigin:
+	    pPicture->clipOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipMask:
+	    {
+		Pixmap	    pid;
+		PixmapPtr   pPixmap;
+		int	    clipType;
+
+		if (vlist)
+		{
+		    pid = NEXT_VAL(Pixmap);
+		    if (pid == None)
+		    {
+			clipType = CT_NONE;
+			pPixmap = NullPixmap;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+								    pid, 
+								    RT_PIXMAP,
+								    SecurityReadAccess);
+			if (!pPixmap)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+		    }
+		}
+		else
+		{
+		    pPixmap = NEXT_PTR(PixmapPtr);
+		    if (pPixmap)
+			clipType = CT_PIXMAP;
+		    else
+			clipType = CT_NONE;
+		}
+
+		if (pPixmap)
+		{
+		    if ((pPixmap->drawable.depth != 1) ||
+			(pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			break;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap->refcnt++;
+		    }
+		}
+		error = (*ps->ChangePictureClip)(pPicture, clipType,
+						 (pointer)pPixmap, 0);
+		break;
+	    }
+	case CPGraphicsExposure:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe <= xTrue)
+		    pPicture->graphicsExposures = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPSubwindowMode:
+	    {
+		unsigned int	news;
+		news = NEXT_VAL(unsigned int);
+		if (news == ClipByChildren || news == IncludeInferiors)
+		    pPicture->subWindowMode = news;
+		else
+		{
+		    client->errorValue = news;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyEdge:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+		    pPicture->polyEdge = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyMode:
+	    {
+		unsigned int	newm;
+		newm = NEXT_VAL(unsigned int);
+		if (newm == PolyModePrecise || newm == PolyModeImprecise)
+		    pPicture->polyMode = newm;
+		else
+		{
+		    client->errorValue = newm;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPDither:
+	    pPicture->dither = NEXT_VAL(Atom);
+	    break;
+	case CPComponentAlpha:
+	    {
+		unsigned int	newca;
+
+		newca = NEXT_VAL (unsigned int);
+		if (newca <= xTrue)
+		    pPicture->componentAlpha = newca;
+		else
+		{
+		    client->errorValue = newca;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	default:
+	    client->errorValue = maskQ;
+	    error = BadValue;
+	    break;
+	}
+    }
+    (*ps->ChangePicture) (pPicture, maskQ);
+    return error;
+}
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    RegionPtr		clientClip;
+    int			result;
+
+    clientClip = RECTS_TO_REGION(pScreen,
+				 nRect, rects, CT_UNSORTED);
+    if (!clientClip)
+	return BadAlloc;
+    result =(*ps->ChangePictureClip) (pPicture, CT_REGION, 
+				      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+	pPicture->clipOrigin.x = xOrigin;
+	pPicture->clipOrigin.y = yOrigin;
+	pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+	pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform)
+{
+    static const PictTransform	identity = { {
+	{ xFixed1, 0x00000, 0x00000 },
+	{ 0x00000, xFixed1, 0x00000 },
+	{ 0x00000, 0x00000, xFixed1 },
+    } };
+
+    if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+	transform = 0;
+    
+    if (transform)
+    {
+	if (!pPicture->transform)
+	{
+	    pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+	    if (!pPicture->transform)
+		return BadAlloc;
+	}
+	*pPicture->transform = *transform;
+    }
+    else
+    {
+	if (pPicture->transform)
+	{
+	    xfree (pPicture->transform);
+	    pPicture->transform = 0;
+	}
+    }
+    return Success;
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+    if (pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+    {
+	PictureScreenPtr    ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+	(*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+	pPicture->stateChanges = 0;
+	pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+    }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+    ValidateOnePicture (pPicture);
+    if (pPicture->alphaMap)
+	ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer	value,
+	     XID	pid)
+{
+    PicturePtr	pPicture = (PicturePtr) value;
+
+    if (--pPicture->refcnt == 0)
+    {
+	ScreenPtr	    pScreen = pPicture->pDrawable->pScreen;
+	PictureScreenPtr    ps = GetPictureScreen(pScreen);
+	
+	if (pPicture->alphaMap)
+	    FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+	(*ps->DestroyPicture) (pPicture);
+	(*ps->DestroyPictureClip) (pPicture);
+	if (pPicture->transform)
+	    xfree (pPicture->transform);
+	if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+	{
+	    WindowPtr	pWindow = (WindowPtr) pPicture->pDrawable;
+	    PicturePtr	*pPrev;
+
+	    for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+		 *pPrev;
+		 pPrev = &(*pPrev)->pNext)
+	    {
+		if (*pPrev == pPicture)
+		{
+		    *pPrev = pPicture->pNext;
+		    break;
+		}
+	    }
+	}
+	else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+	{
+	    (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+	}
+	xfree (pPicture);
+    }
+    return Success;
+}
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid)
+{
+    return Success;
+}
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    if (pMask)
+	ValidatePicture (pMask);
+    ValidatePicture (pDst);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+}
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+
+    #ifdef TEST
+    fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with "
+		"source at [%p] and destination at [%p].\n",
+		    (void *) pSrc, (void *) pDst);
+    #endif
+
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pDst);
+    (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+typedef xFixed_32_32	xFixed_48_16;
+
+#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] * 
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    for (j = 0; j < 2; j++)
+    {
+	partial = (xFixed_48_16) result.vector[j] << 16;
+	v = partial / result.vector[2];
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	vector->vector[j] = (xFixed) v;
+    }
+    vector->vector[2] = xFixed1;
+    return TRUE;
+}
+
+#ifndef True
+# define True 1
+#endif
+
+#ifndef False
+# define False 0
+#endif
+
+void nxagentReconnectPictFormat(void*, XID, void*);
+
+Bool nxagentReconnectAllPictFormat(void *p)
+{
+  PictFormatPtr formats_old, formats;
+  int nformats, nformats_old;
+  Bool success = True;
+  Bool matched;
+  int i, n;
+  CARD32 type, a, r, g, b;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectAllPictFormat\n");
+  #endif
+
+  formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
+  nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
+
+  /*
+   * TODO: We could copy PictureCreateDefaultFormats,
+   *       in order not to waste ID with FakeClientID().
+   */
+  formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
+
+  if (!formats)
+    return FALSE;
+
+  for (n = 0; n < nformats; n++)
+  {
+    if (formats[n].type == PictTypeIndexed)
+    {
+      if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+        type = PICT_TYPE_COLOR;
+      else
+        type = PICT_TYPE_GRAY;
+      a = r = g = b = 0;
+    }
+    else
+    {
+      if ((formats[n].direct.redMask|
+           formats[n].direct.blueMask|
+           formats[n].direct.greenMask) == 0)
+        type = PICT_TYPE_A;
+      else if (formats[n].direct.red > formats[n].direct.blue)
+        type = PICT_TYPE_ARGB;
+      else
+        type = PICT_TYPE_ABGR;
+      a = Ones (formats[n].direct.alphaMask);
+      r = Ones (formats[n].direct.redMask);
+      g = Ones (formats[n].direct.greenMask);
+      b = Ones (formats[n].direct.blueMask);
+    }
+    formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+  }
+
+  for (n = 0; n < nformats_old; n++)
+  {
+    for (i = 0, matched = False; (!matched) && (i < nformats); i++)
+    {
+      if (formats_old[n].format == formats[i].format &&
+          formats_old[n].type == formats[i].type &&
+          formats_old[n].direct.red == formats[i].direct.red &&
+          formats_old[n].direct.green == formats[i].direct.green &&
+          formats_old[n].direct.blue == formats[i].direct.blue &&
+          formats_old[n].direct.redMask == formats[i].direct.redMask &&
+          formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
+          formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
+          formats_old[n].direct.alpha == formats[i].direct.alpha &&
+          formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
+      {
+       /*
+        * Regard depth 16 and 15 as were the same, if all other values match.
+        */
+
+        if ((formats_old[n].depth == formats[i].depth) ||
+               ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
+                    (formats[i].depth == 15 || formats[i].depth == 16)))
+        {
+          matched = True;
+        }
+      }
+    }
+    if (!matched)
+      return False;
+  }
+  xfree(formats);
+
+  /* TODO: Perhaps do i have to do PictureFinishInit ?. */
+  /* TODO: We have to check for new Render protocol version. */
+
+  for (i = 0; (i < MAXCLIENTS) && (success); i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
+    }
+  }
+
+  return success;
+}
+
+/*
+ * It seem we don't have nothing
+ * to do for reconnect PictureFormat.
+ */
+
+void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
+{
+  PictFormatPtr pFormat;
+  Bool *pBool;
+
+  pFormat = (PictFormatPtr)p0;
+  pBool = (Bool*)p2;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectPictFormat.\n");
+  #endif
+}
+
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
new file mode 100644
index 000000000..64ba970c9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
@@ -0,0 +1,1512 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXpicture.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.30 2003/01/26 16:40:43 eich Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "NXpicturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
+
+int		PictureScreenPrivateIndex = -1;
+int		PictureWindowPrivateIndex;
+int		PictureGeneration;
+RESTYPE		PictureType;
+RESTYPE		PictFormatType;
+RESTYPE		GlyphSetType;
+int		PictureCmapPolicy = PictureCmapPolicyDefault;
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+    ScreenPtr		pScreen = pWindow->drawable.pScreen;
+    PicturePtr		pPicture;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool		ret;
+
+    while ((pPicture = GetPictureWindow(pWindow)))
+    {
+	SetPictureWindow(pWindow, pPicture->pNext);
+	if (pPicture->id)
+	    FreeResource (pPicture->id, PictureType);
+	FreePicture ((pointer) pPicture, pPicture->id);
+    }
+    pScreen->DestroyWindow = ps->DestroyWindow;
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool                ret;
+    int			n;
+
+    pScreen->CloseScreen = ps->CloseScreen;
+    ret = (*pScreen->CloseScreen) (index, pScreen);
+    PictureResetFilters (pScreen);
+    for (n = 0; n < ps->nformats; n++)
+	if (ps->formats[n].type == PictTypeIndexed)
+	    (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+    SetPictureScreen(pScreen, 0);
+    xfree (ps->formats);
+    xfree (ps);
+    return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+    ScreenPtr		pScreen = pColormap->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    pScreen->StoreColors = ps->StoreColors;
+    (*pScreen->StoreColors) (pColormap, ndef, pdef);
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+    {
+	PictFormatPtr	format = ps->formats;
+	int		nformats = ps->nformats;
+
+	while (nformats--)
+	{
+	    if (format->type == PictTypeIndexed &&
+		format->index.pColormap == pColormap)
+	    {
+		(*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+		break;
+	    }
+	    format++;
+	}
+    }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    int		d, v;
+    DepthPtr	pDepth;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	for (v = 0; v < pDepth->numVids; v++)
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+    }
+    return 0;
+}
+
+typedef struct _formatInit {
+    CARD32  format;
+    CARD8   depth;
+} FormatInitRec, *FormatInitPtr;
+
+static int
+addFormat (FormatInitRec    formats[256],
+	   int		    nformat,
+	   CARD32	    format,
+	   CARD8	    depth)
+{
+    int	n;
+
+    for (n = 0; n < nformat; n++)
+	if (formats[n].format == format && formats[n].depth == depth)
+	    return nformat;
+    formats[nformat].format = format;
+    formats[nformat].depth = depth;
+    return ++nformat;
+}
+
+#define Mask(n)	((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+#ifdef NXAGENT_SERVER
+    int             nformats, f, n;
+#else
+    int             nformats, f;
+#endif
+    PictFormatPtr   pFormats;
+    FormatInitRec   formats[1024];
+    CARD32	    format;
+    CARD8	    depth;
+    VisualPtr	    pVisual;
+    int		    v;
+    int		    bpp;
+    int		    type;
+    int		    r, g, b;
+    int		    d;
+    DepthPtr	    pDepth;
+
+    nformats = 0;
+    /* formats required by protocol */
+    formats[nformats].format = PICT_a1;
+    formats[nformats].depth = 1;
+    nformats++;
+    formats[nformats].format = PICT_a8;
+    formats[nformats].depth = 8;
+    nformats++;
+    formats[nformats].format = PICT_a4;
+    formats[nformats].depth = 4;
+    nformats++;
+    formats[nformats].format = PICT_a8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+    formats[nformats].format = PICT_x8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+
+    /* now look through the depths and visuals adding other formats */
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = &pScreen->visuals[v];
+	depth = visualDepth (pScreen, pVisual);
+	if (!depth)
+	    continue;
+    	bpp = BitsPerPixel (depth);
+	switch (pVisual->class) {
+	case DirectColor:
+	case TrueColor:
+	    r = Ones (pVisual->redMask);
+	    g = Ones (pVisual->greenMask);
+	    b = Ones (pVisual->blueMask);
+	    type = PICT_TYPE_OTHER;
+	    /*
+	     * Current rendering code supports only two direct formats,
+	     * fields must be packed together at the bottom of the pixel
+	     * and must be either RGB or BGR
+	     */
+	    if (pVisual->offsetBlue == 0 &&
+		pVisual->offsetGreen == b &&
+		pVisual->offsetRed == b + g)
+	    {
+		type = PICT_TYPE_ARGB;
+	    }
+	    else if (pVisual->offsetRed == 0 &&
+		     pVisual->offsetGreen == r && 
+		     pVisual->offsetBlue == r + g)
+	    {
+		type = PICT_TYPE_ABGR;
+	    }
+	    if (type != PICT_TYPE_OTHER)
+	    {
+		format = PICT_FORMAT(bpp, type, 0, r, g, b);
+		nformats = addFormat (formats, nformats, format, depth);
+	    }
+	    break;
+	case StaticColor:
+	case PseudoColor:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	case StaticGray:
+	case GrayScale:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	}
+    }
+    /*
+     * Walk supported depths and add useful Direct formats
+     */
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	bpp = BitsPerPixel (pDepth->depth);
+	format = 0;
+	switch (bpp) {
+	case 16:
+	    /* depth 12 formats */
+	    if (pDepth->depth >= 12)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x4b4g4r4, pDepth->depth);
+	    }
+	    /* depth 15 formats */
+	    if (pDepth->depth >= 15)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x1b5g5r5, pDepth->depth);
+	    }
+	    /* depth 16 formats */
+	    if (pDepth->depth >= 16) 
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_a1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a1b5g5r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_r5g6b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b5g6r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4b4g4r4, pDepth->depth);
+	    }
+	    break;
+	case 24:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b8g8r8, pDepth->depth);
+	    }
+	    break;
+	case 32:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x8r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x8b8g8r8, pDepth->depth);
+	    }
+	    break;
+	}
+    }
+    
+
+    pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+    if (!pFormats)
+	return 0;
+    memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+#ifdef NXAGENT_SERVER
+    for (f = 0, n = 0; n < nformats; n++)
+    {
+        pFormats[f].id = FakeClientID (0);
+        pFormats[f].depth = formats[n].depth;
+        format = formats[n].format;
+        pFormats[f].format = format;
+#else
+    for (f = 0; f < nformats; f++)
+    {
+        pFormats[f].id = FakeClientID (0);
+        pFormats[f].depth = formats[f].depth;
+        format = formats[f].format;
+        pFormats[f].format = format;
+#endif
+	switch (PICT_FORMAT_TYPE(format)) {
+	case PICT_TYPE_ARGB:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = (PICT_FORMAT_G(format) + 
+				      PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_B(format);
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = 0;
+	    break;
+
+	case PICT_TYPE_ABGR:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = (PICT_FORMAT_G(format) + 
+				       PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_R(format);
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = 0;
+	    break;
+
+	case PICT_TYPE_A:
+	    pFormats[f].type = PictTypeDirect;
+
+	    pFormats[f].direct.alpha = 0;
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+	    /* remaining fields already set to zero */
+	    break;
+	    
+	case PICT_TYPE_COLOR:
+	case PICT_TYPE_GRAY:
+	    pFormats[f].type = PictTypeIndexed;
+	    pFormats[f].index.pVisual = &pScreen->visuals[PICT_FORMAT_VIS(format)];
+	    break;
+	}
+
+#ifdef NXAGENT_SERVER
+        if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+        {
+          f++;
+        }
+        else
+        {
+          memset(&pFormats[f], '\0', sizeof(PictFormatRec));
+        } 
+    }
+    *nformatp = f;
+#else
+    }
+    *nformatp = nformats;
+#endif
+    return pFormats;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return FALSE;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->type == PictTypeIndexed && !format->index.pColormap)
+	{
+	    if (format->index.pVisual->vid == pScreen->rootVisual)
+		format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+								       RT_COLORMAP);
+	    else
+	    {
+		if (CreateColormap (FakeClientID (0), pScreen,
+				    format->index.pVisual,
+				    &format->index.pColormap, AllocNone,
+				    0) != Success)
+		{
+		    return FALSE;
+		}
+	    }
+	    if (!(*ps->InitIndexed) (pScreen, format))
+		return FALSE;
+	}
+	format++;
+    }
+    return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+    int	    s;
+
+    for (s = 0; s < screenInfo.numScreens; s++)
+    {
+	if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+	    return FALSE;
+	(void) AnimCurInit (screenInfo.screens[s]);
+    }
+
+    return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return FALSE;
+    ps->subpixel = subpixel;
+    return TRUE;
+    
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return SubPixelUnknown;
+    return ps->subpixel;
+}
+    
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+    int			type;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    switch (pVisual->class) {
+    case StaticGray:
+    case GrayScale:
+    case StaticColor:
+    case PseudoColor:
+	type = PictTypeIndexed;
+	break;
+    case TrueColor:
+	type = PictTypeDirect;
+	break;
+    case DirectColor:
+    default:
+	return 0;
+    }
+    while (nformat--)
+    {
+	if (format->depth == depth && format->type == type)
+	{
+	    if (type == PictTypeIndexed)
+	    {
+		if (format->index.pVisual == pVisual)
+		    return format;
+	    }
+	    else
+	    {
+		if (format->direct.redMask << format->direct.red == 
+		    pVisual->redMask &&
+		    format->direct.greenMask << format->direct.green == 
+		    pVisual->greenMask &&
+		    format->direct.blueMask << format->direct.blue == 
+		    pVisual->blueMask)
+		{
+		    return format;
+		}
+	    }
+	}
+	format++;
+    }
+    return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->depth == depth && format->format == (f & 0xffffff))
+	    return format;
+	format++;
+    }
+    return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+    if ( strcmp (name, "default" ) == 0)
+	return PictureCmapPolicyDefault;
+    else if ( strcmp (name, "mono" ) == 0)
+	return PictureCmapPolicyMono;
+    else if ( strcmp (name, "gray" ) == 0)
+	return PictureCmapPolicyGray;
+    else if ( strcmp (name, "color" ) == 0)
+	return PictureCmapPolicyColor;
+    else if ( strcmp (name, "all" ) == 0)
+	return PictureCmapPolicyAll;
+    else
+	return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+    PictureScreenPtr	ps;
+    int			n;
+    CARD32		type, a, r, g, b;
+    
+    if (PictureGeneration != serverGeneration)
+    {
+	PictureType = CreateNewResourceType (FreePicture);
+	if (!PictureType)
+	    return FALSE;
+	PictFormatType = CreateNewResourceType (FreePictFormat);
+	if (!PictFormatType)
+	    return FALSE;
+	GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+	if (!GlyphSetType)
+	    return FALSE;
+	PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+	if (PictureScreenPrivateIndex < 0)
+	    return FALSE;
+	PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+	PictureGeneration = serverGeneration;
+#ifdef XResExtension
+	RegisterResourceName (PictureType, "PICTURE");
+	RegisterResourceName (PictFormatType, "PICTFORMAT");
+	RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+    }
+    if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+	return FALSE;
+    
+    if (!formats)
+    {
+	formats = PictureCreateDefaultFormats (pScreen, &nformats);
+	if (!formats)
+	    return FALSE;
+    }
+    for (n = 0; n < nformats; n++)
+    {
+	if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+	{
+	    xfree (formats);
+	    return FALSE;
+	}
+	if (formats[n].type == PictTypeIndexed)
+	{
+	    if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+		type = PICT_TYPE_COLOR;
+	    else
+		type = PICT_TYPE_GRAY;
+	    a = r = g = b = 0;
+	}
+	else
+	{
+	    if ((formats[n].direct.redMask|
+		 formats[n].direct.blueMask|
+		 formats[n].direct.greenMask) == 0)
+		type = PICT_TYPE_A;
+	    else if (formats[n].direct.red > formats[n].direct.blue)
+		type = PICT_TYPE_ARGB;
+	    else
+		type = PICT_TYPE_ABGR;
+	    a = Ones (formats[n].direct.alphaMask);
+	    r = Ones (formats[n].direct.redMask);
+	    g = Ones (formats[n].direct.greenMask);
+	    b = Ones (formats[n].direct.blueMask);
+	}
+	formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+    }
+    ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+    if (!ps)
+    {
+	xfree (formats);
+	return FALSE;
+    }
+    SetPictureScreen(pScreen, ps);
+    if (!GlyphInit (pScreen))
+    {
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    ps->totalPictureSize = sizeof (PictureRec);
+    ps->PicturePrivateSizes = 0;
+    ps->PicturePrivateLen = 0;
+    
+    ps->formats = formats;
+    ps->fallback = formats;
+    ps->nformats = nformats;
+    
+    ps->filters = 0;
+    ps->nfilters = 0;
+    ps->filterAliases = 0;
+    ps->nfilterAliases = 0;
+
+    ps->subpixel = SubPixelUnknown;
+
+    ps->CloseScreen = pScreen->CloseScreen;
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    pScreen->CloseScreen = PictureCloseScreen;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (!PictureSetDefaultFilters (pScreen))
+    {
+	PictureResetFilters (pScreen);
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr    pPicture)
+{
+    pPicture->refcnt = 1;
+    pPicture->repeat = 0;
+    pPicture->graphicsExposures = FALSE;
+    pPicture->subWindowMode = ClipByChildren;
+    pPicture->polyEdge = PolyEdgeSharp;
+    pPicture->polyMode = PolyModePrecise;
+    pPicture->freeCompClip = FALSE;
+    pPicture->clientClipType = CT_NONE;
+    pPicture->componentAlpha = FALSE;
+
+    pPicture->alphaMap = 0;
+    pPicture->alphaOrigin.x = 0;
+    pPicture->alphaOrigin.y = 0;
+
+    pPicture->clipOrigin.x = 0;
+    pPicture->clipOrigin.y = 0;
+    pPicture->clientClip = 0;
+
+    pPicture->transform = 0;
+
+    pPicture->dither = None;
+    pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+    pPicture->filter_params = 0;
+    pPicture->filter_nparams = 0;
+
+    pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+    pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture;
+    char		*ptr;
+    DevUnion		*ppriv;
+    unsigned int    	*sizes;
+    unsigned int    	size;
+    int			i;
+
+    pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+    if (!pPicture)
+	return 0;
+    ppriv = (DevUnion *)(pPicture + 1);
+    pPicture->devPrivates = ppriv;
+    sizes = ps->PicturePrivateSizes;
+    ptr = (char *)(ppriv + ps->PicturePrivateLen);
+    for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return pPicture;
+}
+
+/*
+ * Let picture always point to the virtual pixmap.
+ * For sure this is not the best way to deal with
+ * the virtual frame-buffer.
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		vmask,
+	       XID		*vlist,
+	       ClientPtr	client,
+	       int		*error)
+{
+    PicturePtr		pPicture;
+    PictureScreenPtr	ps = GetPictureScreen(pDrawable->pScreen);
+
+    pPicture = AllocatePicture (pDrawable->pScreen);
+    if (!pPicture)
+    {
+	*error = BadAlloc;
+	return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pDrawable = pDrawable;
+    pPicture->pFormat = pFormat;
+    pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+    if (pDrawable->type == DRAWABLE_PIXMAP)
+    {
+        #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+        pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
+
+        #endif
+
+	++((PixmapPtr)pDrawable)->refcnt;
+	pPicture->pNext = 0;
+    }
+    else
+    {
+	pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+	SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+    }
+
+    SetPictureToDefaults (pPicture);
+    
+    if (vmask)
+	*error = ChangePicture (pPicture, vmask, vlist, 0, client);
+    else
+	*error = Success;
+    if (*error == Success)
+	*error = (*ps->CreatePicture) (pPicture);
+    if (*error != Success)
+    {
+	FreePicture (pPicture, (XID) 0);
+	pPicture = 0;
+    }
+    return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    BITS32		index2;
+    int			error = 0;
+    BITS32		maskQ;
+    
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    maskQ = vmask;
+    while (vmask && !error)
+    {
+	index2 = (BITS32) lowbit (vmask);
+	vmask &= ~index2;
+	pPicture->stateChanges |= index2;
+	switch (index2)
+	{
+	case CPRepeat:
+	    {
+		unsigned int	newr;
+		newr = NEXT_VAL(unsigned int);
+		if (newr <= xTrue)
+		    pPicture->repeat = newr;
+		else
+		{
+		    client->errorValue = newr;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPAlphaMap:
+	    {
+		PicturePtr  pAlpha;
+		
+		if (vlist)
+		{
+		    Picture	pid = NEXT_VAL(Picture);
+
+		    if (pid == None)
+			pAlpha = 0;
+		    else
+		    {
+			pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+								     pid, 
+								     PictureType, 
+								     SecurityWriteAccess|SecurityReadAccess);
+			if (!pAlpha)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+			if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+			{
+			    client->errorValue = pid;
+			    error = BadMatch;
+			    break;
+			}
+		    }
+		}
+		else
+		    pAlpha = NEXT_PTR(PicturePtr);
+		if (!error)
+		{
+		    if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+			pAlpha->refcnt++;
+		    if (pPicture->alphaMap)
+			FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+		    pPicture->alphaMap = pAlpha;
+		}
+	    }
+	    break;
+	case CPAlphaXOrigin:
+	    pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPAlphaYOrigin:
+	    pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipXOrigin:
+	    pPicture->clipOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPClipYOrigin:
+	    pPicture->clipOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipMask:
+	    {
+		Pixmap	    pid;
+		PixmapPtr   pPixmap;
+		int	    clipType;
+
+		if (vlist)
+		{
+		    pid = NEXT_VAL(Pixmap);
+		    if (pid == None)
+		    {
+			clipType = CT_NONE;
+			pPixmap = NullPixmap;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+								    pid, 
+								    RT_PIXMAP,
+								    SecurityReadAccess);
+			if (!pPixmap)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+		    }
+		}
+		else
+		{
+		    pPixmap = NEXT_PTR(PixmapPtr);
+		    if (pPixmap)
+			clipType = CT_PIXMAP;
+		    else
+			clipType = CT_NONE;
+		}
+
+		if (pPixmap)
+		{
+		    if ((pPixmap->drawable.depth != 1) ||
+			(pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			break;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap->refcnt++;
+		    }
+		}
+		error = (*ps->ChangePictureClip)(pPicture, clipType,
+						 (pointer)pPixmap, 0);
+		break;
+	    }
+	case CPGraphicsExposure:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe <= xTrue)
+		    pPicture->graphicsExposures = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPSubwindowMode:
+	    {
+		unsigned int	news;
+		news = NEXT_VAL(unsigned int);
+		if (news == ClipByChildren || news == IncludeInferiors)
+		    pPicture->subWindowMode = news;
+		else
+		{
+		    client->errorValue = news;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyEdge:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+		    pPicture->polyEdge = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyMode:
+	    {
+		unsigned int	newm;
+		newm = NEXT_VAL(unsigned int);
+		if (newm == PolyModePrecise || newm == PolyModeImprecise)
+		    pPicture->polyMode = newm;
+		else
+		{
+		    client->errorValue = newm;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPDither:
+	    pPicture->dither = NEXT_VAL(Atom);
+	    break;
+	case CPComponentAlpha:
+	    {
+		unsigned int	newca;
+
+		newca = NEXT_VAL (unsigned int);
+		if (newca <= xTrue)
+		    pPicture->componentAlpha = newca;
+		else
+		{
+		    client->errorValue = newca;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	default:
+	    client->errorValue = maskQ;
+	    error = BadValue;
+	    break;
+	}
+    }
+    (*ps->ChangePicture) (pPicture, maskQ);
+    return error;
+}
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    RegionPtr		clientClip;
+    int			result;
+
+    clientClip = RECTS_TO_REGION(pScreen,
+				 nRect, rects, CT_UNSORTED);
+    if (!clientClip)
+	return BadAlloc;
+    result =(*ps->ChangePictureClip) (pPicture, CT_REGION, 
+				      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+	pPicture->clipOrigin.x = xOrigin;
+	pPicture->clipOrigin.y = yOrigin;
+	pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+	pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform)
+{
+    static const PictTransform	identity = { {
+	{ xFixed1, 0x00000, 0x00000 },
+	{ 0x00000, xFixed1, 0x00000 },
+	{ 0x00000, 0x00000, xFixed1 },
+    } };
+
+    if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+	transform = 0;
+    
+    if (transform)
+    {
+	if (!pPicture->transform)
+	{
+	    pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+	    if (!pPicture->transform)
+		return BadAlloc;
+	}
+	*pPicture->transform = *transform;
+    }
+    else
+    {
+	if (pPicture->transform)
+	{
+	    xfree (pPicture->transform);
+	    pPicture->transform = 0;
+	}
+    }
+    return Success;
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+    if (pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+    {
+	PictureScreenPtr    ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+	(*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+	pPicture->stateChanges = 0;
+	pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+    }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+    ValidateOnePicture (pPicture);
+    if (pPicture->alphaMap)
+	ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer	value,
+	     XID	pid)
+{
+    PicturePtr	pPicture = (PicturePtr) value;
+
+    if (--pPicture->refcnt == 0)
+    {
+	ScreenPtr	    pScreen = pPicture->pDrawable->pScreen;
+	PictureScreenPtr    ps = GetPictureScreen(pScreen);
+	
+	if (pPicture->alphaMap)
+	    FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+	(*ps->DestroyPicture) (pPicture);
+	(*ps->DestroyPictureClip) (pPicture);
+	if (pPicture->transform)
+	    xfree (pPicture->transform);
+	if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+	{
+	    WindowPtr	pWindow = (WindowPtr) pPicture->pDrawable;
+	    PicturePtr	*pPrev;
+
+	    for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+		 *pPrev;
+		 pPrev = &(*pPrev)->pNext)
+	    {
+		if (*pPrev == pPicture)
+		{
+		    *pPrev = pPicture->pNext;
+		    break;
+		}
+	    }
+	}
+	else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+	{
+	    (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+	}
+	xfree (pPicture);
+    }
+    return Success;
+}
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid)
+{
+    return Success;
+}
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    if (pMask)
+	ValidatePicture (pMask);
+    ValidatePicture (pDst);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+}
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+
+    #ifdef TEST
+    fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with "
+		"source at [%p] and destination at [%p].\n",
+		    (void *) pSrc, (void *) pDst);
+    #endif
+
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pDst);
+    (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+typedef xFixed_32_32	xFixed_48_16;
+
+#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] * 
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    for (j = 0; j < 2; j++)
+    {
+	partial = (xFixed_48_16) result.vector[j] << 16;
+	v = partial / result.vector[2];
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	vector->vector[j] = (xFixed) v;
+    }
+    vector->vector[2] = xFixed1;
+    return TRUE;
+}
+
+#ifndef True
+# define True 1
+#endif
+
+#ifndef False
+# define False 0
+#endif
+
+void nxagentReconnectPictFormat(void*, XID, void*);
+
+Bool nxagentReconnectAllPictFormat(void *p)
+{
+  PictFormatPtr formats_old, formats;
+  int nformats, nformats_old;
+  Bool success = True;
+  Bool matched;
+  int i, n;
+  CARD32 type, a, r, g, b;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectAllPictFormat\n");
+  #endif
+
+  formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
+  nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
+
+  /*
+   * TODO: We could copy PictureCreateDefaultFormats,
+   *       in order not to waste ID with FakeClientID().
+   */
+  formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
+
+  if (!formats)
+    return FALSE;
+
+  for (n = 0; n < nformats; n++)
+  {
+    if (formats[n].type == PictTypeIndexed)
+    {
+      if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+        type = PICT_TYPE_COLOR;
+      else
+        type = PICT_TYPE_GRAY;
+      a = r = g = b = 0;
+    }
+    else
+    {
+      if ((formats[n].direct.redMask|
+           formats[n].direct.blueMask|
+           formats[n].direct.greenMask) == 0)
+        type = PICT_TYPE_A;
+      else if (formats[n].direct.red > formats[n].direct.blue)
+        type = PICT_TYPE_ARGB;
+      else
+        type = PICT_TYPE_ABGR;
+      a = Ones (formats[n].direct.alphaMask);
+      r = Ones (formats[n].direct.redMask);
+      g = Ones (formats[n].direct.greenMask);
+      b = Ones (formats[n].direct.blueMask);
+    }
+    formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+  }
+
+  for (n = 0; n < nformats_old; n++)
+  {
+    for (i = 0, matched = False; (!matched) && (i < nformats); i++)
+    {
+      if (formats_old[n].format == formats[i].format &&
+          formats_old[n].type == formats[i].type &&
+          formats_old[n].direct.red == formats[i].direct.red &&
+          formats_old[n].direct.green == formats[i].direct.green &&
+          formats_old[n].direct.blue == formats[i].direct.blue &&
+          formats_old[n].direct.redMask == formats[i].direct.redMask &&
+          formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
+          formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
+          formats_old[n].direct.alpha == formats[i].direct.alpha &&
+          formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
+      {
+       /*
+        * Regard depth 16 and 15 as were the same, if all other values match.
+        */
+
+        if ((formats_old[n].depth == formats[i].depth) ||
+               ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
+                    (formats[i].depth == 15 || formats[i].depth == 16)))
+        {
+          matched = True;
+        }
+      }
+    }
+    if (!matched)
+      return False;
+  }
+  xfree(formats);
+
+  /* TODO: Perhaps do i have to do PictureFinishInit ?. */
+  /* TODO: We have to check for new Render protocol version. */
+
+  for (i = 0; (i < MAXCLIENTS) && (success); i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
+    }
+  }
+
+  return success;
+}
+
+/*
+ * It seem we don't have nothing
+ * to do for reconnect PictureFormat.
+ */
+
+void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
+{
+  PictFormatPtr pFormat;
+  Bool *pBool;
+
+  pFormat = (PictFormatPtr)p0;
+  pBool = (Bool*)p2;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectPictFormat.\n");
+  #endif
+}
+
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.XF86.original
new file mode 100644
index 000000000..b2ef69bdf
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.XF86.original
@@ -0,0 +1,1305 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.30 2003/01/26 16:40:43 eich Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+
+int		PictureScreenPrivateIndex = -1;
+int		PictureWindowPrivateIndex;
+int		PictureGeneration;
+RESTYPE		PictureType;
+RESTYPE		PictFormatType;
+RESTYPE		GlyphSetType;
+int		PictureCmapPolicy = PictureCmapPolicyDefault;
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+    ScreenPtr		pScreen = pWindow->drawable.pScreen;
+    PicturePtr		pPicture;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool		ret;
+
+    while ((pPicture = GetPictureWindow(pWindow)))
+    {
+	SetPictureWindow(pWindow, pPicture->pNext);
+	if (pPicture->id)
+	    FreeResource (pPicture->id, PictureType);
+	FreePicture ((pointer) pPicture, pPicture->id);
+    }
+    pScreen->DestroyWindow = ps->DestroyWindow;
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool                ret;
+    int			n;
+
+    pScreen->CloseScreen = ps->CloseScreen;
+    ret = (*pScreen->CloseScreen) (index, pScreen);
+    PictureResetFilters (pScreen);
+    for (n = 0; n < ps->nformats; n++)
+	if (ps->formats[n].type == PictTypeIndexed)
+	    (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+    SetPictureScreen(pScreen, 0);
+    xfree (ps->formats);
+    xfree (ps);
+    return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+    ScreenPtr		pScreen = pColormap->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    pScreen->StoreColors = ps->StoreColors;
+    (*pScreen->StoreColors) (pColormap, ndef, pdef);
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+    {
+	PictFormatPtr	format = ps->formats;
+	int		nformats = ps->nformats;
+
+	while (nformats--)
+	{
+	    if (format->type == PictTypeIndexed &&
+		format->index.pColormap == pColormap)
+	    {
+		(*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+		break;
+	    }
+	    format++;
+	}
+    }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    int		d, v;
+    DepthPtr	pDepth;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	for (v = 0; v < pDepth->numVids; v++)
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+    }
+    return 0;
+}
+
+typedef struct _formatInit {
+    CARD32  format;
+    CARD8   depth;
+} FormatInitRec, *FormatInitPtr;
+
+static int
+addFormat (FormatInitRec    formats[256],
+	   int		    nformat,
+	   CARD32	    format,
+	   CARD8	    depth)
+{
+    int	n;
+
+    for (n = 0; n < nformat; n++)
+	if (formats[n].format == format && formats[n].depth == depth)
+	    return nformat;
+    formats[nformat].format = format;
+    formats[nformat].depth = depth;
+    return ++nformat;
+}
+
+#define Mask(n)	((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+    int		    nformats, f;
+    PictFormatPtr   pFormats;
+    FormatInitRec   formats[1024];
+    CARD32	    format;
+    CARD8	    depth;
+    VisualPtr	    pVisual;
+    int		    v;
+    int		    bpp;
+    int		    type;
+    int		    r, g, b;
+    int		    d;
+    DepthPtr	    pDepth;
+
+    nformats = 0;
+    /* formats required by protocol */
+    formats[nformats].format = PICT_a1;
+    formats[nformats].depth = 1;
+    nformats++;
+    formats[nformats].format = PICT_a8;
+    formats[nformats].depth = 8;
+    nformats++;
+    formats[nformats].format = PICT_a4;
+    formats[nformats].depth = 4;
+    nformats++;
+    formats[nformats].format = PICT_a8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+    formats[nformats].format = PICT_x8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+
+    /* now look through the depths and visuals adding other formats */
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = &pScreen->visuals[v];
+	depth = visualDepth (pScreen, pVisual);
+	if (!depth)
+	    continue;
+    	bpp = BitsPerPixel (depth);
+	switch (pVisual->class) {
+	case DirectColor:
+	case TrueColor:
+	    r = Ones (pVisual->redMask);
+	    g = Ones (pVisual->greenMask);
+	    b = Ones (pVisual->blueMask);
+	    type = PICT_TYPE_OTHER;
+	    /*
+	     * Current rendering code supports only two direct formats,
+	     * fields must be packed together at the bottom of the pixel
+	     * and must be either RGB or BGR
+	     */
+	    if (pVisual->offsetBlue == 0 &&
+		pVisual->offsetGreen == b &&
+		pVisual->offsetRed == b + g)
+	    {
+		type = PICT_TYPE_ARGB;
+	    }
+	    else if (pVisual->offsetRed == 0 &&
+		     pVisual->offsetGreen == r && 
+		     pVisual->offsetBlue == r + g)
+	    {
+		type = PICT_TYPE_ABGR;
+	    }
+	    if (type != PICT_TYPE_OTHER)
+	    {
+		format = PICT_FORMAT(bpp, type, 0, r, g, b);
+		nformats = addFormat (formats, nformats, format, depth);
+	    }
+	    break;
+	case StaticColor:
+	case PseudoColor:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	case StaticGray:
+	case GrayScale:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	}
+    }
+    /*
+     * Walk supported depths and add useful Direct formats
+     */
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	bpp = BitsPerPixel (pDepth->depth);
+	format = 0;
+	switch (bpp) {
+	case 16:
+	    /* depth 12 formats */
+	    if (pDepth->depth >= 12)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x4b4g4r4, pDepth->depth);
+	    }
+	    /* depth 15 formats */
+	    if (pDepth->depth >= 15)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x1b5g5r5, pDepth->depth);
+	    }
+	    /* depth 16 formats */
+	    if (pDepth->depth >= 16) 
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_a1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a1b5g5r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_r5g6b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b5g6r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4b4g4r4, pDepth->depth);
+	    }
+	    break;
+	case 24:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b8g8r8, pDepth->depth);
+	    }
+	    break;
+	case 32:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x8r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x8b8g8r8, pDepth->depth);
+	    }
+	    break;
+	}
+    }
+    
+
+    pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+    if (!pFormats)
+	return 0;
+    memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+    for (f = 0; f < nformats; f++)
+    {
+        pFormats[f].id = FakeClientID (0);
+	pFormats[f].depth = formats[f].depth;
+	format = formats[f].format;
+	pFormats[f].format = format;
+	switch (PICT_FORMAT_TYPE(format)) {
+	case PICT_TYPE_ARGB:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = (PICT_FORMAT_G(format) + 
+				      PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_B(format);
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = 0;
+	    break;
+
+	case PICT_TYPE_ABGR:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = (PICT_FORMAT_G(format) + 
+				       PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_R(format);
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = 0;
+	    break;
+
+	case PICT_TYPE_A:
+	    pFormats[f].type = PictTypeDirect;
+
+	    pFormats[f].direct.alpha = 0;
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+	    /* remaining fields already set to zero */
+	    break;
+	    
+	case PICT_TYPE_COLOR:
+	case PICT_TYPE_GRAY:
+	    pFormats[f].type = PictTypeIndexed;
+	    pFormats[f].index.pVisual = &pScreen->visuals[PICT_FORMAT_VIS(format)];
+	    break;
+	}
+    }
+    *nformatp = nformats;
+    return pFormats;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return FALSE;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->type == PictTypeIndexed && !format->index.pColormap)
+	{
+	    if (format->index.pVisual->vid == pScreen->rootVisual)
+		format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+								       RT_COLORMAP);
+	    else
+	    {
+		if (CreateColormap (FakeClientID (0), pScreen,
+				    format->index.pVisual,
+				    &format->index.pColormap, AllocNone,
+				    0) != Success)
+		{
+		    return FALSE;
+		}
+	    }
+	    if (!(*ps->InitIndexed) (pScreen, format))
+		return FALSE;
+	}
+	format++;
+    }
+    return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+    int	    s;
+
+    for (s = 0; s < screenInfo.numScreens; s++)
+    {
+	if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+	    return FALSE;
+	(void) AnimCurInit (screenInfo.screens[s]);
+    }
+
+    return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return FALSE;
+    ps->subpixel = subpixel;
+    return TRUE;
+    
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return SubPixelUnknown;
+    return ps->subpixel;
+}
+    
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+    int			type;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    switch (pVisual->class) {
+    case StaticGray:
+    case GrayScale:
+    case StaticColor:
+    case PseudoColor:
+	type = PictTypeIndexed;
+	break;
+    case TrueColor:
+	type = PictTypeDirect;
+	break;
+    case DirectColor:
+    default:
+	return 0;
+    }
+    while (nformat--)
+    {
+	if (format->depth == depth && format->type == type)
+	{
+	    if (type == PictTypeIndexed)
+	    {
+		if (format->index.pVisual == pVisual)
+		    return format;
+	    }
+	    else
+	    {
+		if (format->direct.redMask << format->direct.red == 
+		    pVisual->redMask &&
+		    format->direct.greenMask << format->direct.green == 
+		    pVisual->greenMask &&
+		    format->direct.blueMask << format->direct.blue == 
+		    pVisual->blueMask)
+		{
+		    return format;
+		}
+	    }
+	}
+	format++;
+    }
+    return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->depth == depth && format->format == (f & 0xffffff))
+	    return format;
+	format++;
+    }
+    return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+    if ( strcmp (name, "default" ) == 0)
+	return PictureCmapPolicyDefault;
+    else if ( strcmp (name, "mono" ) == 0)
+	return PictureCmapPolicyMono;
+    else if ( strcmp (name, "gray" ) == 0)
+	return PictureCmapPolicyGray;
+    else if ( strcmp (name, "color" ) == 0)
+	return PictureCmapPolicyColor;
+    else if ( strcmp (name, "all" ) == 0)
+	return PictureCmapPolicyAll;
+    else
+	return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+    PictureScreenPtr	ps;
+    int			n;
+    CARD32		type, a, r, g, b;
+    
+    if (PictureGeneration != serverGeneration)
+    {
+	PictureType = CreateNewResourceType (FreePicture);
+	if (!PictureType)
+	    return FALSE;
+	PictFormatType = CreateNewResourceType (FreePictFormat);
+	if (!PictFormatType)
+	    return FALSE;
+	GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+	if (!GlyphSetType)
+	    return FALSE;
+	PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+	if (PictureScreenPrivateIndex < 0)
+	    return FALSE;
+	PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+	PictureGeneration = serverGeneration;
+#ifdef XResExtension
+	RegisterResourceName (PictureType, "PICTURE");
+	RegisterResourceName (PictFormatType, "PICTFORMAT");
+	RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+    }
+    if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+	return FALSE;
+    
+    if (!formats)
+    {
+	formats = PictureCreateDefaultFormats (pScreen, &nformats);
+	if (!formats)
+	    return FALSE;
+    }
+    for (n = 0; n < nformats; n++)
+    {
+	if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+	{
+	    xfree (formats);
+	    return FALSE;
+	}
+	if (formats[n].type == PictTypeIndexed)
+	{
+	    if ((formats[n].index.pVisual->class | DynamicClass) == PseudoColor)
+		type = PICT_TYPE_COLOR;
+	    else
+		type = PICT_TYPE_GRAY;
+	    a = r = g = b = 0;
+	}
+	else
+	{
+	    if ((formats[n].direct.redMask|
+		 formats[n].direct.blueMask|
+		 formats[n].direct.greenMask) == 0)
+		type = PICT_TYPE_A;
+	    else if (formats[n].direct.red > formats[n].direct.blue)
+		type = PICT_TYPE_ARGB;
+	    else
+		type = PICT_TYPE_ABGR;
+	    a = Ones (formats[n].direct.alphaMask);
+	    r = Ones (formats[n].direct.redMask);
+	    g = Ones (formats[n].direct.greenMask);
+	    b = Ones (formats[n].direct.blueMask);
+	}
+	formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+    }
+    ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+    if (!ps)
+    {
+	xfree (formats);
+	return FALSE;
+    }
+    SetPictureScreen(pScreen, ps);
+    if (!GlyphInit (pScreen))
+    {
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    ps->totalPictureSize = sizeof (PictureRec);
+    ps->PicturePrivateSizes = 0;
+    ps->PicturePrivateLen = 0;
+    
+    ps->formats = formats;
+    ps->fallback = formats;
+    ps->nformats = nformats;
+    
+    ps->filters = 0;
+    ps->nfilters = 0;
+    ps->filterAliases = 0;
+    ps->nfilterAliases = 0;
+
+    ps->subpixel = SubPixelUnknown;
+
+    ps->CloseScreen = pScreen->CloseScreen;
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    pScreen->CloseScreen = PictureCloseScreen;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (!PictureSetDefaultFilters (pScreen))
+    {
+	PictureResetFilters (pScreen);
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr    pPicture)
+{
+    pPicture->refcnt = 1;
+    pPicture->repeat = 0;
+    pPicture->graphicsExposures = FALSE;
+    pPicture->subWindowMode = ClipByChildren;
+    pPicture->polyEdge = PolyEdgeSharp;
+    pPicture->polyMode = PolyModePrecise;
+    pPicture->freeCompClip = FALSE;
+    pPicture->clientClipType = CT_NONE;
+    pPicture->componentAlpha = FALSE;
+
+    pPicture->alphaMap = 0;
+    pPicture->alphaOrigin.x = 0;
+    pPicture->alphaOrigin.y = 0;
+
+    pPicture->clipOrigin.x = 0;
+    pPicture->clipOrigin.y = 0;
+    pPicture->clientClip = 0;
+
+    pPicture->transform = 0;
+
+    pPicture->dither = None;
+    pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+    pPicture->filter_params = 0;
+    pPicture->filter_nparams = 0;
+
+    pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+    pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture;
+    char		*ptr;
+    DevUnion		*ppriv;
+    unsigned int    	*sizes;
+    unsigned int    	size;
+    int			i;
+
+    pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+    if (!pPicture)
+	return 0;
+    ppriv = (DevUnion *)(pPicture + 1);
+    pPicture->devPrivates = ppriv;
+    sizes = ps->PicturePrivateSizes;
+    ptr = (char *)(ppriv + ps->PicturePrivateLen);
+    for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return pPicture;
+}
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		vmask,
+	       XID		*vlist,
+	       ClientPtr	client,
+	       int		*error)
+{
+    PicturePtr		pPicture;
+    PictureScreenPtr	ps = GetPictureScreen(pDrawable->pScreen);
+
+    pPicture = AllocatePicture (pDrawable->pScreen);
+    if (!pPicture)
+    {
+	*error = BadAlloc;
+	return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pDrawable = pDrawable;
+    pPicture->pFormat = pFormat;
+    pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+    if (pDrawable->type == DRAWABLE_PIXMAP)
+    {
+	++((PixmapPtr)pDrawable)->refcnt;
+	pPicture->pNext = 0;
+    }
+    else
+    {
+	pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+	SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+    }
+
+    SetPictureToDefaults (pPicture);
+    
+    if (vmask)
+	*error = ChangePicture (pPicture, vmask, vlist, 0, client);
+    else
+	*error = Success;
+    if (*error == Success)
+	*error = (*ps->CreatePicture) (pPicture);
+    if (*error != Success)
+    {
+	FreePicture (pPicture, (XID) 0);
+	pPicture = 0;
+    }
+    return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    BITS32		index2;
+    int			error = 0;
+    BITS32		maskQ;
+    
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    maskQ = vmask;
+    while (vmask && !error)
+    {
+	index2 = (BITS32) lowbit (vmask);
+	vmask &= ~index2;
+	pPicture->stateChanges |= index2;
+	switch (index2)
+	{
+	case CPRepeat:
+	    {
+		unsigned int	newr;
+		newr = NEXT_VAL(unsigned int);
+		if (newr <= xTrue)
+		    pPicture->repeat = newr;
+		else
+		{
+		    client->errorValue = newr;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPAlphaMap:
+	    {
+		PicturePtr  pAlpha;
+		
+		if (vlist)
+		{
+		    Picture	pid = NEXT_VAL(Picture);
+
+		    if (pid == None)
+			pAlpha = 0;
+		    else
+		    {
+			pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+								     pid, 
+								     PictureType, 
+								     SecurityWriteAccess|SecurityReadAccess);
+			if (!pAlpha)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+			if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+			{
+			    client->errorValue = pid;
+			    error = BadMatch;
+			    break;
+			}
+		    }
+		}
+		else
+		    pAlpha = NEXT_PTR(PicturePtr);
+		if (!error)
+		{
+		    if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+			pAlpha->refcnt++;
+		    if (pPicture->alphaMap)
+			FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+		    pPicture->alphaMap = pAlpha;
+		}
+	    }
+	    break;
+	case CPAlphaXOrigin:
+	    pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPAlphaYOrigin:
+	    pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipXOrigin:
+	    pPicture->clipOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPClipYOrigin:
+	    pPicture->clipOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipMask:
+	    {
+		Pixmap	    pid;
+		PixmapPtr   pPixmap;
+		int	    clipType;
+
+		if (vlist)
+		{
+		    pid = NEXT_VAL(Pixmap);
+		    if (pid == None)
+		    {
+			clipType = CT_NONE;
+			pPixmap = NullPixmap;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+								    pid, 
+								    RT_PIXMAP,
+								    SecurityReadAccess);
+			if (!pPixmap)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+		    }
+		}
+		else
+		{
+		    pPixmap = NEXT_PTR(PixmapPtr);
+		    if (pPixmap)
+			clipType = CT_PIXMAP;
+		    else
+			clipType = CT_NONE;
+		}
+
+		if (pPixmap)
+		{
+		    if ((pPixmap->drawable.depth != 1) ||
+			(pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			break;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap->refcnt++;
+		    }
+		}
+		error = (*ps->ChangePictureClip)(pPicture, clipType,
+						 (pointer)pPixmap, 0);
+		break;
+	    }
+	case CPGraphicsExposure:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe <= xTrue)
+		    pPicture->graphicsExposures = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPSubwindowMode:
+	    {
+		unsigned int	news;
+		news = NEXT_VAL(unsigned int);
+		if (news == ClipByChildren || news == IncludeInferiors)
+		    pPicture->subWindowMode = news;
+		else
+		{
+		    client->errorValue = news;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyEdge:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+		    pPicture->polyEdge = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyMode:
+	    {
+		unsigned int	newm;
+		newm = NEXT_VAL(unsigned int);
+		if (newm == PolyModePrecise || newm == PolyModeImprecise)
+		    pPicture->polyMode = newm;
+		else
+		{
+		    client->errorValue = newm;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPDither:
+	    pPicture->dither = NEXT_VAL(Atom);
+	    break;
+	case CPComponentAlpha:
+	    {
+		unsigned int	newca;
+
+		newca = NEXT_VAL (unsigned int);
+		if (newca <= xTrue)
+		    pPicture->componentAlpha = newca;
+		else
+		{
+		    client->errorValue = newca;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	default:
+	    client->errorValue = maskQ;
+	    error = BadValue;
+	    break;
+	}
+    }
+    (*ps->ChangePicture) (pPicture, maskQ);
+    return error;
+}
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    RegionPtr		clientClip;
+    int			result;
+
+    clientClip = RECTS_TO_REGION(pScreen,
+				 nRect, rects, CT_UNSORTED);
+    if (!clientClip)
+	return BadAlloc;
+    result =(*ps->ChangePictureClip) (pPicture, CT_REGION, 
+				      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+	pPicture->clipOrigin.x = xOrigin;
+	pPicture->clipOrigin.y = yOrigin;
+	pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+	pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform)
+{
+    static const PictTransform	identity = { {
+	{ xFixed1, 0x00000, 0x00000 },
+	{ 0x00000, xFixed1, 0x00000 },
+	{ 0x00000, 0x00000, xFixed1 },
+    } };
+
+    if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+	transform = 0;
+    
+    if (transform)
+    {
+	if (!pPicture->transform)
+	{
+	    pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+	    if (!pPicture->transform)
+		return BadAlloc;
+	}
+	*pPicture->transform = *transform;
+    }
+    else
+    {
+	if (pPicture->transform)
+	{
+	    xfree (pPicture->transform);
+	    pPicture->transform = 0;
+	}
+    }
+    return Success;
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+    if (pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+    {
+	PictureScreenPtr    ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+	(*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+	pPicture->stateChanges = 0;
+	pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+    }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+    ValidateOnePicture (pPicture);
+    if (pPicture->alphaMap)
+	ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer	value,
+	     XID	pid)
+{
+    PicturePtr	pPicture = (PicturePtr) value;
+
+    if (--pPicture->refcnt == 0)
+    {
+	ScreenPtr	    pScreen = pPicture->pDrawable->pScreen;
+	PictureScreenPtr    ps = GetPictureScreen(pScreen);
+	
+	if (pPicture->alphaMap)
+	    FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+	(*ps->DestroyPicture) (pPicture);
+	(*ps->DestroyPictureClip) (pPicture);
+	if (pPicture->transform)
+	    xfree (pPicture->transform);
+	if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+	{
+	    WindowPtr	pWindow = (WindowPtr) pPicture->pDrawable;
+	    PicturePtr	*pPrev;
+
+	    for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+		 *pPrev;
+		 pPrev = &(*pPrev)->pNext)
+	    {
+		if (*pPrev == pPicture)
+		{
+		    *pPrev = pPicture->pNext;
+		    break;
+		}
+	    }
+	}
+	else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+	{
+	    (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+	}
+	xfree (pPicture);
+    }
+    return Success;
+}
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid)
+{
+    return Success;
+}
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    if (pMask)
+	ValidatePicture (pMask);
+    ValidatePicture (pDst);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+}
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pDst);
+    (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+typedef xFixed_32_32	xFixed_48_16;
+
+#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] * 
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    for (j = 0; j < 2; j++)
+    {
+	partial = (xFixed_48_16) result.vector[j] << 16;
+	v = partial / result.vector[2];
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	vector->vector[j] = (xFixed) v;
+    }
+    vector->vector[2] = xFixed1;
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
new file mode 100644
index 000000000..a1790c3f0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
@@ -0,0 +1,533 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXpicturestr.h"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picturestr.h,v 1.22 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original
+ * picturestr.h or symbols  will be redefined. We
+ * should define a new types and cast when appro-
+ * priate.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "NXglyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+    CARD16	    red, redMask;
+    CARD16	    green, greenMask;
+    CARD16	    blue, blueMask;
+    CARD16	    alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+    VisualPtr	    pVisual;
+    ColormapPtr	    pColormap;
+    int		    nvalues;
+    xIndexValue	    *pValues;
+    void	    *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+    CARD32	    id;
+    CARD32	    format;	    /* except bpp */
+    unsigned char   type;
+    unsigned char   depth;
+    DirectFormatRec direct;
+    IndexFormatRec  index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+    xFixed	    vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+    xFixed	    matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+typedef struct _Picture {
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    CARD32	    format;	    /* PICT_FORMAT */
+    int		    refcnt;
+    CARD32	    id;
+    PicturePtr	    pNext;	    /* chain on same drawable */
+    
+    unsigned int    repeat : 1;
+    unsigned int    graphicsExposures : 1;
+    unsigned int    subWindowMode : 1;
+    unsigned int    polyEdge : 1;
+    unsigned int    polyMode : 1;
+    unsigned int    freeCompClip : 1;
+    unsigned int    clientClipType : 2;
+    unsigned int    componentAlpha : 1;
+    unsigned int    unused : 23;
+
+    PicturePtr	    alphaMap;
+    DDXPointRec	    alphaOrigin;
+
+    DDXPointRec	    clipOrigin;
+    pointer	    clientClip;
+
+    Atom	    dither;
+
+    unsigned long   stateChanges;
+    unsigned long   serialNumber;
+
+    RegionPtr	    pCompositeClip;
+    
+    DevUnion	    *devPrivates;
+    
+    PictTransform   *transform;
+
+    int		    filter;
+    xFixed	    *filter_params;
+    int		    filter_nparams;
+} PictureRec;
+
+typedef struct {
+    char	    *name;
+    xFixed	    *params;
+    int		    nparams;
+    int		    id;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest	0
+#define PictFilterBilinear	1
+
+#define PictFilterFast		2
+#define PictFilterGood		3
+#define PictFilterBest		4
+
+typedef struct {
+    char	    *alias;
+    int		    alias_id;
+    int		    filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int	(*CreatePictureProcPtr)	    (PicturePtr pPicture);
+typedef void	(*DestroyPictureProcPtr)    (PicturePtr pPicture);
+typedef int	(*ChangePictureClipProcPtr) (PicturePtr	pPicture,
+					     int	clipType,
+					     pointer    value,
+					     int	n);
+typedef void	(*DestroyPictureClipProcPtr)(PicturePtr	pPicture);
+    
+typedef int	(*ChangePictureTransformProcPtr)    (PicturePtr	    pPicture,
+						     PictTransform  *transform);
+
+typedef int	(*ChangePictureFilterProcPtr)	(PicturePtr	pPicture,
+						 int		filter,
+						 xFixed		*params,
+						 int		nparams);
+
+typedef void	(*DestroyPictureFilterProcPtr)	(PicturePtr pPicture);
+
+typedef void	(*ChangePictureProcPtr)	    (PicturePtr pPicture,
+					     Mask	mask);
+typedef void	(*ValidatePictureProcPtr)    (PicturePtr pPicture,
+					     Mask       mask);
+typedef void	(*CompositeProcPtr)	    (CARD8	op,
+					     PicturePtr pSrc,
+					     PicturePtr pMask,
+					     PicturePtr pDst,
+					     INT16	xSrc,
+					     INT16	ySrc,
+					     INT16	xMask,
+					     INT16	yMask,
+					     INT16	xDst,
+					     INT16	yDst,
+					     CARD16	width,
+					     CARD16	height);
+
+typedef void	(*GlyphsProcPtr)	    (CARD8      op,
+					     PicturePtr pSrc,
+					     PicturePtr pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16      xSrc,
+					     INT16      ySrc,
+					     int	nlists,
+					     GlyphListPtr   lists,
+					     GlyphPtr	*glyphs);
+
+typedef void	(*CompositeRectsProcPtr)    (CARD8	    op,
+					     PicturePtr	    pDst,
+					     xRenderColor   *color,
+					     int	    nRect,
+					     xRectangle	    *rects);
+
+typedef void	(*RasterizeTrapezoidProcPtr)(PicturePtr	    pMask,
+					     xTrapezoid	    *trap,
+					     int	    x_off,
+					     int	    y_off);
+
+typedef void	(*TrapezoidsProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntrap,
+					     xTrapezoid	    *traps);
+
+typedef void	(*TrianglesProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef void	(*TriStripProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef void	(*TriFanProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef Bool	(*InitIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*CloseIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*UpdateIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat,
+					     int	    ndef,
+					     xColorItem	    *pdef);
+
+typedef struct _PictureScreen {
+    int				totalPictureSize;
+    unsigned int		*PicturePrivateSizes;
+    int				PicturePrivateLen;
+
+    PictFormatPtr		formats;
+    PictFormatPtr		fallback;
+    int				nformats;
+    
+    CreatePictureProcPtr	CreatePicture;
+    DestroyPictureProcPtr	DestroyPicture;
+    ChangePictureClipProcPtr	ChangePictureClip;
+    DestroyPictureClipProcPtr	DestroyPictureClip;
+    
+    ChangePictureProcPtr	ChangePicture;
+    ValidatePictureProcPtr	ValidatePicture;
+
+    CompositeProcPtr		Composite;
+    GlyphsProcPtr		Glyphs;
+    CompositeRectsProcPtr	CompositeRects;
+
+    DestroyWindowProcPtr	DestroyWindow;
+    CloseScreenProcPtr		CloseScreen;
+
+    StoreColorsProcPtr		StoreColors;
+
+    InitIndexedProcPtr		InitIndexed;
+    CloseIndexedProcPtr		CloseIndexed;
+    UpdateIndexedProcPtr	UpdateIndexed;
+
+    int				subpixel;
+    
+    PictFilterPtr		filters;
+    int				nfilters;
+    PictFilterAliasPtr		filterAliases;
+    int				nfilterAliases;
+
+    ChangePictureTransformProcPtr   ChangePictureTransform;
+    ChangePictureFilterProcPtr	ChangePictureFilter;
+    DestroyPictureFilterProcPtr	DestroyPictureFilter;
+    
+    TrapezoidsProcPtr		Trapezoids;
+    TrianglesProcPtr		Triangles;
+    TriStripProcPtr		TriStrip;
+    TriFanProcPtr		TriFan;
+
+    RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int		PictureScreenPrivateIndex;
+extern int		PictureWindowPrivateIndex;
+extern RESTYPE		PictureType;
+extern RESTYPE		PictFormatType;
+extern RESTYPE		GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+    
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr pScreen, char *filter, xFixed *params, int nparams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+    
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+    
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		mask,
+	       XID		*list,
+	       ClientPtr	client,
+	       int		*error);
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client);
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects);
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform);
+		     
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer	pPicture,
+	     XID	pid);
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid);
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height);
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs);
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects);
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps);
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles);
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points);
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
new file mode 100644
index 000000000..a1790c3f0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
@@ -0,0 +1,533 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXpicturestr.h"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picturestr.h,v 1.22 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original
+ * picturestr.h or symbols  will be redefined. We
+ * should define a new types and cast when appro-
+ * priate.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "NXglyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+    CARD16	    red, redMask;
+    CARD16	    green, greenMask;
+    CARD16	    blue, blueMask;
+    CARD16	    alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+    VisualPtr	    pVisual;
+    ColormapPtr	    pColormap;
+    int		    nvalues;
+    xIndexValue	    *pValues;
+    void	    *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+    CARD32	    id;
+    CARD32	    format;	    /* except bpp */
+    unsigned char   type;
+    unsigned char   depth;
+    DirectFormatRec direct;
+    IndexFormatRec  index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+    xFixed	    vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+    xFixed	    matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+typedef struct _Picture {
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    CARD32	    format;	    /* PICT_FORMAT */
+    int		    refcnt;
+    CARD32	    id;
+    PicturePtr	    pNext;	    /* chain on same drawable */
+    
+    unsigned int    repeat : 1;
+    unsigned int    graphicsExposures : 1;
+    unsigned int    subWindowMode : 1;
+    unsigned int    polyEdge : 1;
+    unsigned int    polyMode : 1;
+    unsigned int    freeCompClip : 1;
+    unsigned int    clientClipType : 2;
+    unsigned int    componentAlpha : 1;
+    unsigned int    unused : 23;
+
+    PicturePtr	    alphaMap;
+    DDXPointRec	    alphaOrigin;
+
+    DDXPointRec	    clipOrigin;
+    pointer	    clientClip;
+
+    Atom	    dither;
+
+    unsigned long   stateChanges;
+    unsigned long   serialNumber;
+
+    RegionPtr	    pCompositeClip;
+    
+    DevUnion	    *devPrivates;
+    
+    PictTransform   *transform;
+
+    int		    filter;
+    xFixed	    *filter_params;
+    int		    filter_nparams;
+} PictureRec;
+
+typedef struct {
+    char	    *name;
+    xFixed	    *params;
+    int		    nparams;
+    int		    id;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest	0
+#define PictFilterBilinear	1
+
+#define PictFilterFast		2
+#define PictFilterGood		3
+#define PictFilterBest		4
+
+typedef struct {
+    char	    *alias;
+    int		    alias_id;
+    int		    filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int	(*CreatePictureProcPtr)	    (PicturePtr pPicture);
+typedef void	(*DestroyPictureProcPtr)    (PicturePtr pPicture);
+typedef int	(*ChangePictureClipProcPtr) (PicturePtr	pPicture,
+					     int	clipType,
+					     pointer    value,
+					     int	n);
+typedef void	(*DestroyPictureClipProcPtr)(PicturePtr	pPicture);
+    
+typedef int	(*ChangePictureTransformProcPtr)    (PicturePtr	    pPicture,
+						     PictTransform  *transform);
+
+typedef int	(*ChangePictureFilterProcPtr)	(PicturePtr	pPicture,
+						 int		filter,
+						 xFixed		*params,
+						 int		nparams);
+
+typedef void	(*DestroyPictureFilterProcPtr)	(PicturePtr pPicture);
+
+typedef void	(*ChangePictureProcPtr)	    (PicturePtr pPicture,
+					     Mask	mask);
+typedef void	(*ValidatePictureProcPtr)    (PicturePtr pPicture,
+					     Mask       mask);
+typedef void	(*CompositeProcPtr)	    (CARD8	op,
+					     PicturePtr pSrc,
+					     PicturePtr pMask,
+					     PicturePtr pDst,
+					     INT16	xSrc,
+					     INT16	ySrc,
+					     INT16	xMask,
+					     INT16	yMask,
+					     INT16	xDst,
+					     INT16	yDst,
+					     CARD16	width,
+					     CARD16	height);
+
+typedef void	(*GlyphsProcPtr)	    (CARD8      op,
+					     PicturePtr pSrc,
+					     PicturePtr pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16      xSrc,
+					     INT16      ySrc,
+					     int	nlists,
+					     GlyphListPtr   lists,
+					     GlyphPtr	*glyphs);
+
+typedef void	(*CompositeRectsProcPtr)    (CARD8	    op,
+					     PicturePtr	    pDst,
+					     xRenderColor   *color,
+					     int	    nRect,
+					     xRectangle	    *rects);
+
+typedef void	(*RasterizeTrapezoidProcPtr)(PicturePtr	    pMask,
+					     xTrapezoid	    *trap,
+					     int	    x_off,
+					     int	    y_off);
+
+typedef void	(*TrapezoidsProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntrap,
+					     xTrapezoid	    *traps);
+
+typedef void	(*TrianglesProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef void	(*TriStripProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef void	(*TriFanProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef Bool	(*InitIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*CloseIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*UpdateIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat,
+					     int	    ndef,
+					     xColorItem	    *pdef);
+
+typedef struct _PictureScreen {
+    int				totalPictureSize;
+    unsigned int		*PicturePrivateSizes;
+    int				PicturePrivateLen;
+
+    PictFormatPtr		formats;
+    PictFormatPtr		fallback;
+    int				nformats;
+    
+    CreatePictureProcPtr	CreatePicture;
+    DestroyPictureProcPtr	DestroyPicture;
+    ChangePictureClipProcPtr	ChangePictureClip;
+    DestroyPictureClipProcPtr	DestroyPictureClip;
+    
+    ChangePictureProcPtr	ChangePicture;
+    ValidatePictureProcPtr	ValidatePicture;
+
+    CompositeProcPtr		Composite;
+    GlyphsProcPtr		Glyphs;
+    CompositeRectsProcPtr	CompositeRects;
+
+    DestroyWindowProcPtr	DestroyWindow;
+    CloseScreenProcPtr		CloseScreen;
+
+    StoreColorsProcPtr		StoreColors;
+
+    InitIndexedProcPtr		InitIndexed;
+    CloseIndexedProcPtr		CloseIndexed;
+    UpdateIndexedProcPtr	UpdateIndexed;
+
+    int				subpixel;
+    
+    PictFilterPtr		filters;
+    int				nfilters;
+    PictFilterAliasPtr		filterAliases;
+    int				nfilterAliases;
+
+    ChangePictureTransformProcPtr   ChangePictureTransform;
+    ChangePictureFilterProcPtr	ChangePictureFilter;
+    DestroyPictureFilterProcPtr	DestroyPictureFilter;
+    
+    TrapezoidsProcPtr		Trapezoids;
+    TrianglesProcPtr		Triangles;
+    TriStripProcPtr		TriStrip;
+    TriFanProcPtr		TriFan;
+
+    RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int		PictureScreenPrivateIndex;
+extern int		PictureWindowPrivateIndex;
+extern RESTYPE		PictureType;
+extern RESTYPE		PictFormatType;
+extern RESTYPE		GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+    
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr pScreen, char *filter, xFixed *params, int nparams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+    
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+    
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		mask,
+	       XID		*list,
+	       ClientPtr	client,
+	       int		*error);
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client);
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects);
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform);
+		     
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer	pPicture,
+	     XID	pid);
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid);
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height);
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs);
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects);
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps);
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles);
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points);
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.XF86.original
new file mode 100644
index 000000000..cb5ea0ac9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.XF86.original
@@ -0,0 +1,501 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/picturestr.h,v 1.22 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "glyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+    CARD16	    red, redMask;
+    CARD16	    green, greenMask;
+    CARD16	    blue, blueMask;
+    CARD16	    alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+    VisualPtr	    pVisual;
+    ColormapPtr	    pColormap;
+    int		    nvalues;
+    xIndexValue	    *pValues;
+    void	    *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+    CARD32	    id;
+    CARD32	    format;	    /* except bpp */
+    unsigned char   type;
+    unsigned char   depth;
+    DirectFormatRec direct;
+    IndexFormatRec  index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+    xFixed	    vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+    xFixed	    matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+typedef struct _Picture {
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    CARD32	    format;	    /* PICT_FORMAT */
+    int		    refcnt;
+    CARD32	    id;
+    PicturePtr	    pNext;	    /* chain on same drawable */
+    
+    unsigned int    repeat : 1;
+    unsigned int    graphicsExposures : 1;
+    unsigned int    subWindowMode : 1;
+    unsigned int    polyEdge : 1;
+    unsigned int    polyMode : 1;
+    unsigned int    freeCompClip : 1;
+    unsigned int    clientClipType : 2;
+    unsigned int    componentAlpha : 1;
+    unsigned int    unused : 23;
+
+    PicturePtr	    alphaMap;
+    DDXPointRec	    alphaOrigin;
+
+    DDXPointRec	    clipOrigin;
+    pointer	    clientClip;
+
+    Atom	    dither;
+
+    unsigned long   stateChanges;
+    unsigned long   serialNumber;
+
+    RegionPtr	    pCompositeClip;
+    
+    DevUnion	    *devPrivates;
+    
+    PictTransform   *transform;
+
+    int		    filter;
+    xFixed	    *filter_params;
+    int		    filter_nparams;
+} PictureRec;
+
+typedef struct {
+    char	    *name;
+    xFixed	    *params;
+    int		    nparams;
+    int		    id;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest	0
+#define PictFilterBilinear	1
+
+#define PictFilterFast		2
+#define PictFilterGood		3
+#define PictFilterBest		4
+
+typedef struct {
+    char	    *alias;
+    int		    alias_id;
+    int		    filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int	(*CreatePictureProcPtr)	    (PicturePtr pPicture);
+typedef void	(*DestroyPictureProcPtr)    (PicturePtr pPicture);
+typedef int	(*ChangePictureClipProcPtr) (PicturePtr	pPicture,
+					     int	clipType,
+					     pointer    value,
+					     int	n);
+typedef void	(*DestroyPictureClipProcPtr)(PicturePtr	pPicture);
+    
+typedef int	(*ChangePictureTransformProcPtr)    (PicturePtr	    pPicture,
+						     PictTransform  *transform);
+
+typedef int	(*ChangePictureFilterProcPtr)	(PicturePtr	pPicture,
+						 int		filter,
+						 xFixed		*params,
+						 int		nparams);
+
+typedef void	(*DestroyPictureFilterProcPtr)	(PicturePtr pPicture);
+
+typedef void	(*ChangePictureProcPtr)	    (PicturePtr pPicture,
+					     Mask	mask);
+typedef void	(*ValidatePictureProcPtr)    (PicturePtr pPicture,
+					     Mask       mask);
+typedef void	(*CompositeProcPtr)	    (CARD8	op,
+					     PicturePtr pSrc,
+					     PicturePtr pMask,
+					     PicturePtr pDst,
+					     INT16	xSrc,
+					     INT16	ySrc,
+					     INT16	xMask,
+					     INT16	yMask,
+					     INT16	xDst,
+					     INT16	yDst,
+					     CARD16	width,
+					     CARD16	height);
+
+typedef void	(*GlyphsProcPtr)	    (CARD8      op,
+					     PicturePtr pSrc,
+					     PicturePtr pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16      xSrc,
+					     INT16      ySrc,
+					     int	nlists,
+					     GlyphListPtr   lists,
+					     GlyphPtr	*glyphs);
+
+typedef void	(*CompositeRectsProcPtr)    (CARD8	    op,
+					     PicturePtr	    pDst,
+					     xRenderColor   *color,
+					     int	    nRect,
+					     xRectangle	    *rects);
+
+typedef void	(*RasterizeTrapezoidProcPtr)(PicturePtr	    pMask,
+					     xTrapezoid	    *trap,
+					     int	    x_off,
+					     int	    y_off);
+
+typedef void	(*TrapezoidsProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntrap,
+					     xTrapezoid	    *traps);
+
+typedef void	(*TrianglesProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef void	(*TriStripProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef void	(*TriFanProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef Bool	(*InitIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*CloseIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*UpdateIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat,
+					     int	    ndef,
+					     xColorItem	    *pdef);
+
+typedef struct _PictureScreen {
+    int				totalPictureSize;
+    unsigned int		*PicturePrivateSizes;
+    int				PicturePrivateLen;
+
+    PictFormatPtr		formats;
+    PictFormatPtr		fallback;
+    int				nformats;
+    
+    CreatePictureProcPtr	CreatePicture;
+    DestroyPictureProcPtr	DestroyPicture;
+    ChangePictureClipProcPtr	ChangePictureClip;
+    DestroyPictureClipProcPtr	DestroyPictureClip;
+    
+    ChangePictureProcPtr	ChangePicture;
+    ValidatePictureProcPtr	ValidatePicture;
+
+    CompositeProcPtr		Composite;
+    GlyphsProcPtr		Glyphs;
+    CompositeRectsProcPtr	CompositeRects;
+
+    DestroyWindowProcPtr	DestroyWindow;
+    CloseScreenProcPtr		CloseScreen;
+
+    StoreColorsProcPtr		StoreColors;
+
+    InitIndexedProcPtr		InitIndexed;
+    CloseIndexedProcPtr		CloseIndexed;
+    UpdateIndexedProcPtr	UpdateIndexed;
+
+    int				subpixel;
+    
+    PictFilterPtr		filters;
+    int				nfilters;
+    PictFilterAliasPtr		filterAliases;
+    int				nfilterAliases;
+
+    ChangePictureTransformProcPtr   ChangePictureTransform;
+    ChangePictureFilterProcPtr	ChangePictureFilter;
+    DestroyPictureFilterProcPtr	DestroyPictureFilter;
+    
+    TrapezoidsProcPtr		Trapezoids;
+    TrianglesProcPtr		Triangles;
+    TriStripProcPtr		TriStrip;
+    TriFanProcPtr		TriFan;
+
+    RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int		PictureScreenPrivateIndex;
+extern int		PictureWindowPrivateIndex;
+extern RESTYPE		PictureType;
+extern RESTYPE		PictFormatType;
+extern RESTYPE		GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+    
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr pScreen, char *filter, xFixed *params, int nparams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+    
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+    
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		mask,
+	       XID		*list,
+	       ClientPtr	client,
+	       int		*error);
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client);
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects);
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform);
+		     
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer	pPicture,
+	     XID	pid);
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid);
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height);
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs);
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects);
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps);
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles);
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points);
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
new file mode 100644
index 000000000..f5cf91607
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
@@ -0,0 +1,921 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXproperty.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+
+#if defined(LBX) || defined(LBX_COMPAT)
+int fWriteToClient(client, len, buf)
+    ClientPtr   client;
+    int         len;
+    char        *buf;
+{
+    return WriteToClient(client, len, buf);
+}
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ *    ChangeProperty, DeleteProperty, GetProperties,
+ *    ListProperties
+ *
+ *   Properties below to windows.  A allocate slots each time
+ *   a property is added.  No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(pWin)
+    WindowPtr pWin;
+{
+    PropertyPtr pProp;
+    register int j;
+
+    pProp = pWin->userProps;
+    while (pProp)
+    {
+        ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
+        ErrorF("property format: %d\n", pProp->format);
+        ErrorF("property data: \n");
+        for (j=0; j<(pProp->format/8)*pProp->size; j++)
+           ErrorF("%c\n", pProp->data[j]);
+        pProp = pProp->next;
+    }
+}
+#endif
+
+int
+ProcRotateProperties(client)
+    ClientPtr client;
+{
+    int     i, j, delta;
+    REQUEST(xRotatePropertiesReq);
+    WindowPtr pWin;
+    register    Atom * atoms;
+    PropertyPtr * props;               /* array of pointer */
+    PropertyPtr pProp;
+    xEvent event;
+
+    REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+    UpdateCurrentTime();
+    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!stuff->nAtoms)
+	return(Success);
+    atoms = (Atom *) & stuff[1];
+    props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+    if (!props)
+	return(BadAlloc);
+    for (i = 0; i < stuff->nAtoms; i++)
+    {
+#ifdef XCSECURITY
+	char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+				SecurityReadAccess|SecurityWriteAccess);
+#endif
+        if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+	    || (SecurityErrorOperation == action)
+#endif
+	   )
+        {
+            DEALLOCATE_LOCAL(props);
+	    client->errorValue = atoms[i];
+            return BadAtom;
+        }
+#ifdef XCSECURITY
+	if (SecurityIgnoreOperation == action)
+        {
+            DEALLOCATE_LOCAL(props);
+	    return Success;
+	}
+#endif
+        for (j = i + 1; j < stuff->nAtoms; j++)
+            if (atoms[j] == atoms[i])
+            {
+                DEALLOCATE_LOCAL(props);
+                return BadMatch;
+            }
+        pProp = wUserProps (pWin);
+        while (pProp)
+        {
+            if (pProp->propertyName == atoms[i])
+                goto found;
+	    pProp = pProp->next;
+        }
+        DEALLOCATE_LOCAL(props);
+        return BadMatch;
+found: 
+        props[i] = pProp;
+    }
+    delta = stuff->nPositions;
+
+    /* If the rotation is a complete 360 degrees, then moving the properties
+	around and generating PropertyNotify events should be skipped. */
+
+    if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
+    {
+	while (delta < 0)                  /* faster if abs value is small */
+            delta += stuff->nAtoms;
+    	for (i = 0; i < stuff->nAtoms; i++)
+ 	{
+	    /* Generate a PropertyNotify event for each property whose value
+		is changed in the order in which they appear in the request. */
+ 
+ 	    event.u.u.type = PropertyNotify;
+            event.u.property.window = pWin->drawable.id;
+    	    event.u.property.state = PropertyNewValue;
+	    event.u.property.atom = props[i]->propertyName;	
+	    event.u.property.time = currentTime.milliseconds;
+	    DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	
+            props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+	}
+    }
+    DEALLOCATE_LOCAL(props);
+    return Success;
+}
+
+int 
+ProcChangeProperty(client)
+    ClientPtr client;
+{	      
+    WindowPtr pWin;
+    char format, mode;
+    unsigned long len;
+    int sizeInBytes;
+    int totalSize;
+    int err;
+    REQUEST(xChangePropertyReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+    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(xChangePropertyReq, totalSize);
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+       extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
+
+       pWin = nxagentGetClipboardWindow(stuff->property, NULL);
+    }
+
+    if (pWin == NULL)
+#endif
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+	return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return(BadAtom);
+    }
+    if (!ValidAtom(stuff->type))
+    {
+	client->errorValue = stuff->type;
+	return(BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					SecurityWriteAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+#ifdef NXAGENT_ARTSD
+    {
+    /* Do not process MCOPGLOBALS property changes,
+      they are already set reflecting the server side settings.
+      Just return success.
+    */
+      extern Atom mcop_local_atom;
+      if (stuff->property == mcop_local_atom)
+        return client->noClientException;
+    }
+#endif
+
+#ifdef LBX
+    err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+	 (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+    err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+			       (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+    if (err != Success)
+	return err;
+    else
+    {
+      if (nxagentOption(Rootless) == 1)
+      {
+        nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
+                                  (int) mode, len, (pointer) &stuff[1]);
+      }
+
+      nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
+
+      nxagentGuessShadowHint(client, stuff->property);
+
+      return client->noClientException;
+    }
+}
+
+int
+ChangeWindowProperty(pWin, property, type, format, mode, len, value, sendevent)
+    WindowPtr	pWin;
+    Atom	property, type;
+    int		format, mode;
+    unsigned long len;
+    pointer	value;
+    Bool	sendevent;
+{
+#ifdef LBX
+    return LbxChangeWindowProperty(NULL, pWin, property, type,
+				   format, mode, len, TRUE, value,
+				   sendevent, NULL);
+#else
+    PropertyPtr pProp;
+    xEvent event;
+    int sizeInBytes;
+    int totalSize;
+    pointer data;
+
+    sizeInBytes = format>>3;
+    totalSize = len * sizeInBytes;
+
+    /* first see if property already exists */
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	pProp = pProp->next;
+    }
+    if (!pProp)   /* just add to list */
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return(BadAlloc);
+        pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+	if (!pProp)
+	    return(BadAlloc);
+        data = (pointer)xalloc(totalSize);
+	if (!data && len)
+	{
+	    xfree(pProp);
+	    return(BadAlloc);
+	}
+        pProp->propertyName = property;
+        pProp->type = type;
+        pProp->format = format;
+        pProp->data = data;
+	if (len)
+	    memmove((char *)data, (char *)value, totalSize);
+	pProp->size = len;
+        pProp->next = pWin->optional->userProps;
+        pWin->optional->userProps = pProp;
+    }
+    else
+    {
+	/* 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 != pProp->format) && (mode != PropModeReplace))
+	    return(BadMatch);
+        if ((pProp->type != type) && (mode != PropModeReplace))
+            return(BadMatch);
+        if (mode == PropModeReplace)
+        {
+	    if (totalSize != pProp->size * (pProp->format >> 3))
+	    {
+	    	data = (pointer)xrealloc(pProp->data, totalSize);
+	    	if (!data && len)
+		    return(BadAlloc);
+            	pProp->data = data;
+	    }
+	    if (len)
+		memmove((char *)pProp->data, (char *)value, totalSize);
+	    pProp->size = len;
+    	    pProp->type = type;
+	    pProp->format = format;
+	}
+	else if (len == 0)
+	{
+	    /* do nothing */
+	}
+        else if (mode == PropModeAppend)
+        {
+	    data = (pointer)xrealloc(pProp->data,
+				     sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+            pProp->data = data;
+	    memmove(&((char *)data)[pProp->size * sizeInBytes], 
+		    (char *)value,
+		  totalSize);
+            pProp->size += len;
+	}
+        else if (mode == PropModePrepend)
+        {
+            data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+	    memmove(&((char *)data)[totalSize], (char *)pProp->data, 
+		  (int)(pProp->size * sizeInBytes));
+            memmove((char *)data, (char *)value, totalSize);
+	    xfree(pProp->data);
+            pProp->data = data;
+            pProp->size += len;
+	}
+    }
+    if (sendevent)
+    {
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyNewValue;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+    return(Success);
+#endif
+}
+
+int
+DeleteProperty(pWin, propName)
+    WindowPtr pWin;
+    Atom propName;
+{
+    PropertyPtr pProp, prevProp;
+    xEvent event;
+
+    if (!(pProp = wUserProps (pWin)))
+	return(Success);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == propName)
+	    break;
+        prevProp = pProp;
+	pProp = pProp->next;
+    }
+    if (pProp) 
+    {		    
+        if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
+        {
+            if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+        }
+	else
+        {
+            prevProp->next = pProp->next;
+        }
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+        event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	xfree(pProp->data);
+        xfree(pProp);
+    }
+    return(Success);
+}
+
+void
+DeleteAllWindowProperties(pWin)
+    WindowPtr pWin;
+{
+    PropertyPtr pProp, pNextProp;
+    xEvent event;
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	pNextProp = pProp->next;
+        xfree(pProp->data);
+        xfree(pProp);
+	pProp = pNextProp;
+    }
+}
+
+static int
+NullPropertyReply(client, propertyType, format, reply)
+    ClientPtr client;
+    ATOM propertyType;
+    int format;
+    xGetPropertyReply *reply;
+{
+    reply->nItems = 0;
+    reply->length = 0;
+    reply->bytesAfter = 0;
+    reply->propertyType = propertyType;
+    reply->format = format;
+    WriteReplyToClient(client, sizeof(xGenericReply), reply);
+    return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ *    If type Any is specified, returns the property from the specified
+ *    window regardless of its type.  If a type is specified, returns the
+ *    property only if its type equals the specified type.
+ *    If delete is True and a property is returned, the property is also
+ *    deleted from the window and a PropertyNotify event is generated on the
+ *    window.
+ *****************/
+
+int
+ProcGetProperty(client)
+    ClientPtr client;
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+    WindowPtr pWin;
+    xGetPropertyReply reply;
+    REQUEST(xGetPropertyReq);
+
+    REQUEST_SIZE_MATCH(xGetPropertyReq);
+    if (stuff->delete)
+	UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    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);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == stuff->property) 
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    if (!pProp) 
+	return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+    {
+	Mask access_mode = SecurityReadAccess;
+
+	if (stuff->delete)
+	    access_mode |= SecurityDestroyAccess;
+	switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					   access_mode))
+	{
+	    case SecurityErrorOperation:
+		client->errorValue = stuff->property;
+		return BadAtom;;
+	    case SecurityIgnoreOperation:
+		return NullPropertyReply(client, pProp->type, pProp->format,
+					 &reply);
+	}
+    }
+#endif
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((stuff->type != pProp->type) &&
+	 (stuff->type != AnyPropertyType))
+       )
+    {
+	reply.bytesAfter = pProp->size;
+	reply.format = pProp->format;
+	reply.length = 0;
+	reply.nItems = 0;
+	reply.propertyType = pProp->type;
+	WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+	return(Success);
+    }
+#ifdef LBX
+    /* make sure we have the current value */                       
+    if (pProp->tag_id && pProp->owner_pid) {
+	LbxStallPropRequest(client, pProp);
+	return client->noClientException;
+    }                                              
+#endif
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->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);
+
+    reply.bytesAfter = n - (ind + len);
+    reply.format = pProp->format;
+    reply.length = (len + 3) >> 2;
+    reply.nItems = len / (pProp->format / 8 );
+    reply.propertyType = pProp->type;
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+    if (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,
+				 (char *)pProp->data + ind);
+    }
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(client->noClientException);
+}
+
+#ifdef NXAGENT_CLIPBOARD
+/* GetWindowProperty clipboard use only */
+int
+GetWindowProperty(pWin, property, longOffset, longLength, delete,
+            type, actualType, format, nItems, bytesAfter, propData )
+    WindowPtr	        pWin;
+    Atom		property;
+    long			longOffset;
+    long			longLength;
+    Bool			delete;
+    Atom		type;
+    Atom		*actualType;
+    int			*format;
+    unsigned long	*nItems;
+    unsigned long	*bytesAfter;
+    unsigned char	**propData;
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+
+    if (!pWin)
+	return BadWindow;
+
+
+    if (!ValidAtom(property))
+    {
+	return(BadAtom);
+    }
+    if ((type != AnyPropertyType) && !ValidAtom(type))
+    {
+	return(BadAtom);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+
+    if (!pProp)
+	return (BadAtom);
+
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((type != pProp->type) &&
+	 (type != AnyPropertyType))
+       )
+    {
+	*bytesAfter = pProp->size;
+	*format = pProp->format;
+	*nItems = 0;
+	*actualType = pProp->type;
+	return(Success);
+    }
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+    ind = longOffset << 2;
+
+   /* If longOffset is invalid such that it causes "len" to
+	    be negative, it's a value error. */
+
+    if (n < ind)
+    {
+	return BadValue;
+    }
+
+    len = min(n - ind, 4 * longLength);
+
+    *bytesAfter = n - (ind + len);
+    *format = pProp->format;
+    *nItems = len / (pProp->format / 8 );
+    *actualType = pProp->type;
+
+    if (delete && (*bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    if (len)
+    {
+	 *propData = (unsigned char *)(pProp->data) + ind;
+    }
+
+    if (delete && (*bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(Success);
+}
+#endif
+
+int
+ProcListProperties(client)
+    ClientPtr client;
+{
+    Atom *pAtoms = NULL, *temppAtoms;
+    xListPropertiesReply xlpr;
+    int	numProps = 0;
+    WindowPtr pWin;
+    PropertyPtr pProp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {        
+        pProp = pProp->next;
+	numProps++;
+    }
+    if (numProps)
+        if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+            return(BadAlloc);
+
+    xlpr.type = X_Reply;
+    xlpr.nProperties = numProps;
+    xlpr.length = (numProps * sizeof(Atom)) >> 2;
+    xlpr.sequenceNumber = client->sequence;
+    pProp = wUserProps (pWin);
+    temppAtoms = pAtoms;
+    while (pProp)
+    {
+	*temppAtoms++ = pProp->propertyName;
+	pProp = pProp->next;
+    }
+    WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+    if (numProps)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+        DEALLOCATE_LOCAL(pAtoms);
+    }
+    return(client->noClientException);
+}
+
+int 
+ProcDeleteProperty(client)
+    register ClientPtr client;
+{
+    WindowPtr pWin;
+    REQUEST(xDeletePropertyReq);
+    int result;
+              
+    REQUEST_SIZE_MATCH(xDeletePropertyReq);
+    UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return (BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+				       SecurityDestroyAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+    result = DeleteProperty(pWin, stuff->property);
+    if (client->noClientException != Success)
+	return(client->noClientException);
+    else
+	return(result);
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
new file mode 100644
index 000000000..f5cf91607
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
@@ -0,0 +1,921 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXproperty.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+
+#if defined(LBX) || defined(LBX_COMPAT)
+int fWriteToClient(client, len, buf)
+    ClientPtr   client;
+    int         len;
+    char        *buf;
+{
+    return WriteToClient(client, len, buf);
+}
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ *    ChangeProperty, DeleteProperty, GetProperties,
+ *    ListProperties
+ *
+ *   Properties below to windows.  A allocate slots each time
+ *   a property is added.  No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(pWin)
+    WindowPtr pWin;
+{
+    PropertyPtr pProp;
+    register int j;
+
+    pProp = pWin->userProps;
+    while (pProp)
+    {
+        ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
+        ErrorF("property format: %d\n", pProp->format);
+        ErrorF("property data: \n");
+        for (j=0; j<(pProp->format/8)*pProp->size; j++)
+           ErrorF("%c\n", pProp->data[j]);
+        pProp = pProp->next;
+    }
+}
+#endif
+
+int
+ProcRotateProperties(client)
+    ClientPtr client;
+{
+    int     i, j, delta;
+    REQUEST(xRotatePropertiesReq);
+    WindowPtr pWin;
+    register    Atom * atoms;
+    PropertyPtr * props;               /* array of pointer */
+    PropertyPtr pProp;
+    xEvent event;
+
+    REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+    UpdateCurrentTime();
+    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!stuff->nAtoms)
+	return(Success);
+    atoms = (Atom *) & stuff[1];
+    props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+    if (!props)
+	return(BadAlloc);
+    for (i = 0; i < stuff->nAtoms; i++)
+    {
+#ifdef XCSECURITY
+	char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+				SecurityReadAccess|SecurityWriteAccess);
+#endif
+        if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+	    || (SecurityErrorOperation == action)
+#endif
+	   )
+        {
+            DEALLOCATE_LOCAL(props);
+	    client->errorValue = atoms[i];
+            return BadAtom;
+        }
+#ifdef XCSECURITY
+	if (SecurityIgnoreOperation == action)
+        {
+            DEALLOCATE_LOCAL(props);
+	    return Success;
+	}
+#endif
+        for (j = i + 1; j < stuff->nAtoms; j++)
+            if (atoms[j] == atoms[i])
+            {
+                DEALLOCATE_LOCAL(props);
+                return BadMatch;
+            }
+        pProp = wUserProps (pWin);
+        while (pProp)
+        {
+            if (pProp->propertyName == atoms[i])
+                goto found;
+	    pProp = pProp->next;
+        }
+        DEALLOCATE_LOCAL(props);
+        return BadMatch;
+found: 
+        props[i] = pProp;
+    }
+    delta = stuff->nPositions;
+
+    /* If the rotation is a complete 360 degrees, then moving the properties
+	around and generating PropertyNotify events should be skipped. */
+
+    if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
+    {
+	while (delta < 0)                  /* faster if abs value is small */
+            delta += stuff->nAtoms;
+    	for (i = 0; i < stuff->nAtoms; i++)
+ 	{
+	    /* Generate a PropertyNotify event for each property whose value
+		is changed in the order in which they appear in the request. */
+ 
+ 	    event.u.u.type = PropertyNotify;
+            event.u.property.window = pWin->drawable.id;
+    	    event.u.property.state = PropertyNewValue;
+	    event.u.property.atom = props[i]->propertyName;	
+	    event.u.property.time = currentTime.milliseconds;
+	    DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	
+            props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+	}
+    }
+    DEALLOCATE_LOCAL(props);
+    return Success;
+}
+
+int 
+ProcChangeProperty(client)
+    ClientPtr client;
+{	      
+    WindowPtr pWin;
+    char format, mode;
+    unsigned long len;
+    int sizeInBytes;
+    int totalSize;
+    int err;
+    REQUEST(xChangePropertyReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+    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(xChangePropertyReq, totalSize);
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+       extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
+
+       pWin = nxagentGetClipboardWindow(stuff->property, NULL);
+    }
+
+    if (pWin == NULL)
+#endif
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+	return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return(BadAtom);
+    }
+    if (!ValidAtom(stuff->type))
+    {
+	client->errorValue = stuff->type;
+	return(BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					SecurityWriteAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+#ifdef NXAGENT_ARTSD
+    {
+    /* Do not process MCOPGLOBALS property changes,
+      they are already set reflecting the server side settings.
+      Just return success.
+    */
+      extern Atom mcop_local_atom;
+      if (stuff->property == mcop_local_atom)
+        return client->noClientException;
+    }
+#endif
+
+#ifdef LBX
+    err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+	 (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+    err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+			       (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+    if (err != Success)
+	return err;
+    else
+    {
+      if (nxagentOption(Rootless) == 1)
+      {
+        nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
+                                  (int) mode, len, (pointer) &stuff[1]);
+      }
+
+      nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
+
+      nxagentGuessShadowHint(client, stuff->property);
+
+      return client->noClientException;
+    }
+}
+
+int
+ChangeWindowProperty(pWin, property, type, format, mode, len, value, sendevent)
+    WindowPtr	pWin;
+    Atom	property, type;
+    int		format, mode;
+    unsigned long len;
+    pointer	value;
+    Bool	sendevent;
+{
+#ifdef LBX
+    return LbxChangeWindowProperty(NULL, pWin, property, type,
+				   format, mode, len, TRUE, value,
+				   sendevent, NULL);
+#else
+    PropertyPtr pProp;
+    xEvent event;
+    int sizeInBytes;
+    int totalSize;
+    pointer data;
+
+    sizeInBytes = format>>3;
+    totalSize = len * sizeInBytes;
+
+    /* first see if property already exists */
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	pProp = pProp->next;
+    }
+    if (!pProp)   /* just add to list */
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return(BadAlloc);
+        pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+	if (!pProp)
+	    return(BadAlloc);
+        data = (pointer)xalloc(totalSize);
+	if (!data && len)
+	{
+	    xfree(pProp);
+	    return(BadAlloc);
+	}
+        pProp->propertyName = property;
+        pProp->type = type;
+        pProp->format = format;
+        pProp->data = data;
+	if (len)
+	    memmove((char *)data, (char *)value, totalSize);
+	pProp->size = len;
+        pProp->next = pWin->optional->userProps;
+        pWin->optional->userProps = pProp;
+    }
+    else
+    {
+	/* 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 != pProp->format) && (mode != PropModeReplace))
+	    return(BadMatch);
+        if ((pProp->type != type) && (mode != PropModeReplace))
+            return(BadMatch);
+        if (mode == PropModeReplace)
+        {
+	    if (totalSize != pProp->size * (pProp->format >> 3))
+	    {
+	    	data = (pointer)xrealloc(pProp->data, totalSize);
+	    	if (!data && len)
+		    return(BadAlloc);
+            	pProp->data = data;
+	    }
+	    if (len)
+		memmove((char *)pProp->data, (char *)value, totalSize);
+	    pProp->size = len;
+    	    pProp->type = type;
+	    pProp->format = format;
+	}
+	else if (len == 0)
+	{
+	    /* do nothing */
+	}
+        else if (mode == PropModeAppend)
+        {
+	    data = (pointer)xrealloc(pProp->data,
+				     sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+            pProp->data = data;
+	    memmove(&((char *)data)[pProp->size * sizeInBytes], 
+		    (char *)value,
+		  totalSize);
+            pProp->size += len;
+	}
+        else if (mode == PropModePrepend)
+        {
+            data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+	    memmove(&((char *)data)[totalSize], (char *)pProp->data, 
+		  (int)(pProp->size * sizeInBytes));
+            memmove((char *)data, (char *)value, totalSize);
+	    xfree(pProp->data);
+            pProp->data = data;
+            pProp->size += len;
+	}
+    }
+    if (sendevent)
+    {
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyNewValue;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+    return(Success);
+#endif
+}
+
+int
+DeleteProperty(pWin, propName)
+    WindowPtr pWin;
+    Atom propName;
+{
+    PropertyPtr pProp, prevProp;
+    xEvent event;
+
+    if (!(pProp = wUserProps (pWin)))
+	return(Success);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == propName)
+	    break;
+        prevProp = pProp;
+	pProp = pProp->next;
+    }
+    if (pProp) 
+    {		    
+        if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
+        {
+            if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+        }
+	else
+        {
+            prevProp->next = pProp->next;
+        }
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+        event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	xfree(pProp->data);
+        xfree(pProp);
+    }
+    return(Success);
+}
+
+void
+DeleteAllWindowProperties(pWin)
+    WindowPtr pWin;
+{
+    PropertyPtr pProp, pNextProp;
+    xEvent event;
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	pNextProp = pProp->next;
+        xfree(pProp->data);
+        xfree(pProp);
+	pProp = pNextProp;
+    }
+}
+
+static int
+NullPropertyReply(client, propertyType, format, reply)
+    ClientPtr client;
+    ATOM propertyType;
+    int format;
+    xGetPropertyReply *reply;
+{
+    reply->nItems = 0;
+    reply->length = 0;
+    reply->bytesAfter = 0;
+    reply->propertyType = propertyType;
+    reply->format = format;
+    WriteReplyToClient(client, sizeof(xGenericReply), reply);
+    return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ *    If type Any is specified, returns the property from the specified
+ *    window regardless of its type.  If a type is specified, returns the
+ *    property only if its type equals the specified type.
+ *    If delete is True and a property is returned, the property is also
+ *    deleted from the window and a PropertyNotify event is generated on the
+ *    window.
+ *****************/
+
+int
+ProcGetProperty(client)
+    ClientPtr client;
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+    WindowPtr pWin;
+    xGetPropertyReply reply;
+    REQUEST(xGetPropertyReq);
+
+    REQUEST_SIZE_MATCH(xGetPropertyReq);
+    if (stuff->delete)
+	UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    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);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == stuff->property) 
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    if (!pProp) 
+	return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+    {
+	Mask access_mode = SecurityReadAccess;
+
+	if (stuff->delete)
+	    access_mode |= SecurityDestroyAccess;
+	switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					   access_mode))
+	{
+	    case SecurityErrorOperation:
+		client->errorValue = stuff->property;
+		return BadAtom;;
+	    case SecurityIgnoreOperation:
+		return NullPropertyReply(client, pProp->type, pProp->format,
+					 &reply);
+	}
+    }
+#endif
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((stuff->type != pProp->type) &&
+	 (stuff->type != AnyPropertyType))
+       )
+    {
+	reply.bytesAfter = pProp->size;
+	reply.format = pProp->format;
+	reply.length = 0;
+	reply.nItems = 0;
+	reply.propertyType = pProp->type;
+	WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+	return(Success);
+    }
+#ifdef LBX
+    /* make sure we have the current value */                       
+    if (pProp->tag_id && pProp->owner_pid) {
+	LbxStallPropRequest(client, pProp);
+	return client->noClientException;
+    }                                              
+#endif
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->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);
+
+    reply.bytesAfter = n - (ind + len);
+    reply.format = pProp->format;
+    reply.length = (len + 3) >> 2;
+    reply.nItems = len / (pProp->format / 8 );
+    reply.propertyType = pProp->type;
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+    if (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,
+				 (char *)pProp->data + ind);
+    }
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(client->noClientException);
+}
+
+#ifdef NXAGENT_CLIPBOARD
+/* GetWindowProperty clipboard use only */
+int
+GetWindowProperty(pWin, property, longOffset, longLength, delete,
+            type, actualType, format, nItems, bytesAfter, propData )
+    WindowPtr	        pWin;
+    Atom		property;
+    long			longOffset;
+    long			longLength;
+    Bool			delete;
+    Atom		type;
+    Atom		*actualType;
+    int			*format;
+    unsigned long	*nItems;
+    unsigned long	*bytesAfter;
+    unsigned char	**propData;
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+
+    if (!pWin)
+	return BadWindow;
+
+
+    if (!ValidAtom(property))
+    {
+	return(BadAtom);
+    }
+    if ((type != AnyPropertyType) && !ValidAtom(type))
+    {
+	return(BadAtom);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+
+    if (!pProp)
+	return (BadAtom);
+
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((type != pProp->type) &&
+	 (type != AnyPropertyType))
+       )
+    {
+	*bytesAfter = pProp->size;
+	*format = pProp->format;
+	*nItems = 0;
+	*actualType = pProp->type;
+	return(Success);
+    }
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+    ind = longOffset << 2;
+
+   /* If longOffset is invalid such that it causes "len" to
+	    be negative, it's a value error. */
+
+    if (n < ind)
+    {
+	return BadValue;
+    }
+
+    len = min(n - ind, 4 * longLength);
+
+    *bytesAfter = n - (ind + len);
+    *format = pProp->format;
+    *nItems = len / (pProp->format / 8 );
+    *actualType = pProp->type;
+
+    if (delete && (*bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    if (len)
+    {
+	 *propData = (unsigned char *)(pProp->data) + ind;
+    }
+
+    if (delete && (*bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(Success);
+}
+#endif
+
+int
+ProcListProperties(client)
+    ClientPtr client;
+{
+    Atom *pAtoms = NULL, *temppAtoms;
+    xListPropertiesReply xlpr;
+    int	numProps = 0;
+    WindowPtr pWin;
+    PropertyPtr pProp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {        
+        pProp = pProp->next;
+	numProps++;
+    }
+    if (numProps)
+        if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+            return(BadAlloc);
+
+    xlpr.type = X_Reply;
+    xlpr.nProperties = numProps;
+    xlpr.length = (numProps * sizeof(Atom)) >> 2;
+    xlpr.sequenceNumber = client->sequence;
+    pProp = wUserProps (pWin);
+    temppAtoms = pAtoms;
+    while (pProp)
+    {
+	*temppAtoms++ = pProp->propertyName;
+	pProp = pProp->next;
+    }
+    WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+    if (numProps)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+        DEALLOCATE_LOCAL(pAtoms);
+    }
+    return(client->noClientException);
+}
+
+int 
+ProcDeleteProperty(client)
+    register ClientPtr client;
+{
+    WindowPtr pWin;
+    REQUEST(xDeletePropertyReq);
+    int result;
+              
+    REQUEST_SIZE_MATCH(xDeletePropertyReq);
+    UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return (BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+				       SecurityDestroyAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+    result = DeleteProperty(pWin, stuff->property);
+    if (client->noClientException != Success)
+	return(client->noClientException);
+    else
+	return(result);
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.XF86.original
new file mode 100644
index 000000000..ba12faffe
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.XF86.original
@@ -0,0 +1,736 @@
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#include "X.h"
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#if defined(LBX) || defined(LBX_COMPAT)
+int fWriteToClient(ClientPtr client, int len, char *buf)
+{
+    return WriteToClient(client, len, buf);
+}
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ *    ChangeProperty, DeleteProperty, GetProperties,
+ *    ListProperties
+ *
+ *   Properties below to windows.  A allocate slots each time
+ *   a property is added.  No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(pWin)
+    WindowPtr pWin;
+{
+    PropertyPtr pProp;
+    register int j;
+
+    pProp = pWin->userProps;
+    while (pProp)
+    {
+        ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
+        ErrorF("property format: %d\n", pProp->format);
+        ErrorF("property data: \n");
+        for (j=0; j<(pProp->format/8)*pProp->size; j++)
+           ErrorF("%c\n", pProp->data[j]);
+        pProp = pProp->next;
+    }
+}
+#endif
+
+int
+ProcRotateProperties(client)
+    ClientPtr client;
+{
+    int     i, j, delta;
+    REQUEST(xRotatePropertiesReq);
+    WindowPtr pWin;
+    register    Atom * atoms;
+    PropertyPtr * props;               /* array of pointer */
+    PropertyPtr pProp;
+    xEvent event;
+
+    REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+    UpdateCurrentTime();
+    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!stuff->nAtoms)
+	return(Success);
+    atoms = (Atom *) & stuff[1];
+    props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+    if (!props)
+	return(BadAlloc);
+    for (i = 0; i < stuff->nAtoms; i++)
+    {
+#ifdef XCSECURITY
+	char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+				SecurityReadAccess|SecurityWriteAccess);
+#endif
+        if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+	    || (SecurityErrorOperation == action)
+#endif
+	   )
+        {
+            DEALLOCATE_LOCAL(props);
+	    client->errorValue = atoms[i];
+            return BadAtom;
+        }
+#ifdef XCSECURITY
+	if (SecurityIgnoreOperation == action)
+        {
+            DEALLOCATE_LOCAL(props);
+	    return Success;
+	}
+#endif
+        for (j = i + 1; j < stuff->nAtoms; j++)
+            if (atoms[j] == atoms[i])
+            {
+                DEALLOCATE_LOCAL(props);
+                return BadMatch;
+            }
+        pProp = wUserProps (pWin);
+        while (pProp)
+        {
+            if (pProp->propertyName == atoms[i])
+                goto found;
+	    pProp = pProp->next;
+        }
+        DEALLOCATE_LOCAL(props);
+        return BadMatch;
+found: 
+        props[i] = pProp;
+    }
+    delta = stuff->nPositions;
+
+    /* If the rotation is a complete 360 degrees, then moving the properties
+	around and generating PropertyNotify events should be skipped. */
+
+    if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
+    {
+	while (delta < 0)                  /* faster if abs value is small */
+            delta += stuff->nAtoms;
+    	for (i = 0; i < stuff->nAtoms; i++)
+ 	{
+	    /* Generate a PropertyNotify event for each property whose value
+		is changed in the order in which they appear in the request. */
+ 
+ 	    event.u.u.type = PropertyNotify;
+            event.u.property.window = pWin->drawable.id;
+    	    event.u.property.state = PropertyNewValue;
+	    event.u.property.atom = props[i]->propertyName;	
+	    event.u.property.time = currentTime.milliseconds;
+	    DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	
+            props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+	}
+    }
+    DEALLOCATE_LOCAL(props);
+    return Success;
+}
+
+int 
+ProcChangeProperty(client)
+    ClientPtr client;
+{	      
+    WindowPtr pWin;
+    char format, mode;
+    unsigned long len;
+    int sizeInBytes;
+    int totalSize;
+    int err;
+    REQUEST(xChangePropertyReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+    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(xChangePropertyReq, totalSize);
+
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+	return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return(BadAtom);
+    }
+    if (!ValidAtom(stuff->type))
+    {
+	client->errorValue = stuff->type;
+	return(BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					SecurityWriteAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+#ifdef LBX
+    err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+	 (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+    err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+			       (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+    if (err != Success)
+	return err;
+    else
+	return client->noClientException;
+}
+
+int
+ChangeWindowProperty(pWin, property, type, format, mode, len, value, sendevent)
+    WindowPtr	pWin;
+    Atom	property, type;
+    int		format, mode;
+    unsigned long len;
+    pointer	value;
+    Bool	sendevent;
+{
+#ifdef LBX
+    return LbxChangeWindowProperty(NULL, pWin, property, type,
+				   format, mode, len, TRUE, value,
+				   sendevent, NULL);
+#else
+    PropertyPtr pProp;
+    xEvent event;
+    int sizeInBytes;
+    int totalSize;
+    pointer data;
+
+    sizeInBytes = format>>3;
+    totalSize = len * sizeInBytes;
+
+    /* first see if property already exists */
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	pProp = pProp->next;
+    }
+    if (!pProp)   /* just add to list */
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return(BadAlloc);
+        pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+	if (!pProp)
+	    return(BadAlloc);
+        data = (pointer)xalloc(totalSize);
+	if (!data && len)
+	{
+	    xfree(pProp);
+	    return(BadAlloc);
+	}
+        pProp->propertyName = property;
+        pProp->type = type;
+        pProp->format = format;
+        pProp->data = data;
+	if (len)
+	    memmove((char *)data, (char *)value, totalSize);
+	pProp->size = len;
+        pProp->next = pWin->optional->userProps;
+        pWin->optional->userProps = pProp;
+    }
+    else
+    {
+	/* 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 != pProp->format) && (mode != PropModeReplace))
+	    return(BadMatch);
+        if ((pProp->type != type) && (mode != PropModeReplace))
+            return(BadMatch);
+        if (mode == PropModeReplace)
+        {
+	    if (totalSize != pProp->size * (pProp->format >> 3))
+	    {
+	    	data = (pointer)xrealloc(pProp->data, totalSize);
+	    	if (!data && len)
+		    return(BadAlloc);
+            	pProp->data = data;
+	    }
+	    if (len)
+		memmove((char *)pProp->data, (char *)value, totalSize);
+	    pProp->size = len;
+    	    pProp->type = type;
+	    pProp->format = format;
+	}
+	else if (len == 0)
+	{
+	    /* do nothing */
+	}
+        else if (mode == PropModeAppend)
+        {
+	    data = (pointer)xrealloc(pProp->data,
+				     sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+            pProp->data = data;
+	    memmove(&((char *)data)[pProp->size * sizeInBytes], 
+		    (char *)value,
+		  totalSize);
+            pProp->size += len;
+	}
+        else if (mode == PropModePrepend)
+        {
+            data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+	    memmove(&((char *)data)[totalSize], (char *)pProp->data, 
+		  (int)(pProp->size * sizeInBytes));
+            memmove((char *)data, (char *)value, totalSize);
+	    xfree(pProp->data);
+            pProp->data = data;
+            pProp->size += len;
+	}
+    }
+    if (sendevent)
+    {
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyNewValue;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+    return(Success);
+#endif
+}
+
+int
+DeleteProperty(pWin, propName)
+    WindowPtr pWin;
+    Atom propName;
+{
+    PropertyPtr pProp, prevProp;
+    xEvent event;
+
+    if (!(pProp = wUserProps (pWin)))
+	return(Success);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == propName)
+	    break;
+        prevProp = pProp;
+	pProp = pProp->next;
+    }
+    if (pProp) 
+    {		    
+        if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
+        {
+            if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+        }
+	else
+        {
+            prevProp->next = pProp->next;
+        }
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+        event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	xfree(pProp->data);
+        xfree(pProp);
+    }
+    return(Success);
+}
+
+void
+DeleteAllWindowProperties(pWin)
+    WindowPtr pWin;
+{
+    PropertyPtr pProp, pNextProp;
+    xEvent event;
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	pNextProp = pProp->next;
+        xfree(pProp->data);
+        xfree(pProp);
+	pProp = pNextProp;
+    }
+}
+
+static int
+NullPropertyReply(client, propertyType, format, reply)
+    ClientPtr client;
+    ATOM propertyType;
+    int format;
+    xGetPropertyReply *reply;
+{
+    reply->nItems = 0;
+    reply->length = 0;
+    reply->bytesAfter = 0;
+    reply->propertyType = propertyType;
+    reply->format = format;
+    WriteReplyToClient(client, sizeof(xGenericReply), reply);
+    return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ *    If type Any is specified, returns the property from the specified
+ *    window regardless of its type.  If a type is specified, returns the
+ *    property only if its type equals the specified type.
+ *    If delete is True and a property is returned, the property is also
+ *    deleted from the window and a PropertyNotify event is generated on the
+ *    window.
+ *****************/
+
+int
+ProcGetProperty(client)
+    ClientPtr client;
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+    WindowPtr pWin;
+    xGetPropertyReply reply;
+    REQUEST(xGetPropertyReq);
+
+    REQUEST_SIZE_MATCH(xGetPropertyReq);
+    if (stuff->delete)
+	UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    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);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == stuff->property) 
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    if (!pProp) 
+	return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+    {
+	Mask access_mode = SecurityReadAccess;
+
+	if (stuff->delete)
+	    access_mode |= SecurityDestroyAccess;
+	switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					   access_mode))
+	{
+	    case SecurityErrorOperation:
+		client->errorValue = stuff->property;
+		return BadAtom;;
+	    case SecurityIgnoreOperation:
+		return NullPropertyReply(client, pProp->type, pProp->format,
+					 &reply);
+	}
+    }
+#endif
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((stuff->type != pProp->type) &&
+	 (stuff->type != AnyPropertyType))
+       )
+    {
+	reply.bytesAfter = pProp->size;
+	reply.format = pProp->format;
+	reply.length = 0;
+	reply.nItems = 0;
+	reply.propertyType = pProp->type;
+	WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+	return(Success);
+    }
+#ifdef LBX
+    /* make sure we have the current value */                       
+    if (pProp->tag_id && pProp->owner_pid) {
+	LbxStallPropRequest(client, pProp);
+	return client->noClientException;
+    }                                              
+#endif
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->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);
+
+    reply.bytesAfter = n - (ind + len);
+    reply.format = pProp->format;
+    reply.length = (len + 3) >> 2;
+    reply.nItems = len / (pProp->format / 8 );
+    reply.propertyType = pProp->type;
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+    if (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,
+				 (char *)pProp->data + ind);
+    }
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcListProperties(client)
+    ClientPtr client;
+{
+    Atom *pAtoms = NULL, *temppAtoms;
+    xListPropertiesReply xlpr;
+    int	numProps = 0;
+    WindowPtr pWin;
+    PropertyPtr pProp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {        
+        pProp = pProp->next;
+	numProps++;
+    }
+    if (numProps)
+        if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+            return(BadAlloc);
+
+    xlpr.type = X_Reply;
+    xlpr.nProperties = numProps;
+    xlpr.length = (numProps * sizeof(Atom)) >> 2;
+    xlpr.sequenceNumber = client->sequence;
+    pProp = wUserProps (pWin);
+    temppAtoms = pAtoms;
+    while (pProp)
+    {
+	*temppAtoms++ = pProp->propertyName;
+	pProp = pProp->next;
+    }
+    WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+    if (numProps)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+        DEALLOCATE_LOCAL(pAtoms);
+    }
+    return(client->noClientException);
+}
+
+int 
+ProcDeleteProperty(client)
+    register ClientPtr client;
+{
+    WindowPtr pWin;
+    REQUEST(xDeletePropertyReq);
+    int result;
+              
+    REQUEST_SIZE_MATCH(xDeletePropertyReq);
+    UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return (BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+				       SecurityDestroyAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+    result = DeleteProperty(pWin, stuff->property);
+    if (client->noClientException != Success)
+	return(client->noClientException);
+    else
+	return(result);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
new file mode 100644
index 000000000..6f53dcdad
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
@@ -0,0 +1,1229 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXrandr.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
new file mode 100644
index 000000000..6f53dcdad
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
@@ -0,0 +1,1229 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXrandr.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original
new file mode 100644
index 000000000..666605e96
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original
@@ -0,0 +1,1197 @@
+/*
+ * $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/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
new file mode 100644
index 000000000..20aca4619
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
@@ -0,0 +1,3048 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXrender.c"
+
+#else
+
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.26 2003/02/14 18:15:21 dawes Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include "render.h"
+#include "renderproto.h"
+#include "Xfuncproto.h"
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * From NXmiglyph.c.
+ */
+
+void miGlyphExtents(int nlist, GlyphListPtr list,
+                        GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * Functions from Render.c.
+ */
+
+int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+int  nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
+void nxagentChangePicture(PicturePtr, Mask);
+int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
+void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
+                          INT16, INT16, INT16, INT16, CARD16, CARD16);
+void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
+void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+                                 pointer params, int nparams);
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
+                           INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
+
+/*
+ * The void pointer is actually a XGlyphElt8.
+ */
+
+void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
+                       INT16, INT16, int, void *, int, GlyphPtr *);
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    ProcRenderQueryVersion,
+    ProcRenderQueryPictFormats,
+    ProcRenderQueryPictIndexValues,
+    ProcRenderQueryDithers,
+    ProcRenderCreatePicture,
+    ProcRenderChangePicture,
+    ProcRenderSetPictureClipRectangles,
+    ProcRenderFreePicture,
+    ProcRenderComposite,
+    ProcRenderScale,
+    ProcRenderTrapezoids,
+    ProcRenderTriangles,
+    ProcRenderTriStrip,
+    ProcRenderTriFan,
+    ProcRenderColorTrapezoids,
+    ProcRenderColorTriangles,
+    ProcRenderTransform,
+    ProcRenderCreateGlyphSet,
+    ProcRenderReferenceGlyphSet,
+    ProcRenderFreeGlyphSet,
+    ProcRenderAddGlyphs,
+    ProcRenderAddGlyphsFromPicture,
+    ProcRenderFreeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderFillRectangles,
+    ProcRenderCreateCursor,
+    ProcRenderSetPictureTransform,
+    ProcRenderQueryFilters,
+    ProcRenderSetPictureFilter,
+    ProcRenderCreateAnimCursor,
+};
+
+int	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    SProcRenderQueryVersion,
+    SProcRenderQueryPictFormats,
+    SProcRenderQueryPictIndexValues,
+    SProcRenderQueryDithers,
+    SProcRenderCreatePicture,
+    SProcRenderChangePicture,
+    SProcRenderSetPictureClipRectangles,
+    SProcRenderFreePicture,
+    SProcRenderComposite,
+    SProcRenderScale,
+    SProcRenderTrapezoids,
+    SProcRenderTriangles,
+    SProcRenderTriStrip,
+    SProcRenderTriFan,
+    SProcRenderColorTrapezoids,
+    SProcRenderColorTriangles,
+    SProcRenderTransform,
+    SProcRenderCreateGlyphSet,
+    SProcRenderReferenceGlyphSet,
+    SProcRenderFreeGlyphSet,
+    SProcRenderAddGlyphs,
+    SProcRenderAddGlyphsFromPicture,
+    SProcRenderFreeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderFillRectangles,
+    SProcRenderCreateCursor,
+    SProcRenderSetPictureTransform,
+    SProcRenderQueryFilters,
+    SProcRenderSetPictureFilter,
+    SProcRenderCreateAnimCursor,
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+    
+static CARD8	RenderReqCode;
+int	RenderErrBase;
+int	RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+    int	    major_version;
+    int	    minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient)    ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr	*list,
+		      pointer		closure,
+		      pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
+
+    pRenderClient->major_version = 0;
+    pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+    ExtensionEntry *extEntry;
+
+    if (!PictureType)
+	return;
+    if (!PictureFinishInit ())
+	return;
+    RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+    if (!AllocateClientPrivate (RenderClientPrivateIndex, 
+				sizeof (RenderClientRec)))
+	return;
+    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+	return;
+
+    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+			     ProcRenderDispatch, SProcRenderDispatch,
+			     RenderResetProc, StandardMinorOpcode);
+    if (!extEntry)
+	return;
+    RenderReqCode = (CARD8) extEntry->base;
+    RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+    RenderClientPtr pRenderClient = GetRenderClient (client);
+    xRenderQueryVersionReply rep;
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    pRenderClient->major_version = stuff->majorVersion;
+    pRenderClient->minor_version = stuff->minorVersion;
+
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = nxagentRenderVersionMajor;
+    rep.minorVersion = nxagentRenderVersionMinor;
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.majorVersion, n);
+	swapl(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    DepthPtr    pDepth;
+    int		d, v;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = pScreen->allowedDepths + d;
+	for (v = 0; v < pDepth->numVids; v++)
+	{
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+	}
+    }
+    return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+    VisualPtr	pVisual;
+    int		v;
+
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = pScreen->visuals + v;
+	if (pVisual->vid == vid)
+	    return pVisual;
+    }
+    return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+    RenderClientPtr		    pRenderClient = GetRenderClient (client);
+    xRenderQueryPictFormatsReply    *reply;
+    xPictScreen			    *pictScreen;
+    xPictDepth			    *pictDepth;
+    xPictVisual			    *pictVisual;
+    xPictFormInfo		    *pictForm;
+    CARD32			    *pictSubpixel;
+    ScreenPtr			    pScreen;
+    VisualPtr			    pVisual;
+    DepthPtr			    pDepth;
+    int				    v, d;
+    PictureScreenPtr		    ps;
+    PictFormatPtr		    pFormat;
+    int				    nformat;
+    int				    ndepth;
+    int				    nvisual;
+    int				    rlength;
+    int				    s;
+    int				    n;
+    int				    numScreens;
+    int				    numSubpixel;
+
+    extern int                      nxagentAlphaEnabled;
+/*    REQUEST(xRenderQueryPictFormatsReq); */
+
+    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+    numScreens = screenInfo.numScreens;
+#endif
+    ndepth = nformat = nvisual = 0;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pDepth = pScreen->allowedDepths + d;
+	    ++ndepth;
+
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+		    ++nvisual;
+	    }
+	}
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    nformat += ps->nformats;
+    }
+    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+	numSubpixel = 0;
+    else
+	numSubpixel = numScreens;
+    
+    rlength = (sizeof (xRenderQueryPictFormatsReply) +
+	       nformat * sizeof (xPictFormInfo) +
+	       numScreens * sizeof (xPictScreen) +
+	       ndepth * sizeof (xPictDepth) +
+	       nvisual * sizeof (xPictVisual) +
+	       numSubpixel * sizeof (CARD32));
+    reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numFormats = nformat;
+    reply->numScreens = numScreens;
+    reply->numDepths = ndepth;
+    reply->numVisuals = nvisual;
+    reply->numSubpixel = numSubpixel;
+    
+    pictForm = (xPictFormInfo *) (reply + 1);
+    
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	{
+	    for (nformat = 0, pFormat = ps->formats; 
+		 nformat < ps->nformats;
+		 nformat++, pFormat++)
+	    {
+		pictForm->id = pFormat->id;
+		pictForm->type = pFormat->type;
+		pictForm->depth = pFormat->depth;
+		pictForm->direct.red = pFormat->direct.red;
+		pictForm->direct.redMask = pFormat->direct.redMask;
+		pictForm->direct.green = pFormat->direct.green;
+		pictForm->direct.greenMask = pFormat->direct.greenMask;
+		pictForm->direct.blue = pFormat->direct.blue;
+		pictForm->direct.blueMask = pFormat->direct.blueMask;
+		pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+		    pictForm->colormap = pFormat->index.pColormap->mid;
+		else
+		    pictForm->colormap = None;
+		if (client->swapped)
+		{
+		    swapl (&pictForm->id, n);
+		    swaps (&pictForm->direct.red, n);
+		    swaps (&pictForm->direct.redMask, n);
+		    swaps (&pictForm->direct.green, n);
+		    swaps (&pictForm->direct.greenMask, n);
+		    swaps (&pictForm->direct.blue, n);
+		    swaps (&pictForm->direct.blueMask, n);
+		    swaps (&pictForm->direct.alpha, n);
+		    swaps (&pictForm->direct.alphaMask, n);
+		    swapl (&pictForm->colormap, n);
+		}
+		pictForm++;
+	    }
+	}
+    }
+    
+    pictScreen = (xPictScreen *) pictForm;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	pictDepth = (xPictDepth *) (pictScreen + 1);
+	ndepth = 0;
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pictVisual = (xPictVisual *) (pictDepth + 1);
+	    pDepth = pScreen->allowedDepths + d;
+
+	    nvisual = 0;
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && (pFormat = PictureMatchVisual (pScreen, 
+							      pDepth->depth, 
+							      pVisual)))
+		{
+		    pictVisual->visual = pVisual->vid;
+		    pictVisual->format = pFormat->id;
+		    if (client->swapped)
+		    {
+			swapl (&pictVisual->visual, n);
+			swapl (&pictVisual->format, n);
+		    }
+		    pictVisual++;
+		    nvisual++;
+		}
+	    }
+	    pictDepth->depth = pDepth->depth;
+	    pictDepth->nPictVisuals = nvisual;
+	    if (client->swapped)
+	    {
+		swaps (&pictDepth->nPictVisuals, n);
+	    }
+	    ndepth++;
+	    pictDepth = (xPictDepth *) pictVisual;
+	}
+	pictScreen->nDepth = ndepth;
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    pictScreen->fallback = ps->fallback->id;
+	else
+	    pictScreen->fallback = 0;
+	if (client->swapped)
+	{
+	    swapl (&pictScreen->nDepth, n);
+	    swapl (&pictScreen->fallback, n);
+	}
+	pictScreen = (xPictScreen *) pictDepth;
+    }
+    pictSubpixel = (CARD32 *) pictScreen;
+    
+    for (s = 0; s < numSubpixel; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    *pictSubpixel = ps->subpixel;
+	else
+	    *pictSubpixel = SubPixelUnknown;
+	if (client->swapped)
+	{
+	    swapl (pictSubpixel, n);
+	}
+	++pictSubpixel;
+    }
+    
+    if (client->swapped)
+    {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numFormats, n);
+	swapl (&reply->numScreens, n);
+	swapl (&reply->numDepths, n);
+	swapl (&reply->numVisuals, n);
+	swapl (&reply->numSubpixel, n);
+    }
+    WriteToClient(client, rlength, (char *) reply);
+    xfree (reply);
+    return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    PictFormatPtr   pFormat;
+    int		    num;
+    int		    rlength;
+    int		    i, n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    xRenderQueryPictIndexValuesReply *reply;
+    xIndexValue	    *values;
+
+    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->type != PictTypeIndexed)
+    {
+	client->errorValue = stuff->format;
+	return BadMatch;
+    }
+    num = pFormat->index.nvalues;
+    rlength = (sizeof (xRenderQueryPictIndexValuesReply) + 
+	       num * sizeof(xIndexValue));
+    reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numIndexValues = num;
+
+    values = (xIndexValue *) (reply + 1);
+    
+    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+    
+    if (client->swapped)
+    {
+	for (i = 0; i < num; i++)
+	{
+	    swapl (&values[i].pixel, n);
+	    swaps (&values[i].red, n);
+	    swaps (&values[i].green, n);
+	    swaps (&values[i].blue, n);
+	    swaps (&values[i].alpha, n);
+	}
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numIndexValues, n);
+    }
+
+    WriteToClient(client, rlength, (char *) reply);
+    xfree(reply);
+    return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    int		    len;
+    int		    error;
+    REQUEST(xRenderCreatePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+			     SecurityWriteAccess);
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->depth != pDrawable->depth)
+	return BadMatch;
+    len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    pPicture = CreatePicture (stuff->pid,
+			      pDrawable,
+			      pFormat,
+			      stuff->mask,
+			      (XID *) (stuff + 1),
+			      client,
+			      &error);
+    if (!pPicture)
+	return error;
+    nxagentCreatePicture(pPicture, stuff -> mask);
+
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    REQUEST(xRenderChangePictureReq);
+    int len;
+    int error;
+
+    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+			  (DevUnion *) 0, client);
+    
+    nxagentChangePicture(pPicture, stuff->mask);
+
+    return error;
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    PicturePtr	    pPicture;
+    int		    nr;
+    int		    result;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    /*
+     * The original code used sizeof(xRenderChangePictureReq).
+     * This was harmless, as both structures have the same size.
+     *
+     * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+     */
+    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+    if (nr & 4)
+	return BadLength;
+    nr >>= 3;
+    result = SetPictureClipRects (pPicture, 
+				  stuff->xOrigin, stuff->yOrigin,
+				  nr, (xRectangle *) &stuff[1]);
+    nxagentChangePictureClip (pPicture,
+                              CT_NONE,
+                              nr,
+                              (xRectangle *) &stuff[1],
+                              (int)stuff -> xOrigin,
+                              (int)stuff -> yOrigin);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+    PicturePtr	pPicture;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+		    RenderErrBase + BadPicture);
+
+    nxagentDestroyPicture(pPicture);
+
+    FreeResource (stuff->picture, RT_NONE);
+    return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+	return TRUE;
+    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+	return TRUE;
+    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Check if both pictures have drawables which are
+ * virtual pixmaps. See the corresponding define
+ * in NXpicture.c
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#define nxagentCompositePredicate(pSrc, pDst)  TRUE
+
+#else
+
+/*
+ * This is still under development. The final
+ * goal is to let pictures point to the real
+ * pixmaps instead of pointing to virtuals.
+ */
+
+int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
+{
+  PixmapPtr pPixmap1;
+  PixmapPtr pPixmap2;
+
+  pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pSrc -> pDrawable) : NULL);
+
+  pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pDst -> pDrawable) : NULL);
+
+  if (pPixmap1 == NULL || pPixmap2 == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
+    #endif
+
+    return FALSE;
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
+    #endif
+
+    if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
+            nxagentPixmapIsVirtual(pPixmap2) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
+      #endif
+
+      return TRUE;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
+  #endif
+
+  return FALSE;
+}
+
+#endif
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+    PicturePtr	pSrc, pMask, pDst;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
+		  RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen ||
+	(pMask && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
+
+    ValidatePicture (pSrc);
+    if (pMask)
+        ValidatePicture (pMask);
+    ValidatePicture (pDst);
+
+    #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+    if (nxagentCompositePredicate(pSrc, pDst))
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pMask, (void *) pDst);
+      #endif
+
+    CompositePicture (stuff->op,
+		      pSrc,
+		      pMask,
+		      pDst,
+		      stuff->xSrc,
+		      stuff->ySrc,
+		      stuff->xMask,
+		      stuff->yMask,
+		      stuff->xDst,
+		      stuff->yDst,
+		      stuff->width,
+		      stuff->height);
+    }
+
+    #else
+
+    if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+            pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
+    {
+      PixmapPtr pVirtualPixmapSrc;
+      PixmapPtr pVirtualPixmapDst;
+      PixmapPtr pVirtualPixmapMask;
+
+      PicturePtr pVirtualPictureSrc;
+      PicturePtr pVirtualPictureDst;
+      PicturePtr pVirtualPictureMask;
+
+      pVirtualPixmapSrc  = (PixmapPtr) pSrc  -> pDrawable;
+      pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
+
+      pVirtualPixmapDst  = (PixmapPtr) pDst  -> pDrawable;
+      pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
+
+      if (pMask)
+      {
+        pVirtualPixmapMask  = (PixmapPtr) pMask  -> pDrawable;
+        pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
+      }
+      else
+      {
+        pVirtualPixmapMask  = NULL;
+        pVirtualPictureMask = NULL;
+      }
+
+      if (pVirtualPictureSrc && pVirtualPictureDst)
+      {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
+                          (void *) pVirtualPixmapDst);
+      #endif
+
+      CompositePicture (stuff->op,
+                        pVirtualPictureSrc,
+                        pVirtualPictureMask,
+                        pVirtualPictureDst,
+                        stuff->xSrc,
+                        stuff->ySrc,
+                        stuff->xMask,
+                        stuff->yMask,
+                        stuff->xDst,
+                        stuff->yDst,
+                        stuff->width,
+                        stuff->height);
+      }
+    }
+
+    #endif
+
+    nxagentComposite (stuff -> op,
+                      pSrc,
+                      pMask,
+                      pDst,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      stuff -> xMask,
+                      stuff -> yMask,
+                      stuff -> xDst,
+                      stuff -> yDst,
+                      stuff -> width,
+                      stuff -> height);
+
+    return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+    if (ntraps % sizeof (xTrapezoid))
+	return BadLength;
+    ntraps /= sizeof (xTrapezoid);
+    if (ntraps)
+    {
+        if (nxagentCompositePredicate(pSrc, pDst))
+        {
+	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+			     stuff->xSrc, stuff->ySrc,
+			     ntraps, (xTrapezoid *) &stuff[1]);
+        }
+
+        nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
+                             stuff->xSrc, stuff->ySrc,
+                             ntraps, (xTrapezoid *) &stuff[1]);
+    }
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+    int		ntris;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+    if (ntris % sizeof (xTriangle))
+	return BadLength;
+    ntris /= sizeof (xTriangle);
+    if (ntris)
+	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+			    stuff->xSrc, stuff->ySrc,
+			    ntris, (xTriangle *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+			   stuff->xSrc, stuff->ySrc,
+			   npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+			 stuff->xSrc, stuff->ySrc,
+			 npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr	    glyphSet;
+    PictFormatPtr   format;
+    int		    f;
+    REQUEST(xRenderCreateGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+    format = (PictFormatPtr) SecurityLookupIDByType (client,
+						     stuff->format,
+						     PictFormatType,
+						     SecurityReadAccess);
+    if (!format)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    switch (format->depth) {
+    case 1:
+	f = GlyphFormat1;
+	break;
+    case 4:
+	f = GlyphFormat4;
+	break;
+    case 8:
+	f = GlyphFormat8;
+	break;
+    case 16:
+	f = GlyphFormat16;
+	break;
+    case 32:
+	f = GlyphFormat32;
+	break;
+    default:
+	return BadMatch;
+    }
+    if (format->type != PictTypeDirect)
+	return BadMatch;
+    glyphSet = AllocateGlyphSet (f, format);
+    if (!glyphSet)
+	return BadAlloc;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+
+    nxagentCreateGlyphSet(glyphSet);
+
+    return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderReferenceGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->existing,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->existing;
+	return RenderErrBase + BadGlyphSet;
+    }
+    glyphSet->refcnt++;
+
+    nxagentReferenceGlyphSet(glyphSet);
+
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return client->noClientException;
+}
+
+#define NLOCALDELTA	64
+#define NLOCALGLYPH	256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderFreeGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityDestroyAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nxagentFreeGlyphSet(glyphSet);
+
+    FreeResource (stuff->glyphset, RT_NONE);
+    return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+    Glyph	id;
+    GlyphPtr    glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderAddGlyphsReq);
+    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
+    GlyphNewPtr	    glyphsBase, glyphs;
+    GlyphPtr	    glyph = NULL;
+    int		    remain, nglyphs;
+    CARD32	    *gids;
+    xGlyphInfo	    *gi;
+    CARD8	    *bits;
+    int		    size;
+    int		    err = BadAlloc;
+
+    int             totSizeImages;
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nglyphs = stuff->nglyphs;
+    if (nglyphs <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphNewPtr) ALLOCATE_LOCAL (nglyphs * sizeof (GlyphNewRec));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+
+    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+    glyphs = glyphsBase;
+
+    totSizeImages = 0;
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + nglyphs);
+    bits = (CARD8 *) (gi + nglyphs);
+    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+
+    while (remain >= 0 && nglyphs)
+    {
+	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+	if (!glyph)
+	{
+	    err = BadAlloc;
+	    goto bail;
+	}
+	
+	glyphs->glyph = glyph;
+	glyphs->id = *gids;	
+	
+	size = glyph->size - sizeof (xGlyphInfo);
+	if (remain < size)
+	    break;
+	memcpy ((CARD8 *) (glyph + 1), bits, size);
+	
+	if (size & 3)
+	    size += 4 - (size & 3);
+	bits += size;
+	totSizeImages += size;
+	remain -= size;
+	gi++;
+	gids++;
+	glyphs++;
+	nglyphs--;
+    }
+
+    if (nglyphs || remain)
+    {
+	err = BadLength;
+	goto bail;
+    }
+    nglyphs = stuff->nglyphs;
+    if (!ResizeGlyphSet (glyphSet, nglyphs))
+    {
+	err = BadAlloc;
+	goto bail;
+    }
+    glyphs = glyphsBase;
+    while (nglyphs--)
+	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    return client->noClientException;
+bail:
+    while (glyphs != glyphsBase)
+    {
+	--glyphs;
+	xfree (glyphs->glyph);
+    }
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+    REQUEST(xRenderFreeGlyphsReq);
+    GlyphSetPtr     glyphSet;
+    int		    nglyph;
+    CARD32	    *gids;
+    CARD32	    glyph;
+
+    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+    gids = (CARD32 *) (stuff + 1);
+
+    nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
+    while (nglyph-- > 0)
+    {
+	glyph = *gids++;
+	if (!DeleteGlyph (glyphSet, glyph))
+	{
+	    client->errorValue = glyph;
+	    return RenderErrBase + BadGlyph;
+	}
+    }
+    return client->noClientException;
+}
+
+typedef struct XGlyphElt8{
+    GlyphSet                glyphset;
+    _Xconst char            *chars;
+    int                     nchars;
+    int                     xOff;
+    int                     yOff;
+} XGlyphElt8;
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    GlyphSet	    gs;
+    PicturePtr      pSrc, pDst;
+    PictFormatPtr   pFormat;
+    GlyphListRec    listsLocal[NLOCALDELTA];
+    GlyphListPtr    lists, listsBase;
+    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
+    Glyph	    glyph;
+    GlyphPtr	    *glyphs, *glyphsBase;
+    xGlyphElt	    *elt;
+    CARD8	    *buffer, *end;
+    int		    nglyph;
+    int		    nlist;
+    int		    space;
+    int		    size;
+    int		    n;
+    
+    XGlyphElt8      *elements, *elementsBase;
+
+    REQUEST(xRenderCompositeGlyphsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityReadAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    nglyph = 0;
+    nlist = 0;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    buffer += 4;
+	}
+	else
+	{
+	    nlist++;
+	    nglyph += elt->len;
+	    space = size * elt->len;
+	    if (space & 3)
+		space += 4 - (space & 3);
+	    buffer += space;
+	}
+    }
+    if (nglyph <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+    if (nlist <= NLOCALDELTA)
+	listsBase = listsLocal;
+    else
+    {
+	listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+	if (!listsBase)
+	    return BadAlloc;
+    }
+
+    elementsBase = xalloc(nlist * sizeof(XGlyphElt8));
+    if (!elementsBase)
+      return BadAlloc;
+
+    buffer = (CARD8 *) (stuff + 1);
+    glyphs = glyphsBase;
+    lists = listsBase;
+    elements = elementsBase;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+            #ifdef DEBUG
+            fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+                        size);
+            #endif
+
+	    if (buffer + sizeof (GlyphSet) < end)
+	    {
+		gs = *(GlyphSet *) buffer;
+		glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+								 gs,
+								 GlyphSetType,
+								 SecurityReadAccess);
+		if (!glyphSet)
+		{
+		    client->errorValue = gs;
+		    if (glyphsBase != glyphsLocal)
+			DEALLOCATE_LOCAL (glyphsBase);
+		    if (listsBase != listsLocal)
+			DEALLOCATE_LOCAL (listsBase);
+		    return RenderErrBase + BadGlyphSet;
+		}
+	    }
+	    buffer += 4;
+	}
+	else
+	{
+	    lists->xOff = elt->deltax;
+	    lists->yOff = elt->deltay;
+	    lists->format = glyphSet->format;
+	    lists->len = 0;
+            elements -> glyphset = glyphSet -> remoteID;
+            elements -> chars = (char *) buffer;
+            elements -> nchars = elt->len;
+            elements -> xOff = elt->deltax;
+            elements -> yOff = elt->deltay;
+	    n = elt->len;
+	    while (n--)
+	    {
+		if (buffer + size <= end)
+		{
+		    switch (size) {
+		    case 1:
+			glyph = *((CARD8 *)buffer); break;
+		    case 2:
+			glyph = *((CARD16 *)buffer); break;
+		    case 4:
+		    default:
+			glyph = *((CARD32 *)buffer); break;
+		    }
+		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
+		    {
+			lists->len++;
+			glyphs++;
+		    }
+		}
+		buffer += size;
+	    }
+	    space = size * elt->len;
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	    lists++;
+            elements++;
+	}
+    }
+    if (buffer > end)
+	return BadLength;
+
+    /*
+     * We need to know the glyphs extents to synchronize
+     * the drawables involved in the composite text ope-
+     * ration. Also we need to synchronize only the back-
+     * ground of the text we are going to render, so the
+     * operations on the framebuffer must be executed
+     * after the X requests.
+     */
+
+    if (pFormat != NULL)
+    {
+      nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+      miGlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
+    }
+
+    nxagentGlyphs(stuff -> op,
+                  pSrc,
+                  pDst,
+                  pFormat,
+                  stuff -> xSrc,
+                  stuff -> ySrc,
+                  nlist,
+                  elementsBase,
+                  size,
+                  glyphsBase);
+
+    if (nxagentCompositePredicate(pSrc, pDst) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
+                  "source at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pDst);
+      #endif
+
+      CompositeGlyphs(stuff -> op,
+                      pSrc,
+                      pDst,
+                      pFormat,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      nlist,
+                      listsBase,
+                      glyphsBase);
+    }
+
+    if (nxagentGlyphsExtents != NullBox)
+    {
+      xfree(nxagentGlyphsExtents);
+
+      nxagentGlyphsExtents = NullBox;
+    }
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    if (listsBase != listsLocal)
+	DEALLOCATE_LOCAL (listsBase);
+    
+    xfree(elementsBase);
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+    PicturePtr	    pDst;
+    int             things;
+    REQUEST(xRenderFillRectanglesReq);
+    
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    
+    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+    
+    CompositeRects (stuff->op,
+		    pDst,
+		    &stuff->color,
+		    things,
+		    (xRectangle *) &stuff[1]);
+
+    ValidatePicture (pDst);
+    nxagentCompositeRects(stuff -> op,
+                          pDst,
+                          &stuff -> color,
+                          things,
+                          (xRectangle *) &stuff[1]);
+    
+    return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+    unsigned char   mask;
+    
+    if (screenInfo.bitmapBitOrder == LSBFirst)
+	mask = (1 << (x & 7));
+    else
+	mask = (0x80 >> (x & 7));
+    /* XXX assumes byte order is host byte order */
+    line += (x >> 3);
+    if (bit)
+	*line |= mask;
+    else
+	*line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+    {  1,  3,  },
+    {  4,  2,  },
+};
+
+#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateCursorReq);
+    PicturePtr	    pSrc;
+    ScreenPtr	    pScreen;
+    unsigned short  width, height;
+    CARD32	    *argbbits, *argb;
+    unsigned char   *srcbits, *srcline;
+    unsigned char   *mskbits, *mskline;
+    int		    stride;
+    int		    x, y;
+    int		    nbytes_mono;
+    CursorMetricRec cm;
+    CursorPtr	    pCursor;
+    CARD32	    twocolor[3];
+    int		    ncolor;
+
+    RealizeCursorProcPtr saveRealizeCursor;
+
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    pScreen = pSrc->pDrawable->pScreen;
+    width = pSrc->pDrawable->width;
+    height = pSrc->pDrawable->height;
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+    argbbits = xalloc (width * height * sizeof (CARD32));
+    if (!argbbits)
+	return (BadAlloc);
+    
+    stride = BitmapBytePad(width);
+    nbytes_mono = stride*height;
+    srcbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!srcbits)
+    {
+	xfree (argbbits);
+	return (BadAlloc);
+    }
+    mskbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!mskbits)
+    {
+	xfree(argbbits);
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+    bzero ((char *) mskbits, nbytes_mono);
+    bzero ((char *) srcbits, nbytes_mono);
+
+    if (pSrc->format == PICT_a8r8g8b8)
+    {
+	(*pScreen->GetImage) (pSrc->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+    }
+    else
+    {
+	PixmapPtr	pPixmap;
+	PicturePtr	pPicture;
+	PictFormatPtr	pFormat;
+	int		error;
+
+	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+	if (!pFormat)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadImplementation);
+	}
+	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+	if (!pPixmap)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadAlloc);
+	}
+	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, 
+				  client, &error);
+	if (!pPicture)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return error;
+	}
+	(*pScreen->DestroyPixmap) (pPixmap);
+	CompositePicture (PictOpSrc,
+			  pSrc, 0, pPicture,
+			  0, 0, 0, 0, 0, 0, width, height);
+	(*pScreen->GetImage) (pPicture->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+	FreePicture (pPicture, 0);
+    }
+    /*
+     * Check whether the cursor can be directly supported by 
+     * the core cursor code
+     */
+    ncolor = 0;
+    argb = argbbits;
+    for (y = 0; ncolor <= 2 && y < height; y++)
+    {
+	for (x = 0; ncolor <= 2 && x < width; x++)
+	{
+	    CARD32  p = *argb++;
+	    CARD32  a = (p >> 24);
+
+	    if (a == 0)	    /* transparent */
+		continue;
+	    if (a == 0xff)  /* opaque */
+	    {
+		int n;
+		for (n = 0; n < ncolor; n++)
+		    if (p == twocolor[n])
+			break;
+		if (n == ncolor)
+		    twocolor[ncolor++] = p;
+	    }
+	    else
+		ncolor = 3;
+	}
+    }
+    
+    /*
+     * Convert argb image to two plane cursor
+     */
+    srcline = srcbits;
+    mskline = mskbits;
+    argb = argbbits;
+    for (y = 0; y < height; y++)
+    {
+	for (x = 0; x < width; x++)
+	{
+	    CARD32  p = *argb++;
+
+	    if (ncolor <= 2)
+	    {
+		CARD32	a = ((p >> 24));
+
+		SetBit (mskline, x, a != 0);
+		SetBit (srcline, x, a != 0 && p == twocolor[0]);
+	    }
+	    else
+	    {
+		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+		/* Set mask from dithered alpha value */
+		SetBit(mskline, x, a > d);
+		/* Set src from dithered intensity value */
+		SetBit(srcline, x, a > d && i <= d);
+	    }
+	}
+	srcline += stride;
+	mskline += stride;
+    }
+    /*
+     * Dither to white and black if the cursor has more than two colors
+     */
+    if (ncolor > 2)
+    {
+	twocolor[0] = 0xff000000;
+	twocolor[1] = 0xffffffff;
+    }
+    else
+    {
+	xfree (argbbits);
+	argbbits = 0;
+    }
+    
+#define GetByte(p,s)	(((p) >> (s)) & 0xff)
+#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
+    
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+
+    /*
+     * This cursor uses RENDER, so we make sure
+     * that it is allocated in a way that allows
+     * the mi and dix layers to handle it but we
+     * later create it on the server by mirror-
+     * ing the RENDER operation we got from the
+     * client.
+     */
+
+    saveRealizeCursor = pScreen -> RealizeCursor;
+
+    pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
+
+    pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+			       GetColor(twocolor[0], 16),
+			       GetColor(twocolor[0], 8),
+			       GetColor(twocolor[0], 0),
+			       GetColor(twocolor[1], 16),
+			       GetColor(twocolor[1], 8),
+			       GetColor(twocolor[1], 0));
+
+    pScreen -> RealizeCursor = saveRealizeCursor;
+
+    /*
+     * Store into the private data members the
+     * information needed to recreate it at
+     * reconnection. This is done in two steps
+     * as in the first step we don't have the
+     * picture info.
+     */
+
+    if (pCursor == NULL)
+    {
+      return BadAlloc;
+    }
+
+    nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
+
+    nxagentRenderRealizeCursor(pScreen, pCursor);
+
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return (client->noClientException);
+    return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    PicturePtr	pPicture;
+    int		result;
+
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+
+    nxagentSetPictureTransform(pPicture, &stuff->transform);
+    
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+    REQUEST (xRenderQueryFiltersReq);
+    DrawablePtr			pDrawable;
+    xRenderQueryFiltersReply	*reply;
+    int				nbytesName;
+    int				nnames;
+    ScreenPtr			pScreen;
+    PictureScreenPtr		ps;
+    int				i, j;
+    int				len;
+    int				total_bytes;
+    INT16			*aliases;
+    char			*names;
+
+    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+    
+    pScreen = pDrawable->pScreen;
+    nbytesName = 0;
+    nnames = 0;
+    ps = GetPictureScreenIfSet(pScreen);
+    if (ps)
+    {
+	for (i = 0; i < ps->nfilters; i++)
+	    nbytesName += 1 + strlen (ps->filters[i].name);
+	for (i = 0; i < ps->nfilterAliases; i++)
+	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+	nnames = ps->nfilters + ps->nfilterAliases;
+    }
+    len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+    reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+    if (!reply)
+	return BadAlloc;
+    aliases = (INT16 *) (reply + 1);
+    names = (char *) (aliases + ((nnames + 1) & ~1));
+    
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = len;
+    reply->numAliases = nnames;
+    reply->numFilters = nnames;
+    if (ps)
+    {
+
+	/* fill in alias values */
+	for (i = 0; i < ps->nfilters; i++)
+	    aliases[i] = FilterAliasNone;
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    for (j = 0; j < ps->nfilters; j++)
+		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+		    break;
+	    if (j == ps->nfilters)
+	    {
+		for (j = 0; j < ps->nfilterAliases; j++)
+		    if (ps->filterAliases[i].filter_id == 
+			ps->filterAliases[j].alias_id)
+		    {
+			break;
+		    }
+		if (j == ps->nfilterAliases)
+		    j = FilterAliasNone;
+		else
+		    j = j + ps->nfilters;
+	    }
+	    aliases[i + ps->nfilters] = j;
+	}
+
+	/* fill in filter names */
+	for (i = 0; i < ps->nfilters; i++)
+	{
+	    j = strlen (ps->filters[i].name);
+	    *names++ = j;
+	    strncpy (names, ps->filters[i].name, j);
+	    names += j;
+	}
+	
+	/* fill in filter alias names */
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    j = strlen (ps->filterAliases[i].alias);
+	    *names++ = j;
+	    strncpy (names, ps->filterAliases[i].alias, j);
+	    names += j;
+	}
+    }
+
+    if (client->swapped)
+    {
+	register int n;
+
+	for (i = 0; i < (int)reply->numAliases; i++)
+	{
+	    swaps (&aliases[i], n);
+	}
+    	swaps(&reply->sequenceNumber, n);
+    	swapl(&reply->length, n);
+	swapl(&reply->numAliases, n);
+	swapl(&reply->numFilters, n);
+    }
+    WriteToClient(client, total_bytes, (char *) reply);
+    xfree (reply);
+    
+    return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST (xRenderSetPictureFilterReq);
+    PicturePtr	pPicture;
+    int		result;
+    xFixed	*params;
+    int		nparams;
+    char	*name;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    name = (char *) (stuff + 1);
+    params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+
+    nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
+
+    return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateAnimCursorReq);
+    CursorPtr	    *cursors;
+    CARD32	    *deltas;
+    CursorPtr	    pCursor;
+    int		    ncursor;
+    xAnimCursorElt  *elt;
+    int		    i;
+    int		    ret;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    if (client->req_len & 1)
+	return BadLength;
+    ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+    cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+    if (!cursors)
+	return BadAlloc;
+    deltas = (CARD32 *) (cursors + ncursor);
+    elt = (xAnimCursorElt *) (stuff + 1);
+    for (i = 0; i < ncursor; i++)
+    {
+	cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+						       RT_CURSOR, SecurityReadAccess);
+	if (!cursors[i])
+	{
+	    xfree (cursors);
+	    client->errorValue = elt->cursor;
+	    return BadCursor;
+	}
+	deltas[i] = elt->delay;
+	elt++;
+    }
+    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+    xfree (cursors);
+    if (ret != Success)
+	return ret;
+    
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+      pCursor -> devPriv[i] = NULL;
+    }
+
+    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*ProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->majorVersion, n);
+    swapl(&stuff->minorVersion, n);
+    return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictFormatsReq);
+    swaps(&stuff->length, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreatePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->format, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderChangePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCompositeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->mask, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xMask, n);
+    swaps(&stuff->yMask, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderScaleReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->colorScale, n);
+    swapl(&stuff->alphaScale, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriStripReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriFanReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderReferenceGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->existing, n);
+    return (*ProcRenderVector[stuff->renderReqType])  (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+    register int n;
+    register unsigned int i;
+    CARD32  *gids;
+    void    *end;
+    xGlyphInfo *gi;
+    REQUEST(xRenderAddGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    swapl(&stuff->nglyphs, n);
+    if (stuff->nglyphs & 0xe0000000)
+	return BadLength;
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+	return BadLength;
+    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+	return BadLength;
+    for (i = 0; i < stuff->nglyphs; i++)
+    {
+	swapl (&gids[i], n);
+	swaps (&gi[i].width, n);
+	swaps (&gi[i].height, n);
+	swaps (&gi[i].x, n);
+	swaps (&gi[i].y, n);
+	swaps (&gi[i].xOff, n);
+	swaps (&gi[i].yOff, n);
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+    register int n;
+    xGlyphElt	*elt;
+    CARD8	*buffer;
+    CARD8	*end;
+    int		space;
+    int		i;
+    int		size;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+    
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->maskFormat, n);
+    swapl(&stuff->glyphset, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	swaps (&elt->deltax, n);
+	swaps (&elt->deltay, n);
+	
+	i = elt->len;
+	if (i == 0xff)
+	{
+	    swapl (buffer, n);
+	    buffer += 4;
+	}
+	else
+	{
+	    space = size * i;
+	    switch (size) {
+	    case 1:
+		buffer += i;
+		break;
+	    case 2:
+		while (i--)
+		{
+		    swaps (buffer, n);
+		    buffer += 2;
+		}
+		break;
+	    case 4:
+		while (i--)
+		{
+		    swapl (buffer, n);
+		    buffer += 4;
+		}
+		break;
+	    }
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	}
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFillRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    swaps(&stuff->color.alpha, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateCursorReq);
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    swapl(&stuff->src, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureTransformReq);
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->transform.matrix11, n);
+    swapl(&stuff->transform.matrix12, n);
+    swapl(&stuff->transform.matrix13, n);
+    swapl(&stuff->transform.matrix21, n);
+    swapl(&stuff->transform.matrix22, n);
+    swapl(&stuff->transform.matrix23, n);
+    swapl(&stuff->transform.matrix31, n);
+    swapl(&stuff->transform.matrix32, n);
+    swapl(&stuff->transform.matrix33, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderQueryFiltersReq);
+    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderSetPictureFilterReq);
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->nbytes, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateAnimCursorReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+    
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*SProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+int	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long	XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+    REQUEST(xRenderCreatePictureReq);
+    PanoramiXRes    *refDraw, *newPict;
+    int		    result = Success, j;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+    if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+    if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+    newPict->type = XRT_PICTURE;
+    newPict->info[0].id = stuff->pid;
+    
+    if (refDraw->type == XRT_WINDOW &&
+	stuff->drawable == WindowTable[0]->drawable.id)
+    {
+	newPict->u.pict.root = TRUE;
+    }
+    else
+	newPict->u.pict.root = FALSE;
+
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPict->info[j].id = FakeClientID(client->index);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->pid = newPict->info[j].id;
+	stuff->drawable = refDraw->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+	if(result != Success) break;
+    }
+
+    if (result == Success)
+	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+    else 
+	xfree(newPict);
+
+    return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+    PanoramiXRes    *pict;
+    int		    result = Success, j;
+    REQUEST(xRenderChangePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+    PanoramiXRes *pict;
+    int         result = Success, j;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    client->errorValue = stuff->picture;
+
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+		       RenderErrBase + BadPicture);
+    
+
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->picture = pict->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+	if(result != Success) break;
+    }
+
+    /* Since ProcRenderFreePicture is using FreeResource, it will free
+	our resource for us on the last pass through the loop above */
+ 
+    return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+    PanoramiXRes	*src, *msk, *dst;
+    int			result = Success, j;
+    xRenderCompositeReq	orig;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess, 
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess, 
+		      RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    
+    orig = *stuff;
+    
+    FOR_NSCREENS_FORWARD(j) {
+	stuff->src = src->info[j].id;
+	if (src->u.pict.root)
+	{
+	    stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+	    stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+	}
+	stuff->dst = dst->info[j].id;
+	if (dst->u.pict.root)
+	{
+	    stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+	    stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+	}
+	if (msk)
+	{
+	    stuff->mask = msk->info[j].id;
+	    if (msk->u.pict.root)
+	    {
+		stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+		stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+	    }
+	}
+	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+	if(result != Success) break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+    PanoramiXRes    *src, *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderCompositeGlyphsReq);
+    xGlyphElt	    origElt, *elt;
+    INT16	    xSrc, ySrc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+				 sizeof (xGlyphElt)))
+    {
+	elt = (xGlyphElt *) (stuff + 1);
+	origElt = *elt;
+	xSrc = stuff->xSrc;
+	ySrc = stuff->ySrc;
+	FOR_NSCREENS_FORWARD(j) {
+	    stuff->src = src->info[j].id;
+	    if (src->u.pict.root)
+	    {
+		stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+		stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+	    }
+	    stuff->dst = dst->info[j].id;
+	    if (dst->u.pict.root)
+	    {
+		elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+		elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+	    if(result != Success) break;
+	}
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+    PanoramiXRes    *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderFillRectanglesReq);
+    char	    *extra;
+    int		    extra_len;
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root)
+	    {
+		int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+		    xRectangle	*rects = (xRectangle *) (stuff + 1);
+		    int		i = extra_len / sizeof (xRectangle);
+
+		    while (i--)
+		    {
+			rects->x -= x_off;
+			rects->y -= y_off;
+			rects++;
+		    }
+		}
+	    }
+	    stuff->dst = dst->info[j].id;
+	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+    int	    i;
+    
+    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+    for (i = 0; i < RenderNumberRequests; i++)
+	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+    /*
+     * Stuff in Xinerama aware request processing hooks
+     */
+    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+    int	    i;
+    for (i = 0; i < RenderNumberRequests; i++)
+	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif	/* PANORAMIX */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
new file mode 100644
index 000000000..20aca4619
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
@@ -0,0 +1,3048 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXrender.c"
+
+#else
+
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.26 2003/02/14 18:15:21 dawes Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include "render.h"
+#include "renderproto.h"
+#include "Xfuncproto.h"
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * From NXmiglyph.c.
+ */
+
+void miGlyphExtents(int nlist, GlyphListPtr list,
+                        GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * Functions from Render.c.
+ */
+
+int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+int  nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
+void nxagentChangePicture(PicturePtr, Mask);
+int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
+void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
+                          INT16, INT16, INT16, INT16, CARD16, CARD16);
+void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
+void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+                                 pointer params, int nparams);
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
+                           INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
+
+/*
+ * The void pointer is actually a XGlyphElt8.
+ */
+
+void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
+                       INT16, INT16, int, void *, int, GlyphPtr *);
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    ProcRenderQueryVersion,
+    ProcRenderQueryPictFormats,
+    ProcRenderQueryPictIndexValues,
+    ProcRenderQueryDithers,
+    ProcRenderCreatePicture,
+    ProcRenderChangePicture,
+    ProcRenderSetPictureClipRectangles,
+    ProcRenderFreePicture,
+    ProcRenderComposite,
+    ProcRenderScale,
+    ProcRenderTrapezoids,
+    ProcRenderTriangles,
+    ProcRenderTriStrip,
+    ProcRenderTriFan,
+    ProcRenderColorTrapezoids,
+    ProcRenderColorTriangles,
+    ProcRenderTransform,
+    ProcRenderCreateGlyphSet,
+    ProcRenderReferenceGlyphSet,
+    ProcRenderFreeGlyphSet,
+    ProcRenderAddGlyphs,
+    ProcRenderAddGlyphsFromPicture,
+    ProcRenderFreeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderFillRectangles,
+    ProcRenderCreateCursor,
+    ProcRenderSetPictureTransform,
+    ProcRenderQueryFilters,
+    ProcRenderSetPictureFilter,
+    ProcRenderCreateAnimCursor,
+};
+
+int	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    SProcRenderQueryVersion,
+    SProcRenderQueryPictFormats,
+    SProcRenderQueryPictIndexValues,
+    SProcRenderQueryDithers,
+    SProcRenderCreatePicture,
+    SProcRenderChangePicture,
+    SProcRenderSetPictureClipRectangles,
+    SProcRenderFreePicture,
+    SProcRenderComposite,
+    SProcRenderScale,
+    SProcRenderTrapezoids,
+    SProcRenderTriangles,
+    SProcRenderTriStrip,
+    SProcRenderTriFan,
+    SProcRenderColorTrapezoids,
+    SProcRenderColorTriangles,
+    SProcRenderTransform,
+    SProcRenderCreateGlyphSet,
+    SProcRenderReferenceGlyphSet,
+    SProcRenderFreeGlyphSet,
+    SProcRenderAddGlyphs,
+    SProcRenderAddGlyphsFromPicture,
+    SProcRenderFreeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderFillRectangles,
+    SProcRenderCreateCursor,
+    SProcRenderSetPictureTransform,
+    SProcRenderQueryFilters,
+    SProcRenderSetPictureFilter,
+    SProcRenderCreateAnimCursor,
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+    
+static CARD8	RenderReqCode;
+int	RenderErrBase;
+int	RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+    int	    major_version;
+    int	    minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient)    ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr	*list,
+		      pointer		closure,
+		      pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
+
+    pRenderClient->major_version = 0;
+    pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+    ExtensionEntry *extEntry;
+
+    if (!PictureType)
+	return;
+    if (!PictureFinishInit ())
+	return;
+    RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+    if (!AllocateClientPrivate (RenderClientPrivateIndex, 
+				sizeof (RenderClientRec)))
+	return;
+    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+	return;
+
+    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+			     ProcRenderDispatch, SProcRenderDispatch,
+			     RenderResetProc, StandardMinorOpcode);
+    if (!extEntry)
+	return;
+    RenderReqCode = (CARD8) extEntry->base;
+    RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+    RenderClientPtr pRenderClient = GetRenderClient (client);
+    xRenderQueryVersionReply rep;
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    pRenderClient->major_version = stuff->majorVersion;
+    pRenderClient->minor_version = stuff->minorVersion;
+
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = nxagentRenderVersionMajor;
+    rep.minorVersion = nxagentRenderVersionMinor;
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.majorVersion, n);
+	swapl(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    DepthPtr    pDepth;
+    int		d, v;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = pScreen->allowedDepths + d;
+	for (v = 0; v < pDepth->numVids; v++)
+	{
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+	}
+    }
+    return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+    VisualPtr	pVisual;
+    int		v;
+
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = pScreen->visuals + v;
+	if (pVisual->vid == vid)
+	    return pVisual;
+    }
+    return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+    RenderClientPtr		    pRenderClient = GetRenderClient (client);
+    xRenderQueryPictFormatsReply    *reply;
+    xPictScreen			    *pictScreen;
+    xPictDepth			    *pictDepth;
+    xPictVisual			    *pictVisual;
+    xPictFormInfo		    *pictForm;
+    CARD32			    *pictSubpixel;
+    ScreenPtr			    pScreen;
+    VisualPtr			    pVisual;
+    DepthPtr			    pDepth;
+    int				    v, d;
+    PictureScreenPtr		    ps;
+    PictFormatPtr		    pFormat;
+    int				    nformat;
+    int				    ndepth;
+    int				    nvisual;
+    int				    rlength;
+    int				    s;
+    int				    n;
+    int				    numScreens;
+    int				    numSubpixel;
+
+    extern int                      nxagentAlphaEnabled;
+/*    REQUEST(xRenderQueryPictFormatsReq); */
+
+    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+    numScreens = screenInfo.numScreens;
+#endif
+    ndepth = nformat = nvisual = 0;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pDepth = pScreen->allowedDepths + d;
+	    ++ndepth;
+
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+		    ++nvisual;
+	    }
+	}
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    nformat += ps->nformats;
+    }
+    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+	numSubpixel = 0;
+    else
+	numSubpixel = numScreens;
+    
+    rlength = (sizeof (xRenderQueryPictFormatsReply) +
+	       nformat * sizeof (xPictFormInfo) +
+	       numScreens * sizeof (xPictScreen) +
+	       ndepth * sizeof (xPictDepth) +
+	       nvisual * sizeof (xPictVisual) +
+	       numSubpixel * sizeof (CARD32));
+    reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numFormats = nformat;
+    reply->numScreens = numScreens;
+    reply->numDepths = ndepth;
+    reply->numVisuals = nvisual;
+    reply->numSubpixel = numSubpixel;
+    
+    pictForm = (xPictFormInfo *) (reply + 1);
+    
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	{
+	    for (nformat = 0, pFormat = ps->formats; 
+		 nformat < ps->nformats;
+		 nformat++, pFormat++)
+	    {
+		pictForm->id = pFormat->id;
+		pictForm->type = pFormat->type;
+		pictForm->depth = pFormat->depth;
+		pictForm->direct.red = pFormat->direct.red;
+		pictForm->direct.redMask = pFormat->direct.redMask;
+		pictForm->direct.green = pFormat->direct.green;
+		pictForm->direct.greenMask = pFormat->direct.greenMask;
+		pictForm->direct.blue = pFormat->direct.blue;
+		pictForm->direct.blueMask = pFormat->direct.blueMask;
+		pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+		    pictForm->colormap = pFormat->index.pColormap->mid;
+		else
+		    pictForm->colormap = None;
+		if (client->swapped)
+		{
+		    swapl (&pictForm->id, n);
+		    swaps (&pictForm->direct.red, n);
+		    swaps (&pictForm->direct.redMask, n);
+		    swaps (&pictForm->direct.green, n);
+		    swaps (&pictForm->direct.greenMask, n);
+		    swaps (&pictForm->direct.blue, n);
+		    swaps (&pictForm->direct.blueMask, n);
+		    swaps (&pictForm->direct.alpha, n);
+		    swaps (&pictForm->direct.alphaMask, n);
+		    swapl (&pictForm->colormap, n);
+		}
+		pictForm++;
+	    }
+	}
+    }
+    
+    pictScreen = (xPictScreen *) pictForm;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	pictDepth = (xPictDepth *) (pictScreen + 1);
+	ndepth = 0;
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pictVisual = (xPictVisual *) (pictDepth + 1);
+	    pDepth = pScreen->allowedDepths + d;
+
+	    nvisual = 0;
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && (pFormat = PictureMatchVisual (pScreen, 
+							      pDepth->depth, 
+							      pVisual)))
+		{
+		    pictVisual->visual = pVisual->vid;
+		    pictVisual->format = pFormat->id;
+		    if (client->swapped)
+		    {
+			swapl (&pictVisual->visual, n);
+			swapl (&pictVisual->format, n);
+		    }
+		    pictVisual++;
+		    nvisual++;
+		}
+	    }
+	    pictDepth->depth = pDepth->depth;
+	    pictDepth->nPictVisuals = nvisual;
+	    if (client->swapped)
+	    {
+		swaps (&pictDepth->nPictVisuals, n);
+	    }
+	    ndepth++;
+	    pictDepth = (xPictDepth *) pictVisual;
+	}
+	pictScreen->nDepth = ndepth;
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    pictScreen->fallback = ps->fallback->id;
+	else
+	    pictScreen->fallback = 0;
+	if (client->swapped)
+	{
+	    swapl (&pictScreen->nDepth, n);
+	    swapl (&pictScreen->fallback, n);
+	}
+	pictScreen = (xPictScreen *) pictDepth;
+    }
+    pictSubpixel = (CARD32 *) pictScreen;
+    
+    for (s = 0; s < numSubpixel; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    *pictSubpixel = ps->subpixel;
+	else
+	    *pictSubpixel = SubPixelUnknown;
+	if (client->swapped)
+	{
+	    swapl (pictSubpixel, n);
+	}
+	++pictSubpixel;
+    }
+    
+    if (client->swapped)
+    {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numFormats, n);
+	swapl (&reply->numScreens, n);
+	swapl (&reply->numDepths, n);
+	swapl (&reply->numVisuals, n);
+	swapl (&reply->numSubpixel, n);
+    }
+    WriteToClient(client, rlength, (char *) reply);
+    xfree (reply);
+    return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    PictFormatPtr   pFormat;
+    int		    num;
+    int		    rlength;
+    int		    i, n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    xRenderQueryPictIndexValuesReply *reply;
+    xIndexValue	    *values;
+
+    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->type != PictTypeIndexed)
+    {
+	client->errorValue = stuff->format;
+	return BadMatch;
+    }
+    num = pFormat->index.nvalues;
+    rlength = (sizeof (xRenderQueryPictIndexValuesReply) + 
+	       num * sizeof(xIndexValue));
+    reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numIndexValues = num;
+
+    values = (xIndexValue *) (reply + 1);
+    
+    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+    
+    if (client->swapped)
+    {
+	for (i = 0; i < num; i++)
+	{
+	    swapl (&values[i].pixel, n);
+	    swaps (&values[i].red, n);
+	    swaps (&values[i].green, n);
+	    swaps (&values[i].blue, n);
+	    swaps (&values[i].alpha, n);
+	}
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numIndexValues, n);
+    }
+
+    WriteToClient(client, rlength, (char *) reply);
+    xfree(reply);
+    return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    int		    len;
+    int		    error;
+    REQUEST(xRenderCreatePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+			     SecurityWriteAccess);
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->depth != pDrawable->depth)
+	return BadMatch;
+    len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    pPicture = CreatePicture (stuff->pid,
+			      pDrawable,
+			      pFormat,
+			      stuff->mask,
+			      (XID *) (stuff + 1),
+			      client,
+			      &error);
+    if (!pPicture)
+	return error;
+    nxagentCreatePicture(pPicture, stuff -> mask);
+
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    REQUEST(xRenderChangePictureReq);
+    int len;
+    int error;
+
+    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+			  (DevUnion *) 0, client);
+    
+    nxagentChangePicture(pPicture, stuff->mask);
+
+    return error;
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    PicturePtr	    pPicture;
+    int		    nr;
+    int		    result;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    /*
+     * The original code used sizeof(xRenderChangePictureReq).
+     * This was harmless, as both structures have the same size.
+     *
+     * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+     */
+    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+    if (nr & 4)
+	return BadLength;
+    nr >>= 3;
+    result = SetPictureClipRects (pPicture, 
+				  stuff->xOrigin, stuff->yOrigin,
+				  nr, (xRectangle *) &stuff[1]);
+    nxagentChangePictureClip (pPicture,
+                              CT_NONE,
+                              nr,
+                              (xRectangle *) &stuff[1],
+                              (int)stuff -> xOrigin,
+                              (int)stuff -> yOrigin);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+    PicturePtr	pPicture;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+		    RenderErrBase + BadPicture);
+
+    nxagentDestroyPicture(pPicture);
+
+    FreeResource (stuff->picture, RT_NONE);
+    return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+	return TRUE;
+    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+	return TRUE;
+    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Check if both pictures have drawables which are
+ * virtual pixmaps. See the corresponding define
+ * in NXpicture.c
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#define nxagentCompositePredicate(pSrc, pDst)  TRUE
+
+#else
+
+/*
+ * This is still under development. The final
+ * goal is to let pictures point to the real
+ * pixmaps instead of pointing to virtuals.
+ */
+
+int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
+{
+  PixmapPtr pPixmap1;
+  PixmapPtr pPixmap2;
+
+  pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pSrc -> pDrawable) : NULL);
+
+  pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pDst -> pDrawable) : NULL);
+
+  if (pPixmap1 == NULL || pPixmap2 == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
+    #endif
+
+    return FALSE;
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
+    #endif
+
+    if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
+            nxagentPixmapIsVirtual(pPixmap2) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
+      #endif
+
+      return TRUE;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
+  #endif
+
+  return FALSE;
+}
+
+#endif
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+    PicturePtr	pSrc, pMask, pDst;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
+		  RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen ||
+	(pMask && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
+
+    ValidatePicture (pSrc);
+    if (pMask)
+        ValidatePicture (pMask);
+    ValidatePicture (pDst);
+
+    #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+    if (nxagentCompositePredicate(pSrc, pDst))
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pMask, (void *) pDst);
+      #endif
+
+    CompositePicture (stuff->op,
+		      pSrc,
+		      pMask,
+		      pDst,
+		      stuff->xSrc,
+		      stuff->ySrc,
+		      stuff->xMask,
+		      stuff->yMask,
+		      stuff->xDst,
+		      stuff->yDst,
+		      stuff->width,
+		      stuff->height);
+    }
+
+    #else
+
+    if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+            pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
+    {
+      PixmapPtr pVirtualPixmapSrc;
+      PixmapPtr pVirtualPixmapDst;
+      PixmapPtr pVirtualPixmapMask;
+
+      PicturePtr pVirtualPictureSrc;
+      PicturePtr pVirtualPictureDst;
+      PicturePtr pVirtualPictureMask;
+
+      pVirtualPixmapSrc  = (PixmapPtr) pSrc  -> pDrawable;
+      pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
+
+      pVirtualPixmapDst  = (PixmapPtr) pDst  -> pDrawable;
+      pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
+
+      if (pMask)
+      {
+        pVirtualPixmapMask  = (PixmapPtr) pMask  -> pDrawable;
+        pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
+      }
+      else
+      {
+        pVirtualPixmapMask  = NULL;
+        pVirtualPictureMask = NULL;
+      }
+
+      if (pVirtualPictureSrc && pVirtualPictureDst)
+      {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
+                          (void *) pVirtualPixmapDst);
+      #endif
+
+      CompositePicture (stuff->op,
+                        pVirtualPictureSrc,
+                        pVirtualPictureMask,
+                        pVirtualPictureDst,
+                        stuff->xSrc,
+                        stuff->ySrc,
+                        stuff->xMask,
+                        stuff->yMask,
+                        stuff->xDst,
+                        stuff->yDst,
+                        stuff->width,
+                        stuff->height);
+      }
+    }
+
+    #endif
+
+    nxagentComposite (stuff -> op,
+                      pSrc,
+                      pMask,
+                      pDst,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      stuff -> xMask,
+                      stuff -> yMask,
+                      stuff -> xDst,
+                      stuff -> yDst,
+                      stuff -> width,
+                      stuff -> height);
+
+    return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+    if (ntraps % sizeof (xTrapezoid))
+	return BadLength;
+    ntraps /= sizeof (xTrapezoid);
+    if (ntraps)
+    {
+        if (nxagentCompositePredicate(pSrc, pDst))
+        {
+	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+			     stuff->xSrc, stuff->ySrc,
+			     ntraps, (xTrapezoid *) &stuff[1]);
+        }
+
+        nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
+                             stuff->xSrc, stuff->ySrc,
+                             ntraps, (xTrapezoid *) &stuff[1]);
+    }
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+    int		ntris;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+    if (ntris % sizeof (xTriangle))
+	return BadLength;
+    ntris /= sizeof (xTriangle);
+    if (ntris)
+	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+			    stuff->xSrc, stuff->ySrc,
+			    ntris, (xTriangle *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+			   stuff->xSrc, stuff->ySrc,
+			   npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+			 stuff->xSrc, stuff->ySrc,
+			 npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr	    glyphSet;
+    PictFormatPtr   format;
+    int		    f;
+    REQUEST(xRenderCreateGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+    format = (PictFormatPtr) SecurityLookupIDByType (client,
+						     stuff->format,
+						     PictFormatType,
+						     SecurityReadAccess);
+    if (!format)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    switch (format->depth) {
+    case 1:
+	f = GlyphFormat1;
+	break;
+    case 4:
+	f = GlyphFormat4;
+	break;
+    case 8:
+	f = GlyphFormat8;
+	break;
+    case 16:
+	f = GlyphFormat16;
+	break;
+    case 32:
+	f = GlyphFormat32;
+	break;
+    default:
+	return BadMatch;
+    }
+    if (format->type != PictTypeDirect)
+	return BadMatch;
+    glyphSet = AllocateGlyphSet (f, format);
+    if (!glyphSet)
+	return BadAlloc;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+
+    nxagentCreateGlyphSet(glyphSet);
+
+    return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderReferenceGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->existing,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->existing;
+	return RenderErrBase + BadGlyphSet;
+    }
+    glyphSet->refcnt++;
+
+    nxagentReferenceGlyphSet(glyphSet);
+
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return client->noClientException;
+}
+
+#define NLOCALDELTA	64
+#define NLOCALGLYPH	256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderFreeGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityDestroyAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nxagentFreeGlyphSet(glyphSet);
+
+    FreeResource (stuff->glyphset, RT_NONE);
+    return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+    Glyph	id;
+    GlyphPtr    glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderAddGlyphsReq);
+    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
+    GlyphNewPtr	    glyphsBase, glyphs;
+    GlyphPtr	    glyph = NULL;
+    int		    remain, nglyphs;
+    CARD32	    *gids;
+    xGlyphInfo	    *gi;
+    CARD8	    *bits;
+    int		    size;
+    int		    err = BadAlloc;
+
+    int             totSizeImages;
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nglyphs = stuff->nglyphs;
+    if (nglyphs <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphNewPtr) ALLOCATE_LOCAL (nglyphs * sizeof (GlyphNewRec));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+
+    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+    glyphs = glyphsBase;
+
+    totSizeImages = 0;
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + nglyphs);
+    bits = (CARD8 *) (gi + nglyphs);
+    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+
+    while (remain >= 0 && nglyphs)
+    {
+	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+	if (!glyph)
+	{
+	    err = BadAlloc;
+	    goto bail;
+	}
+	
+	glyphs->glyph = glyph;
+	glyphs->id = *gids;	
+	
+	size = glyph->size - sizeof (xGlyphInfo);
+	if (remain < size)
+	    break;
+	memcpy ((CARD8 *) (glyph + 1), bits, size);
+	
+	if (size & 3)
+	    size += 4 - (size & 3);
+	bits += size;
+	totSizeImages += size;
+	remain -= size;
+	gi++;
+	gids++;
+	glyphs++;
+	nglyphs--;
+    }
+
+    if (nglyphs || remain)
+    {
+	err = BadLength;
+	goto bail;
+    }
+    nglyphs = stuff->nglyphs;
+    if (!ResizeGlyphSet (glyphSet, nglyphs))
+    {
+	err = BadAlloc;
+	goto bail;
+    }
+    glyphs = glyphsBase;
+    while (nglyphs--)
+	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    return client->noClientException;
+bail:
+    while (glyphs != glyphsBase)
+    {
+	--glyphs;
+	xfree (glyphs->glyph);
+    }
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+    REQUEST(xRenderFreeGlyphsReq);
+    GlyphSetPtr     glyphSet;
+    int		    nglyph;
+    CARD32	    *gids;
+    CARD32	    glyph;
+
+    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+    gids = (CARD32 *) (stuff + 1);
+
+    nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
+    while (nglyph-- > 0)
+    {
+	glyph = *gids++;
+	if (!DeleteGlyph (glyphSet, glyph))
+	{
+	    client->errorValue = glyph;
+	    return RenderErrBase + BadGlyph;
+	}
+    }
+    return client->noClientException;
+}
+
+typedef struct XGlyphElt8{
+    GlyphSet                glyphset;
+    _Xconst char            *chars;
+    int                     nchars;
+    int                     xOff;
+    int                     yOff;
+} XGlyphElt8;
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    GlyphSet	    gs;
+    PicturePtr      pSrc, pDst;
+    PictFormatPtr   pFormat;
+    GlyphListRec    listsLocal[NLOCALDELTA];
+    GlyphListPtr    lists, listsBase;
+    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
+    Glyph	    glyph;
+    GlyphPtr	    *glyphs, *glyphsBase;
+    xGlyphElt	    *elt;
+    CARD8	    *buffer, *end;
+    int		    nglyph;
+    int		    nlist;
+    int		    space;
+    int		    size;
+    int		    n;
+    
+    XGlyphElt8      *elements, *elementsBase;
+
+    REQUEST(xRenderCompositeGlyphsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityReadAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    nglyph = 0;
+    nlist = 0;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    buffer += 4;
+	}
+	else
+	{
+	    nlist++;
+	    nglyph += elt->len;
+	    space = size * elt->len;
+	    if (space & 3)
+		space += 4 - (space & 3);
+	    buffer += space;
+	}
+    }
+    if (nglyph <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+    if (nlist <= NLOCALDELTA)
+	listsBase = listsLocal;
+    else
+    {
+	listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+	if (!listsBase)
+	    return BadAlloc;
+    }
+
+    elementsBase = xalloc(nlist * sizeof(XGlyphElt8));
+    if (!elementsBase)
+      return BadAlloc;
+
+    buffer = (CARD8 *) (stuff + 1);
+    glyphs = glyphsBase;
+    lists = listsBase;
+    elements = elementsBase;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+            #ifdef DEBUG
+            fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+                        size);
+            #endif
+
+	    if (buffer + sizeof (GlyphSet) < end)
+	    {
+		gs = *(GlyphSet *) buffer;
+		glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+								 gs,
+								 GlyphSetType,
+								 SecurityReadAccess);
+		if (!glyphSet)
+		{
+		    client->errorValue = gs;
+		    if (glyphsBase != glyphsLocal)
+			DEALLOCATE_LOCAL (glyphsBase);
+		    if (listsBase != listsLocal)
+			DEALLOCATE_LOCAL (listsBase);
+		    return RenderErrBase + BadGlyphSet;
+		}
+	    }
+	    buffer += 4;
+	}
+	else
+	{
+	    lists->xOff = elt->deltax;
+	    lists->yOff = elt->deltay;
+	    lists->format = glyphSet->format;
+	    lists->len = 0;
+            elements -> glyphset = glyphSet -> remoteID;
+            elements -> chars = (char *) buffer;
+            elements -> nchars = elt->len;
+            elements -> xOff = elt->deltax;
+            elements -> yOff = elt->deltay;
+	    n = elt->len;
+	    while (n--)
+	    {
+		if (buffer + size <= end)
+		{
+		    switch (size) {
+		    case 1:
+			glyph = *((CARD8 *)buffer); break;
+		    case 2:
+			glyph = *((CARD16 *)buffer); break;
+		    case 4:
+		    default:
+			glyph = *((CARD32 *)buffer); break;
+		    }
+		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
+		    {
+			lists->len++;
+			glyphs++;
+		    }
+		}
+		buffer += size;
+	    }
+	    space = size * elt->len;
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	    lists++;
+            elements++;
+	}
+    }
+    if (buffer > end)
+	return BadLength;
+
+    /*
+     * We need to know the glyphs extents to synchronize
+     * the drawables involved in the composite text ope-
+     * ration. Also we need to synchronize only the back-
+     * ground of the text we are going to render, so the
+     * operations on the framebuffer must be executed
+     * after the X requests.
+     */
+
+    if (pFormat != NULL)
+    {
+      nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+      miGlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
+    }
+
+    nxagentGlyphs(stuff -> op,
+                  pSrc,
+                  pDst,
+                  pFormat,
+                  stuff -> xSrc,
+                  stuff -> ySrc,
+                  nlist,
+                  elementsBase,
+                  size,
+                  glyphsBase);
+
+    if (nxagentCompositePredicate(pSrc, pDst) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
+                  "source at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pDst);
+      #endif
+
+      CompositeGlyphs(stuff -> op,
+                      pSrc,
+                      pDst,
+                      pFormat,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      nlist,
+                      listsBase,
+                      glyphsBase);
+    }
+
+    if (nxagentGlyphsExtents != NullBox)
+    {
+      xfree(nxagentGlyphsExtents);
+
+      nxagentGlyphsExtents = NullBox;
+    }
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    if (listsBase != listsLocal)
+	DEALLOCATE_LOCAL (listsBase);
+    
+    xfree(elementsBase);
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+    PicturePtr	    pDst;
+    int             things;
+    REQUEST(xRenderFillRectanglesReq);
+    
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    
+    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+    
+    CompositeRects (stuff->op,
+		    pDst,
+		    &stuff->color,
+		    things,
+		    (xRectangle *) &stuff[1]);
+
+    ValidatePicture (pDst);
+    nxagentCompositeRects(stuff -> op,
+                          pDst,
+                          &stuff -> color,
+                          things,
+                          (xRectangle *) &stuff[1]);
+    
+    return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+    unsigned char   mask;
+    
+    if (screenInfo.bitmapBitOrder == LSBFirst)
+	mask = (1 << (x & 7));
+    else
+	mask = (0x80 >> (x & 7));
+    /* XXX assumes byte order is host byte order */
+    line += (x >> 3);
+    if (bit)
+	*line |= mask;
+    else
+	*line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+    {  1,  3,  },
+    {  4,  2,  },
+};
+
+#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateCursorReq);
+    PicturePtr	    pSrc;
+    ScreenPtr	    pScreen;
+    unsigned short  width, height;
+    CARD32	    *argbbits, *argb;
+    unsigned char   *srcbits, *srcline;
+    unsigned char   *mskbits, *mskline;
+    int		    stride;
+    int		    x, y;
+    int		    nbytes_mono;
+    CursorMetricRec cm;
+    CursorPtr	    pCursor;
+    CARD32	    twocolor[3];
+    int		    ncolor;
+
+    RealizeCursorProcPtr saveRealizeCursor;
+
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    pScreen = pSrc->pDrawable->pScreen;
+    width = pSrc->pDrawable->width;
+    height = pSrc->pDrawable->height;
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+    argbbits = xalloc (width * height * sizeof (CARD32));
+    if (!argbbits)
+	return (BadAlloc);
+    
+    stride = BitmapBytePad(width);
+    nbytes_mono = stride*height;
+    srcbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!srcbits)
+    {
+	xfree (argbbits);
+	return (BadAlloc);
+    }
+    mskbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!mskbits)
+    {
+	xfree(argbbits);
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+    bzero ((char *) mskbits, nbytes_mono);
+    bzero ((char *) srcbits, nbytes_mono);
+
+    if (pSrc->format == PICT_a8r8g8b8)
+    {
+	(*pScreen->GetImage) (pSrc->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+    }
+    else
+    {
+	PixmapPtr	pPixmap;
+	PicturePtr	pPicture;
+	PictFormatPtr	pFormat;
+	int		error;
+
+	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+	if (!pFormat)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadImplementation);
+	}
+	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+	if (!pPixmap)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadAlloc);
+	}
+	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, 
+				  client, &error);
+	if (!pPicture)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return error;
+	}
+	(*pScreen->DestroyPixmap) (pPixmap);
+	CompositePicture (PictOpSrc,
+			  pSrc, 0, pPicture,
+			  0, 0, 0, 0, 0, 0, width, height);
+	(*pScreen->GetImage) (pPicture->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+	FreePicture (pPicture, 0);
+    }
+    /*
+     * Check whether the cursor can be directly supported by 
+     * the core cursor code
+     */
+    ncolor = 0;
+    argb = argbbits;
+    for (y = 0; ncolor <= 2 && y < height; y++)
+    {
+	for (x = 0; ncolor <= 2 && x < width; x++)
+	{
+	    CARD32  p = *argb++;
+	    CARD32  a = (p >> 24);
+
+	    if (a == 0)	    /* transparent */
+		continue;
+	    if (a == 0xff)  /* opaque */
+	    {
+		int n;
+		for (n = 0; n < ncolor; n++)
+		    if (p == twocolor[n])
+			break;
+		if (n == ncolor)
+		    twocolor[ncolor++] = p;
+	    }
+	    else
+		ncolor = 3;
+	}
+    }
+    
+    /*
+     * Convert argb image to two plane cursor
+     */
+    srcline = srcbits;
+    mskline = mskbits;
+    argb = argbbits;
+    for (y = 0; y < height; y++)
+    {
+	for (x = 0; x < width; x++)
+	{
+	    CARD32  p = *argb++;
+
+	    if (ncolor <= 2)
+	    {
+		CARD32	a = ((p >> 24));
+
+		SetBit (mskline, x, a != 0);
+		SetBit (srcline, x, a != 0 && p == twocolor[0]);
+	    }
+	    else
+	    {
+		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+		/* Set mask from dithered alpha value */
+		SetBit(mskline, x, a > d);
+		/* Set src from dithered intensity value */
+		SetBit(srcline, x, a > d && i <= d);
+	    }
+	}
+	srcline += stride;
+	mskline += stride;
+    }
+    /*
+     * Dither to white and black if the cursor has more than two colors
+     */
+    if (ncolor > 2)
+    {
+	twocolor[0] = 0xff000000;
+	twocolor[1] = 0xffffffff;
+    }
+    else
+    {
+	xfree (argbbits);
+	argbbits = 0;
+    }
+    
+#define GetByte(p,s)	(((p) >> (s)) & 0xff)
+#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
+    
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+
+    /*
+     * This cursor uses RENDER, so we make sure
+     * that it is allocated in a way that allows
+     * the mi and dix layers to handle it but we
+     * later create it on the server by mirror-
+     * ing the RENDER operation we got from the
+     * client.
+     */
+
+    saveRealizeCursor = pScreen -> RealizeCursor;
+
+    pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
+
+    pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+			       GetColor(twocolor[0], 16),
+			       GetColor(twocolor[0], 8),
+			       GetColor(twocolor[0], 0),
+			       GetColor(twocolor[1], 16),
+			       GetColor(twocolor[1], 8),
+			       GetColor(twocolor[1], 0));
+
+    pScreen -> RealizeCursor = saveRealizeCursor;
+
+    /*
+     * Store into the private data members the
+     * information needed to recreate it at
+     * reconnection. This is done in two steps
+     * as in the first step we don't have the
+     * picture info.
+     */
+
+    if (pCursor == NULL)
+    {
+      return BadAlloc;
+    }
+
+    nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
+
+    nxagentRenderRealizeCursor(pScreen, pCursor);
+
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return (client->noClientException);
+    return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    PicturePtr	pPicture;
+    int		result;
+
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+
+    nxagentSetPictureTransform(pPicture, &stuff->transform);
+    
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+    REQUEST (xRenderQueryFiltersReq);
+    DrawablePtr			pDrawable;
+    xRenderQueryFiltersReply	*reply;
+    int				nbytesName;
+    int				nnames;
+    ScreenPtr			pScreen;
+    PictureScreenPtr		ps;
+    int				i, j;
+    int				len;
+    int				total_bytes;
+    INT16			*aliases;
+    char			*names;
+
+    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+    
+    pScreen = pDrawable->pScreen;
+    nbytesName = 0;
+    nnames = 0;
+    ps = GetPictureScreenIfSet(pScreen);
+    if (ps)
+    {
+	for (i = 0; i < ps->nfilters; i++)
+	    nbytesName += 1 + strlen (ps->filters[i].name);
+	for (i = 0; i < ps->nfilterAliases; i++)
+	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+	nnames = ps->nfilters + ps->nfilterAliases;
+    }
+    len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+    reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+    if (!reply)
+	return BadAlloc;
+    aliases = (INT16 *) (reply + 1);
+    names = (char *) (aliases + ((nnames + 1) & ~1));
+    
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = len;
+    reply->numAliases = nnames;
+    reply->numFilters = nnames;
+    if (ps)
+    {
+
+	/* fill in alias values */
+	for (i = 0; i < ps->nfilters; i++)
+	    aliases[i] = FilterAliasNone;
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    for (j = 0; j < ps->nfilters; j++)
+		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+		    break;
+	    if (j == ps->nfilters)
+	    {
+		for (j = 0; j < ps->nfilterAliases; j++)
+		    if (ps->filterAliases[i].filter_id == 
+			ps->filterAliases[j].alias_id)
+		    {
+			break;
+		    }
+		if (j == ps->nfilterAliases)
+		    j = FilterAliasNone;
+		else
+		    j = j + ps->nfilters;
+	    }
+	    aliases[i + ps->nfilters] = j;
+	}
+
+	/* fill in filter names */
+	for (i = 0; i < ps->nfilters; i++)
+	{
+	    j = strlen (ps->filters[i].name);
+	    *names++ = j;
+	    strncpy (names, ps->filters[i].name, j);
+	    names += j;
+	}
+	
+	/* fill in filter alias names */
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    j = strlen (ps->filterAliases[i].alias);
+	    *names++ = j;
+	    strncpy (names, ps->filterAliases[i].alias, j);
+	    names += j;
+	}
+    }
+
+    if (client->swapped)
+    {
+	register int n;
+
+	for (i = 0; i < (int)reply->numAliases; i++)
+	{
+	    swaps (&aliases[i], n);
+	}
+    	swaps(&reply->sequenceNumber, n);
+    	swapl(&reply->length, n);
+	swapl(&reply->numAliases, n);
+	swapl(&reply->numFilters, n);
+    }
+    WriteToClient(client, total_bytes, (char *) reply);
+    xfree (reply);
+    
+    return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST (xRenderSetPictureFilterReq);
+    PicturePtr	pPicture;
+    int		result;
+    xFixed	*params;
+    int		nparams;
+    char	*name;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    name = (char *) (stuff + 1);
+    params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+
+    nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
+
+    return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateAnimCursorReq);
+    CursorPtr	    *cursors;
+    CARD32	    *deltas;
+    CursorPtr	    pCursor;
+    int		    ncursor;
+    xAnimCursorElt  *elt;
+    int		    i;
+    int		    ret;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    if (client->req_len & 1)
+	return BadLength;
+    ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+    cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+    if (!cursors)
+	return BadAlloc;
+    deltas = (CARD32 *) (cursors + ncursor);
+    elt = (xAnimCursorElt *) (stuff + 1);
+    for (i = 0; i < ncursor; i++)
+    {
+	cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+						       RT_CURSOR, SecurityReadAccess);
+	if (!cursors[i])
+	{
+	    xfree (cursors);
+	    client->errorValue = elt->cursor;
+	    return BadCursor;
+	}
+	deltas[i] = elt->delay;
+	elt++;
+    }
+    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+    xfree (cursors);
+    if (ret != Success)
+	return ret;
+    
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+      pCursor -> devPriv[i] = NULL;
+    }
+
+    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*ProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->majorVersion, n);
+    swapl(&stuff->minorVersion, n);
+    return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictFormatsReq);
+    swaps(&stuff->length, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreatePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->format, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderChangePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCompositeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->mask, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xMask, n);
+    swaps(&stuff->yMask, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderScaleReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->colorScale, n);
+    swapl(&stuff->alphaScale, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriStripReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriFanReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderReferenceGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->existing, n);
+    return (*ProcRenderVector[stuff->renderReqType])  (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+    register int n;
+    register unsigned int i;
+    CARD32  *gids;
+    void    *end;
+    xGlyphInfo *gi;
+    REQUEST(xRenderAddGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    swapl(&stuff->nglyphs, n);
+    if (stuff->nglyphs & 0xe0000000)
+	return BadLength;
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+	return BadLength;
+    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+	return BadLength;
+    for (i = 0; i < stuff->nglyphs; i++)
+    {
+	swapl (&gids[i], n);
+	swaps (&gi[i].width, n);
+	swaps (&gi[i].height, n);
+	swaps (&gi[i].x, n);
+	swaps (&gi[i].y, n);
+	swaps (&gi[i].xOff, n);
+	swaps (&gi[i].yOff, n);
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+    register int n;
+    xGlyphElt	*elt;
+    CARD8	*buffer;
+    CARD8	*end;
+    int		space;
+    int		i;
+    int		size;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+    
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->maskFormat, n);
+    swapl(&stuff->glyphset, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	swaps (&elt->deltax, n);
+	swaps (&elt->deltay, n);
+	
+	i = elt->len;
+	if (i == 0xff)
+	{
+	    swapl (buffer, n);
+	    buffer += 4;
+	}
+	else
+	{
+	    space = size * i;
+	    switch (size) {
+	    case 1:
+		buffer += i;
+		break;
+	    case 2:
+		while (i--)
+		{
+		    swaps (buffer, n);
+		    buffer += 2;
+		}
+		break;
+	    case 4:
+		while (i--)
+		{
+		    swapl (buffer, n);
+		    buffer += 4;
+		}
+		break;
+	    }
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	}
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFillRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    swaps(&stuff->color.alpha, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateCursorReq);
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    swapl(&stuff->src, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureTransformReq);
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->transform.matrix11, n);
+    swapl(&stuff->transform.matrix12, n);
+    swapl(&stuff->transform.matrix13, n);
+    swapl(&stuff->transform.matrix21, n);
+    swapl(&stuff->transform.matrix22, n);
+    swapl(&stuff->transform.matrix23, n);
+    swapl(&stuff->transform.matrix31, n);
+    swapl(&stuff->transform.matrix32, n);
+    swapl(&stuff->transform.matrix33, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderQueryFiltersReq);
+    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderSetPictureFilterReq);
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->nbytes, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateAnimCursorReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+    
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*SProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+int	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long	XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+    REQUEST(xRenderCreatePictureReq);
+    PanoramiXRes    *refDraw, *newPict;
+    int		    result = Success, j;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+    if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+    if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+    newPict->type = XRT_PICTURE;
+    newPict->info[0].id = stuff->pid;
+    
+    if (refDraw->type == XRT_WINDOW &&
+	stuff->drawable == WindowTable[0]->drawable.id)
+    {
+	newPict->u.pict.root = TRUE;
+    }
+    else
+	newPict->u.pict.root = FALSE;
+
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPict->info[j].id = FakeClientID(client->index);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->pid = newPict->info[j].id;
+	stuff->drawable = refDraw->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+	if(result != Success) break;
+    }
+
+    if (result == Success)
+	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+    else 
+	xfree(newPict);
+
+    return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+    PanoramiXRes    *pict;
+    int		    result = Success, j;
+    REQUEST(xRenderChangePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+    PanoramiXRes *pict;
+    int         result = Success, j;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    client->errorValue = stuff->picture;
+
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+		       RenderErrBase + BadPicture);
+    
+
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->picture = pict->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+	if(result != Success) break;
+    }
+
+    /* Since ProcRenderFreePicture is using FreeResource, it will free
+	our resource for us on the last pass through the loop above */
+ 
+    return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+    PanoramiXRes	*src, *msk, *dst;
+    int			result = Success, j;
+    xRenderCompositeReq	orig;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess, 
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess, 
+		      RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    
+    orig = *stuff;
+    
+    FOR_NSCREENS_FORWARD(j) {
+	stuff->src = src->info[j].id;
+	if (src->u.pict.root)
+	{
+	    stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+	    stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+	}
+	stuff->dst = dst->info[j].id;
+	if (dst->u.pict.root)
+	{
+	    stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+	    stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+	}
+	if (msk)
+	{
+	    stuff->mask = msk->info[j].id;
+	    if (msk->u.pict.root)
+	    {
+		stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+		stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+	    }
+	}
+	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+	if(result != Success) break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+    PanoramiXRes    *src, *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderCompositeGlyphsReq);
+    xGlyphElt	    origElt, *elt;
+    INT16	    xSrc, ySrc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+				 sizeof (xGlyphElt)))
+    {
+	elt = (xGlyphElt *) (stuff + 1);
+	origElt = *elt;
+	xSrc = stuff->xSrc;
+	ySrc = stuff->ySrc;
+	FOR_NSCREENS_FORWARD(j) {
+	    stuff->src = src->info[j].id;
+	    if (src->u.pict.root)
+	    {
+		stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+		stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+	    }
+	    stuff->dst = dst->info[j].id;
+	    if (dst->u.pict.root)
+	    {
+		elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+		elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+	    if(result != Success) break;
+	}
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+    PanoramiXRes    *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderFillRectanglesReq);
+    char	    *extra;
+    int		    extra_len;
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root)
+	    {
+		int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+		    xRectangle	*rects = (xRectangle *) (stuff + 1);
+		    int		i = extra_len / sizeof (xRectangle);
+
+		    while (i--)
+		    {
+			rects->x -= x_off;
+			rects->y -= y_off;
+			rects++;
+		    }
+		}
+	    }
+	    stuff->dst = dst->info[j].id;
+	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+    int	    i;
+    
+    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+    for (i = 0; i < RenderNumberRequests; i++)
+	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+    /*
+     * Stuff in Xinerama aware request processing hooks
+     */
+    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+    int	    i;
+    for (i = 0; i < RenderNumberRequests; i++)
+	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif	/* PANORAMIX */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.XF86.original
new file mode 100644
index 000000000..a4f90ea77
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.XF86.original
@@ -0,0 +1,2584 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.26 2003/02/14 18:15:21 dawes Exp $
+ *
+ * Copyright � 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, 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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include "render.h"
+#include "renderproto.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+#include "Xfuncproto.h"
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    ProcRenderQueryVersion,
+    ProcRenderQueryPictFormats,
+    ProcRenderQueryPictIndexValues,
+    ProcRenderQueryDithers,
+    ProcRenderCreatePicture,
+    ProcRenderChangePicture,
+    ProcRenderSetPictureClipRectangles,
+    ProcRenderFreePicture,
+    ProcRenderComposite,
+    ProcRenderScale,
+    ProcRenderTrapezoids,
+    ProcRenderTriangles,
+    ProcRenderTriStrip,
+    ProcRenderTriFan,
+    ProcRenderColorTrapezoids,
+    ProcRenderColorTriangles,
+    ProcRenderTransform,
+    ProcRenderCreateGlyphSet,
+    ProcRenderReferenceGlyphSet,
+    ProcRenderFreeGlyphSet,
+    ProcRenderAddGlyphs,
+    ProcRenderAddGlyphsFromPicture,
+    ProcRenderFreeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderFillRectangles,
+    ProcRenderCreateCursor,
+    ProcRenderSetPictureTransform,
+    ProcRenderQueryFilters,
+    ProcRenderSetPictureFilter,
+    ProcRenderCreateAnimCursor,
+};
+
+int	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    SProcRenderQueryVersion,
+    SProcRenderQueryPictFormats,
+    SProcRenderQueryPictIndexValues,
+    SProcRenderQueryDithers,
+    SProcRenderCreatePicture,
+    SProcRenderChangePicture,
+    SProcRenderSetPictureClipRectangles,
+    SProcRenderFreePicture,
+    SProcRenderComposite,
+    SProcRenderScale,
+    SProcRenderTrapezoids,
+    SProcRenderTriangles,
+    SProcRenderTriStrip,
+    SProcRenderTriFan,
+    SProcRenderColorTrapezoids,
+    SProcRenderColorTriangles,
+    SProcRenderTransform,
+    SProcRenderCreateGlyphSet,
+    SProcRenderReferenceGlyphSet,
+    SProcRenderFreeGlyphSet,
+    SProcRenderAddGlyphs,
+    SProcRenderAddGlyphsFromPicture,
+    SProcRenderFreeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderFillRectangles,
+    SProcRenderCreateCursor,
+    SProcRenderSetPictureTransform,
+    SProcRenderQueryFilters,
+    SProcRenderSetPictureFilter,
+    SProcRenderCreateAnimCursor,
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+    
+static CARD8	RenderReqCode;
+int	RenderErrBase;
+int	RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+    int	    major_version;
+    int	    minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient)    ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr	*list,
+		      pointer		closure,
+		      pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
+
+    pRenderClient->major_version = 0;
+    pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+    ExtensionEntry *extEntry;
+
+    if (!PictureType)
+	return;
+    if (!PictureFinishInit ())
+	return;
+    RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+    if (!AllocateClientPrivate (RenderClientPrivateIndex, 
+				sizeof (RenderClientRec)))
+	return;
+    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+	return;
+
+    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+			     ProcRenderDispatch, SProcRenderDispatch,
+			     RenderResetProc, StandardMinorOpcode);
+    if (!extEntry)
+	return;
+    RenderReqCode = (CARD8) extEntry->base;
+    RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+    RenderClientPtr pRenderClient = GetRenderClient (client);
+    xRenderQueryVersionReply rep;
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    pRenderClient->major_version = stuff->majorVersion;
+    pRenderClient->minor_version = stuff->minorVersion;
+
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = RENDER_MAJOR;
+    rep.minorVersion = RENDER_MINOR;
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.majorVersion, n);
+	swapl(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    DepthPtr    pDepth;
+    int		d, v;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = pScreen->allowedDepths + d;
+	for (v = 0; v < pDepth->numVids; v++)
+	{
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+	}
+    }
+    return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+    VisualPtr	pVisual;
+    int		v;
+
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = pScreen->visuals + v;
+	if (pVisual->vid == vid)
+	    return pVisual;
+    }
+    return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+    RenderClientPtr		    pRenderClient = GetRenderClient (client);
+    xRenderQueryPictFormatsReply    *reply;
+    xPictScreen			    *pictScreen;
+    xPictDepth			    *pictDepth;
+    xPictVisual			    *pictVisual;
+    xPictFormInfo		    *pictForm;
+    CARD32			    *pictSubpixel;
+    ScreenPtr			    pScreen;
+    VisualPtr			    pVisual;
+    DepthPtr			    pDepth;
+    int				    v, d;
+    PictureScreenPtr		    ps;
+    PictFormatPtr		    pFormat;
+    int				    nformat;
+    int				    ndepth;
+    int				    nvisual;
+    int				    rlength;
+    int				    s;
+    int				    n;
+    int				    numScreens;
+    int				    numSubpixel;
+/*    REQUEST(xRenderQueryPictFormatsReq); */
+
+    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+    numScreens = screenInfo.numScreens;
+#endif
+    ndepth = nformat = nvisual = 0;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pDepth = pScreen->allowedDepths + d;
+	    ++ndepth;
+
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+		    ++nvisual;
+	    }
+	}
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    nformat += ps->nformats;
+    }
+    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+	numSubpixel = 0;
+    else
+	numSubpixel = numScreens;
+    
+    rlength = (sizeof (xRenderQueryPictFormatsReply) +
+	       nformat * sizeof (xPictFormInfo) +
+	       numScreens * sizeof (xPictScreen) +
+	       ndepth * sizeof (xPictDepth) +
+	       nvisual * sizeof (xPictVisual) +
+	       numSubpixel * sizeof (CARD32));
+    reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numFormats = nformat;
+    reply->numScreens = numScreens;
+    reply->numDepths = ndepth;
+    reply->numVisuals = nvisual;
+    reply->numSubpixel = numSubpixel;
+    
+    pictForm = (xPictFormInfo *) (reply + 1);
+    
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	{
+	    for (nformat = 0, pFormat = ps->formats; 
+		 nformat < ps->nformats;
+		 nformat++, pFormat++)
+	    {
+		pictForm->id = pFormat->id;
+		pictForm->type = pFormat->type;
+		pictForm->depth = pFormat->depth;
+		pictForm->direct.red = pFormat->direct.red;
+		pictForm->direct.redMask = pFormat->direct.redMask;
+		pictForm->direct.green = pFormat->direct.green;
+		pictForm->direct.greenMask = pFormat->direct.greenMask;
+		pictForm->direct.blue = pFormat->direct.blue;
+		pictForm->direct.blueMask = pFormat->direct.blueMask;
+		pictForm->direct.alpha = pFormat->direct.alpha;
+		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+		    pictForm->colormap = pFormat->index.pColormap->mid;
+		else
+		    pictForm->colormap = None;
+		if (client->swapped)
+		{
+		    swapl (&pictForm->id, n);
+		    swaps (&pictForm->direct.red, n);
+		    swaps (&pictForm->direct.redMask, n);
+		    swaps (&pictForm->direct.green, n);
+		    swaps (&pictForm->direct.greenMask, n);
+		    swaps (&pictForm->direct.blue, n);
+		    swaps (&pictForm->direct.blueMask, n);
+		    swaps (&pictForm->direct.alpha, n);
+		    swaps (&pictForm->direct.alphaMask, n);
+		    swapl (&pictForm->colormap, n);
+		}
+		pictForm++;
+	    }
+	}
+    }
+    
+    pictScreen = (xPictScreen *) pictForm;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	pictDepth = (xPictDepth *) (pictScreen + 1);
+	ndepth = 0;
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pictVisual = (xPictVisual *) (pictDepth + 1);
+	    pDepth = pScreen->allowedDepths + d;
+
+	    nvisual = 0;
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && (pFormat = PictureMatchVisual (pScreen, 
+							      pDepth->depth, 
+							      pVisual)))
+		{
+		    pictVisual->visual = pVisual->vid;
+		    pictVisual->format = pFormat->id;
+		    if (client->swapped)
+		    {
+			swapl (&pictVisual->visual, n);
+			swapl (&pictVisual->format, n);
+		    }
+		    pictVisual++;
+		    nvisual++;
+		}
+	    }
+	    pictDepth->depth = pDepth->depth;
+	    pictDepth->nPictVisuals = nvisual;
+	    if (client->swapped)
+	    {
+		swaps (&pictDepth->nPictVisuals, n);
+	    }
+	    ndepth++;
+	    pictDepth = (xPictDepth *) pictVisual;
+	}
+	pictScreen->nDepth = ndepth;
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    pictScreen->fallback = ps->fallback->id;
+	else
+	    pictScreen->fallback = 0;
+	if (client->swapped)
+	{
+	    swapl (&pictScreen->nDepth, n);
+	    swapl (&pictScreen->fallback, n);
+	}
+	pictScreen = (xPictScreen *) pictDepth;
+    }
+    pictSubpixel = (CARD32 *) pictScreen;
+    
+    for (s = 0; s < numSubpixel; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    *pictSubpixel = ps->subpixel;
+	else
+	    *pictSubpixel = SubPixelUnknown;
+	if (client->swapped)
+	{
+	    swapl (pictSubpixel, n);
+	}
+	++pictSubpixel;
+    }
+    
+    if (client->swapped)
+    {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numFormats, n);
+	swapl (&reply->numScreens, n);
+	swapl (&reply->numDepths, n);
+	swapl (&reply->numVisuals, n);
+	swapl (&reply->numSubpixel, n);
+    }
+    WriteToClient(client, rlength, (char *) reply);
+    xfree (reply);
+    return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    PictFormatPtr   pFormat;
+    int		    num;
+    int		    rlength;
+    int		    i, n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    xRenderQueryPictIndexValuesReply *reply;
+    xIndexValue	    *values;
+
+    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->type != PictTypeIndexed)
+    {
+	client->errorValue = stuff->format;
+	return BadMatch;
+    }
+    num = pFormat->index.nvalues;
+    rlength = (sizeof (xRenderQueryPictIndexValuesReply) + 
+	       num * sizeof(xIndexValue));
+    reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numIndexValues = num;
+
+    values = (xIndexValue *) (reply + 1);
+    
+    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+    
+    if (client->swapped)
+    {
+	for (i = 0; i < num; i++)
+	{
+	    swapl (&values[i].pixel, n);
+	    swaps (&values[i].red, n);
+	    swaps (&values[i].green, n);
+	    swaps (&values[i].blue, n);
+	    swaps (&values[i].alpha, n);
+	}
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numIndexValues, n);
+    }
+
+    WriteToClient(client, rlength, (char *) reply);
+    xfree(reply);
+    return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    int		    len;
+    int		    error;
+    REQUEST(xRenderCreatePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+			     SecurityWriteAccess);
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->depth != pDrawable->depth)
+	return BadMatch;
+    len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    pPicture = CreatePicture (stuff->pid,
+			      pDrawable,
+			      pFormat,
+			      stuff->mask,
+			      (XID *) (stuff + 1),
+			      client,
+			      &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    REQUEST(xRenderChangePictureReq);
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+			  (DevUnion *) 0, client);
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    PicturePtr	    pPicture;
+    int		    nr;
+    int		    result;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+    if (nr & 4)
+	return BadLength;
+    nr >>= 3;
+    result = SetPictureClipRects (pPicture, 
+				  stuff->xOrigin, stuff->yOrigin,
+				  nr, (xRectangle *) &stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+    PicturePtr	pPicture;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+		    RenderErrBase + BadPicture);
+    FreeResource (stuff->picture, RT_NONE);
+    return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+	return TRUE;
+    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+	return TRUE;
+    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+	return TRUE;
+    return FALSE;
+}
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+    PicturePtr	pSrc, pMask, pDst;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
+		  RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen ||
+	(pMask && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
+    CompositePicture (stuff->op,
+		      pSrc,
+		      pMask,
+		      pDst,
+		      stuff->xSrc,
+		      stuff->ySrc,
+		      stuff->xMask,
+		      stuff->yMask,
+		      stuff->xDst,
+		      stuff->yDst,
+		      stuff->width,
+		      stuff->height);
+    return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+    if (ntraps % sizeof (xTrapezoid))
+	return BadLength;
+    ntraps /= sizeof (xTrapezoid);
+    if (ntraps)
+	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+			     stuff->xSrc, stuff->ySrc,
+			     ntraps, (xTrapezoid *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+    int		ntris;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+    if (ntris % sizeof (xTriangle))
+	return BadLength;
+    ntris /= sizeof (xTriangle);
+    if (ntris)
+	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+			    stuff->xSrc, stuff->ySrc,
+			    ntris, (xTriangle *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+			   stuff->xSrc, stuff->ySrc,
+			   npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+			 stuff->xSrc, stuff->ySrc,
+			 npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr	    glyphSet;
+    PictFormatPtr   format;
+    int		    f;
+    REQUEST(xRenderCreateGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+    format = (PictFormatPtr) SecurityLookupIDByType (client,
+						     stuff->format,
+						     PictFormatType,
+						     SecurityReadAccess);
+    if (!format)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    switch (format->depth) {
+    case 1:
+	f = GlyphFormat1;
+	break;
+    case 4:
+	f = GlyphFormat4;
+	break;
+    case 8:
+	f = GlyphFormat8;
+	break;
+    case 16:
+	f = GlyphFormat16;
+	break;
+    case 32:
+	f = GlyphFormat32;
+	break;
+    default:
+	return BadMatch;
+    }
+    if (format->type != PictTypeDirect)
+	return BadMatch;
+    glyphSet = AllocateGlyphSet (f, format);
+    if (!glyphSet)
+	return BadAlloc;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderReferenceGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->existing,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->existing;
+	return RenderErrBase + BadGlyphSet;
+    }
+    glyphSet->refcnt++;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return client->noClientException;
+}
+
+#define NLOCALDELTA	64
+#define NLOCALGLYPH	256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderFreeGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityDestroyAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    FreeResource (stuff->glyphset, RT_NONE);
+    return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+    Glyph	id;
+    GlyphPtr    glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderAddGlyphsReq);
+    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
+    GlyphNewPtr	    glyphsBase, glyphs;
+    GlyphPtr	    glyph;
+    int		    remain, nglyphs;
+    CARD32	    *gids;
+    xGlyphInfo	    *gi;
+    CARD8	    *bits;
+    int		    size;
+    int		    err = BadAlloc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nglyphs = stuff->nglyphs;
+    if (nglyphs <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphNewPtr) ALLOCATE_LOCAL (nglyphs * sizeof (GlyphNewRec));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+
+    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+    glyphs = glyphsBase;
+
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + nglyphs);
+    bits = (CARD8 *) (gi + nglyphs);
+    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+    while (remain >= 0 && nglyphs)
+    {
+	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+	if (!glyph)
+	{
+	    err = BadAlloc;
+	    goto bail;
+	}
+	
+	glyphs->glyph = glyph;
+	glyphs->id = *gids;	
+	
+	size = glyph->size - sizeof (xGlyphInfo);
+	if (remain < size)
+	    break;
+	memcpy ((CARD8 *) (glyph + 1), bits, size);
+	
+	if (size & 3)
+	    size += 4 - (size & 3);
+	bits += size;
+	remain -= size;
+	gi++;
+	gids++;
+	glyphs++;
+	nglyphs--;
+    }
+    if (nglyphs || remain)
+    {
+	err = BadLength;
+	goto bail;
+    }
+    nglyphs = stuff->nglyphs;
+    if (!ResizeGlyphSet (glyphSet, nglyphs))
+    {
+	err = BadAlloc;
+	goto bail;
+    }
+    glyphs = glyphsBase;
+    while (nglyphs--)
+	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    return client->noClientException;
+bail:
+    while (glyphs != glyphsBase)
+    {
+	--glyphs;
+	xfree (glyphs->glyph);
+    }
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+    REQUEST(xRenderFreeGlyphsReq);
+    GlyphSetPtr     glyphSet;
+    int		    nglyph;
+    CARD32	    *gids;
+    CARD32	    glyph;
+
+    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+    gids = (CARD32 *) (stuff + 1);
+    while (nglyph-- > 0)
+    {
+	glyph = *gids++;
+	if (!DeleteGlyph (glyphSet, glyph))
+	{
+	    client->errorValue = glyph;
+	    return RenderErrBase + BadGlyph;
+	}
+    }
+    return client->noClientException;
+}
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    GlyphSet	    gs;
+    PicturePtr      pSrc, pDst;
+    PictFormatPtr   pFormat;
+    GlyphListRec    listsLocal[NLOCALDELTA];
+    GlyphListPtr    lists, listsBase;
+    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
+    Glyph	    glyph;
+    GlyphPtr	    *glyphs, *glyphsBase;
+    xGlyphElt	    *elt;
+    CARD8	    *buffer, *end;
+    int		    nglyph;
+    int		    nlist;
+    int		    space;
+    int		    size;
+    int		    n;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityReadAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    nglyph = 0;
+    nlist = 0;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    buffer += 4;
+	}
+	else
+	{
+	    nlist++;
+	    nglyph += elt->len;
+	    space = size * elt->len;
+	    if (space & 3)
+		space += 4 - (space & 3);
+	    buffer += space;
+	}
+    }
+    if (nglyph <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+    if (nlist <= NLOCALDELTA)
+	listsBase = listsLocal;
+    else
+    {
+	listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+	if (!listsBase)
+	    return BadAlloc;
+    }
+    buffer = (CARD8 *) (stuff + 1);
+    glyphs = glyphsBase;
+    lists = listsBase;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    if (buffer + sizeof (GlyphSet) < end)
+	    {
+		gs = *(GlyphSet *) buffer;
+		glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+								 gs,
+								 GlyphSetType,
+								 SecurityReadAccess);
+		if (!glyphSet)
+		{
+		    client->errorValue = gs;
+		    if (glyphsBase != glyphsLocal)
+			DEALLOCATE_LOCAL (glyphsBase);
+		    if (listsBase != listsLocal)
+			DEALLOCATE_LOCAL (listsBase);
+		    return RenderErrBase + BadGlyphSet;
+		}
+	    }
+	    buffer += 4;
+	}
+	else
+	{
+	    lists->xOff = elt->deltax;
+	    lists->yOff = elt->deltay;
+	    lists->format = glyphSet->format;
+	    lists->len = 0;
+	    n = elt->len;
+	    while (n--)
+	    {
+		if (buffer + size <= end)
+		{
+		    switch (size) {
+		    case 1:
+			glyph = *((CARD8 *)buffer); break;
+		    case 2:
+			glyph = *((CARD16 *)buffer); break;
+		    case 4:
+		    default:
+			glyph = *((CARD32 *)buffer); break;
+		    }
+		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
+		    {
+			lists->len++;
+			glyphs++;
+		    }
+		}
+		buffer += size;
+	    }
+	    space = size * elt->len;
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	    lists++;
+	}
+    }
+    if (buffer > end)
+	return BadLength;
+
+    CompositeGlyphs (stuff->op,
+		     pSrc,
+		     pDst,
+		     pFormat,
+		     stuff->xSrc,
+		     stuff->ySrc,
+		     nlist,
+		     listsBase,
+		     glyphsBase);
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    if (listsBase != listsLocal)
+	DEALLOCATE_LOCAL (listsBase);
+    
+    return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+    PicturePtr	    pDst;
+    int             things;
+    REQUEST(xRenderFillRectanglesReq);
+    
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    
+    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+    
+    CompositeRects (stuff->op,
+		    pDst,
+		    &stuff->color,
+		    things,
+		    (xRectangle *) &stuff[1]);
+    
+    return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+    unsigned char   mask;
+    
+    if (screenInfo.bitmapBitOrder == LSBFirst)
+	mask = (1 << (x & 7));
+    else
+	mask = (0x80 >> (x & 7));
+    /* XXX assumes byte order is host byte order */
+    line += (x >> 3);
+    if (bit)
+	*line |= mask;
+    else
+	*line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+    {  1,  3,  },
+    {  4,  2,  },
+};
+
+#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateCursorReq);
+    PicturePtr	    pSrc;
+    ScreenPtr	    pScreen;
+    unsigned short  width, height;
+    CARD32	    *argbbits, *argb;
+    unsigned char   *srcbits, *srcline;
+    unsigned char   *mskbits, *mskline;
+    int		    stride;
+    int		    x, y;
+    int		    nbytes_mono;
+    CursorMetricRec cm;
+    CursorPtr	    pCursor;
+    CARD32	    twocolor[3];
+    int		    ncolor;
+
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    pScreen = pSrc->pDrawable->pScreen;
+    width = pSrc->pDrawable->width;
+    height = pSrc->pDrawable->height;
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+    argbbits = xalloc (width * height * sizeof (CARD32));
+    if (!argbbits)
+	return (BadAlloc);
+    
+    stride = BitmapBytePad(width);
+    nbytes_mono = stride*height;
+    srcbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!srcbits)
+    {
+	xfree (argbbits);
+	return (BadAlloc);
+    }
+    mskbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!mskbits)
+    {
+	xfree(argbbits);
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+    bzero ((char *) mskbits, nbytes_mono);
+    bzero ((char *) srcbits, nbytes_mono);
+
+    if (pSrc->format == PICT_a8r8g8b8)
+    {
+	(*pScreen->GetImage) (pSrc->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+    }
+    else
+    {
+	PixmapPtr	pPixmap;
+	PicturePtr	pPicture;
+	PictFormatPtr	pFormat;
+	int		error;
+
+	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+	if (!pFormat)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadImplementation);
+	}
+	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+	if (!pPixmap)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadAlloc);
+	}
+	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, 
+				  client, &error);
+	if (!pPicture);
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return error;
+	}
+	(*pScreen->DestroyPixmap) (pPixmap);
+	CompositePicture (PictOpSrc,
+			  pSrc, 0, pPicture,
+			  0, 0, 0, 0, 0, 0, width, height);
+	(*pScreen->GetImage) (pPicture->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+	FreePicture (pPicture, 0);
+    }
+    /*
+     * Check whether the cursor can be directly supported by 
+     * the core cursor code
+     */
+    ncolor = 0;
+    argb = argbbits;
+    for (y = 0; ncolor <= 2 && y < height; y++)
+    {
+	for (x = 0; ncolor <= 2 && x < width; x++)
+	{
+	    CARD32  p = *argb++;
+	    CARD32  a = (p >> 24);
+
+	    if (a == 0)	    /* transparent */
+		continue;
+	    if (a == 0xff)  /* opaque */
+	    {
+		int n;
+		for (n = 0; n < ncolor; n++)
+		    if (p == twocolor[n])
+			break;
+		if (n == ncolor)
+		    twocolor[ncolor++] = p;
+	    }
+	    else
+		ncolor = 3;
+	}
+    }
+    
+    /*
+     * Convert argb image to two plane cursor
+     */
+    srcline = srcbits;
+    mskline = mskbits;
+    argb = argbbits;
+    for (y = 0; y < height; y++)
+    {
+	for (x = 0; x < width; x++)
+	{
+	    CARD32  p = *argb++;
+
+	    if (ncolor <= 2)
+	    {
+		CARD32	a = ((p >> 24));
+
+		SetBit (mskline, x, a != 0);
+		SetBit (srcline, x, a != 0 && p == twocolor[0]);
+	    }
+	    else
+	    {
+		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+		/* Set mask from dithered alpha value */
+		SetBit(mskline, x, a > d);
+		/* Set src from dithered intensity value */
+		SetBit(srcline, x, a > d && i <= d);
+	    }
+	}
+	srcline += stride;
+	mskline += stride;
+    }
+    /*
+     * Dither to white and black if the cursor has more than two colors
+     */
+    if (ncolor > 2)
+    {
+	twocolor[0] = 0xff000000;
+	twocolor[1] = 0xffffffff;
+    }
+    else
+    {
+	xfree (argbbits);
+	argbbits = 0;
+    }
+    
+#define GetByte(p,s)	(((p) >> (s)) & 0xff)
+#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
+    
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+			       GetColor(twocolor[0], 16),
+			       GetColor(twocolor[0], 8),
+			       GetColor(twocolor[0], 0),
+			       GetColor(twocolor[1], 16),
+			       GetColor(twocolor[1], 8),
+			       GetColor(twocolor[1], 0));
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return (client->noClientException);
+    return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    PicturePtr	pPicture;
+    int		result;
+
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+    REQUEST (xRenderQueryFiltersReq);
+    DrawablePtr			pDrawable;
+    xRenderQueryFiltersReply	*reply;
+    int				nbytesName;
+    int				nnames;
+    ScreenPtr			pScreen;
+    PictureScreenPtr		ps;
+    int				i, j;
+    int				len;
+    int				total_bytes;
+    INT16			*aliases;
+    char			*names;
+
+    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+    
+    pScreen = pDrawable->pScreen;
+    nbytesName = 0;
+    nnames = 0;
+    ps = GetPictureScreenIfSet(pScreen);
+    if (ps)
+    {
+	for (i = 0; i < ps->nfilters; i++)
+	    nbytesName += 1 + strlen (ps->filters[i].name);
+	for (i = 0; i < ps->nfilterAliases; i++)
+	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+	nnames = ps->nfilters + ps->nfilterAliases;
+    }
+    len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+    reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+    if (!reply)
+	return BadAlloc;
+    aliases = (INT16 *) (reply + 1);
+    names = (char *) (aliases + ((nnames + 1) & ~1));
+    
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = len;
+    reply->numAliases = nnames;
+    reply->numFilters = nnames;
+    if (ps)
+    {
+
+	/* fill in alias values */
+	for (i = 0; i < ps->nfilters; i++)
+	    aliases[i] = FilterAliasNone;
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    for (j = 0; j < ps->nfilters; j++)
+		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+		    break;
+	    if (j == ps->nfilters)
+	    {
+		for (j = 0; j < ps->nfilterAliases; j++)
+		    if (ps->filterAliases[i].filter_id == 
+			ps->filterAliases[j].alias_id)
+		    {
+			break;
+		    }
+		if (j == ps->nfilterAliases)
+		    j = FilterAliasNone;
+		else
+		    j = j + ps->nfilters;
+	    }
+	    aliases[i + ps->nfilters] = j;
+	}
+
+	/* fill in filter names */
+	for (i = 0; i < ps->nfilters; i++)
+	{
+	    j = strlen (ps->filters[i].name);
+	    *names++ = j;
+	    strncpy (names, ps->filters[i].name, j);
+	    names += j;
+	}
+	
+	/* fill in filter alias names */
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    j = strlen (ps->filterAliases[i].alias);
+	    *names++ = j;
+	    strncpy (names, ps->filterAliases[i].alias, j);
+	    names += j;
+	}
+    }
+
+    if (client->swapped)
+    {
+	register int n;
+
+	for (i = 0; i < reply->numAliases; i++)
+	{
+	    swaps (&aliases[i], n);
+	}
+    	swaps(&reply->sequenceNumber, n);
+    	swapl(&reply->length, n);
+	swapl(&reply->numAliases, n);
+	swapl(&reply->numFilters, n);
+    }
+    WriteToClient(client, total_bytes, (char *) reply);
+    xfree (reply);
+    
+    return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST (xRenderSetPictureFilterReq);
+    PicturePtr	pPicture;
+    int		result;
+    xFixed	*params;
+    int		nparams;
+    char	*name;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    name = (char *) (stuff + 1);
+    params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+    return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateAnimCursorReq);
+    CursorPtr	    *cursors;
+    CARD32	    *deltas;
+    CursorPtr	    pCursor;
+    int		    ncursor;
+    xAnimCursorElt  *elt;
+    int		    i;
+    int		    ret;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    if (client->req_len & 1)
+	return BadLength;
+    ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+    cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+    if (!cursors)
+	return BadAlloc;
+    deltas = (CARD32 *) (cursors + ncursor);
+    elt = (xAnimCursorElt *) (stuff + 1);
+    for (i = 0; i < ncursor; i++)
+    {
+	cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+						       RT_CURSOR, SecurityReadAccess);
+	if (!cursors[i])
+	{
+	    xfree (cursors);
+	    client->errorValue = elt->cursor;
+	    return BadCursor;
+	}
+	deltas[i] = elt->delay;
+	elt++;
+    }
+    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+    xfree (cursors);
+    if (ret != Success)
+	return ret;
+    
+    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+    
+    if (stuff->data < RenderNumberRequests)
+	return (*ProcRenderVector[stuff->data]) (client);
+    else
+	return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->majorVersion, n);
+    swapl(&stuff->minorVersion, n);
+    return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictFormatsReq);
+    swaps(&stuff->length, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreatePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->format, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderChangePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCompositeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->mask, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xMask, n);
+    swaps(&stuff->yMask, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderScaleReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->colorScale, n);
+    swapl(&stuff->alphaScale, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriStripReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriFanReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderReferenceGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->existing, n);
+    return (*ProcRenderVector[stuff->renderReqType])  (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+    register int n;
+    register int i;
+    CARD32  *gids;
+    void    *end;
+    xGlyphInfo *gi;
+    REQUEST(xRenderAddGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    swapl(&stuff->nglyphs, n);
+    if (stuff->nglyphs & 0xe0000000)
+	return BadLength;
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+	return BadLength;
+    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+	return BadLength;
+    for (i = 0; i < stuff->nglyphs; i++)
+    {
+	swapl (&gids[i], n);
+	swaps (&gi[i].width, n);
+	swaps (&gi[i].height, n);
+	swaps (&gi[i].x, n);
+	swaps (&gi[i].y, n);
+	swaps (&gi[i].xOff, n);
+	swaps (&gi[i].yOff, n);
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+    register int n;
+    xGlyphElt	*elt;
+    CARD8	*buffer;
+    CARD8	*end;
+    int		space;
+    int		i;
+    int		size;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+    
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->maskFormat, n);
+    swapl(&stuff->glyphset, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	swaps (&elt->deltax, n);
+	swaps (&elt->deltay, n);
+	
+	i = elt->len;
+	if (i == 0xff)
+	{
+	    swapl (buffer, n);
+	    buffer += 4;
+	}
+	else
+	{
+	    space = size * i;
+	    switch (size) {
+	    case 1:
+		buffer += i;
+		break;
+	    case 2:
+		while (i--)
+		{
+		    swaps (buffer, n);
+		    buffer += 2;
+		}
+		break;
+	    case 4:
+		while (i--)
+		{
+		    swapl (buffer, n);
+		    buffer += 4;
+		}
+		break;
+	    }
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	}
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFillRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    swaps(&stuff->color.alpha, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateCursorReq);
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    swapl(&stuff->src, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureTransformReq);
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->transform.matrix11, n);
+    swapl(&stuff->transform.matrix12, n);
+    swapl(&stuff->transform.matrix13, n);
+    swapl(&stuff->transform.matrix21, n);
+    swapl(&stuff->transform.matrix22, n);
+    swapl(&stuff->transform.matrix23, n);
+    swapl(&stuff->transform.matrix31, n);
+    swapl(&stuff->transform.matrix32, n);
+    swapl(&stuff->transform.matrix33, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderQueryFiltersReq);
+    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderSetPictureFilterReq);
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->nbytes, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateAnimCursorReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+    
+    if (stuff->data < RenderNumberRequests)
+	return (*SProcRenderVector[stuff->data]) (client);
+    else
+	return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+int	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long	XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+    REQUEST(xRenderCreatePictureReq);
+    PanoramiXRes    *refDraw, *newPict;
+    int		    result = Success, j;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+    if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+    if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+    newPict->type = XRT_PICTURE;
+    newPict->info[0].id = stuff->pid;
+    
+    if (refDraw->type == XRT_WINDOW &&
+	stuff->drawable == WindowTable[0]->drawable.id)
+    {
+	newPict->u.pict.root = TRUE;
+    }
+    else
+	newPict->u.pict.root = FALSE;
+
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPict->info[j].id = FakeClientID(client->index);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->pid = newPict->info[j].id;
+	stuff->drawable = refDraw->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+	if(result != Success) break;
+    }
+
+    if (result == Success)
+	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+    else 
+	xfree(newPict);
+
+    return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+    PanoramiXRes    *pict;
+    int		    result = Success, j;
+    REQUEST(xRenderChangePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+    PanoramiXRes *pict;
+    int         result = Success, j;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    client->errorValue = stuff->picture;
+
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+		       RenderErrBase + BadPicture);
+    
+
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->picture = pict->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+	if(result != Success) break;
+    }
+
+    /* Since ProcRenderFreePicture is using FreeResource, it will free
+	our resource for us on the last pass through the loop above */
+ 
+    return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+    PanoramiXRes	*src, *msk, *dst;
+    int			result = Success, j;
+    xRenderCompositeReq	orig;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess, 
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess, 
+		      RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    
+    orig = *stuff;
+    
+    FOR_NSCREENS_FORWARD(j) {
+	stuff->src = src->info[j].id;
+	if (src->u.pict.root)
+	{
+	    stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+	    stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+	}
+	stuff->dst = dst->info[j].id;
+	if (dst->u.pict.root)
+	{
+	    stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+	    stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+	}
+	if (msk)
+	{
+	    stuff->mask = msk->info[j].id;
+	    if (msk->u.pict.root)
+	    {
+		stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+		stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+	    }
+	}
+	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+	if(result != Success) break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+    PanoramiXRes    *src, *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderCompositeGlyphsReq);
+    xGlyphElt	    origElt, *elt;
+    INT16	    xSrc, ySrc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+				 sizeof (xGlyphElt)))
+    {
+	elt = (xGlyphElt *) (stuff + 1);
+	origElt = *elt;
+	xSrc = stuff->xSrc;
+	ySrc = stuff->ySrc;
+	FOR_NSCREENS_FORWARD(j) {
+	    stuff->src = src->info[j].id;
+	    if (src->u.pict.root)
+	    {
+		stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+		stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+	    }
+	    stuff->dst = dst->info[j].id;
+	    if (dst->u.pict.root)
+	    {
+		elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+		elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+	    if(result != Success) break;
+	}
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+    PanoramiXRes    *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderFillRectanglesReq);
+    char	    *extra;
+    int		    extra_len;
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root)
+	    {
+		int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+		    xRectangle	*rects = (xRectangle *) (stuff + 1);
+		    int		i = extra_len / sizeof (xRectangle);
+
+		    while (i--)
+		    {
+			rects->x -= x_off;
+			rects->y -= y_off;
+			rects++;
+		    }
+		}
+	    }
+	    stuff->dst = dst->info[j].id;
+	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+    int	    i;
+    
+    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+    for (i = 0; i < RenderNumberRequests; i++)
+	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+    /*
+     * Stuff in Xinerama aware request processing hooks
+     */
+    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+    int	    i;
+    for (i = 0; i < RenderNumberRequests; i++)
+	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif	/* PANORAMIX */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c
new file mode 100644
index 000000000..0c81c81ef
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c
@@ -0,0 +1,1103 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXresource.c"
+
+#else
+
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/*	Routines to manage various kinds of resources:
+ *
+ *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ *	FakeClientID, AddResource, FreeResource, FreeClientResources,
+ *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/* 
+ *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ *	off-limits for client-visible resources.  The next 8 bits are
+ *      used as client ID, and the low 22 bits come from the client.
+ *	A resource ID is "hashed" by extracting and xoring subfields
+ *      (varying with the size of the hash table).
+ *
+ *      It is sometimes necessary for the server to create an ID that looks
+ *      like it belongs to a client.  This ID, however,  must not be one
+ *      the client actually can create, or we have the potential for conflict.
+ *      The 31st bit of the ID is reserved for the server's use for this
+ *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ *      resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.12 2002/03/06 21:13:38 mvojkovi Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h" 
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#endif
+
+static void RebuildTable(
+#if NeedFunctionPrototypes
+    int /*client*/
+#endif
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+    struct _Resource	*next;
+    XID			id;
+    RESTYPE		type;
+    pointer		value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+    ResourcePtr *resources;
+    int		elements;
+    int		buckets;
+    int		hashsize;	/* log(2)(buckets) */
+    XID		fakeID;
+    XID		endFakeID;
+    XID		expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(deleteFunc)
+    DeleteType deleteFunc;
+{
+    RESTYPE next = lastResourceType + 1;
+    DeleteType *funcs;
+
+    if (next & lastResourceClass)
+	return 0;
+    funcs = (DeleteType *)xrealloc(DeleteFuncs,
+				   (next + 1) * sizeof(DeleteType));
+    if (!funcs)
+	return 0;
+
+#ifdef XResExtension
+    {
+       Atom *newnames;
+       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+       if(!newnames)
+           return 0;
+       ResourceNames = newnames;
+       ResourceNames[next] = 0;
+    }
+#endif
+
+    lastResourceType = next;
+    DeleteFuncs = funcs;
+    DeleteFuncs[next] = deleteFunc;
+    return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+    RESTYPE next = lastResourceClass >> 1;
+
+    if (next & lastResourceType)
+	return 0;
+    lastResourceClass = next;
+    TypeMask = next - 1;
+    return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ *    When a new client is created, call this to allocate space
+ *    in resource table
+ *****************/
+
+Bool
+InitClientResources(client)
+    ClientPtr client;
+{
+    register int i, j;
+ 
+    if (client == serverClient)
+    {
+	lastResourceType = RT_LASTPREDEF;
+	lastResourceClass = RC_LASTPREDEF;
+	TypeMask = RC_LASTPREDEF - 1;
+	if (DeleteFuncs)
+	    xfree(DeleteFuncs);
+	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+					   sizeof(DeleteType));
+	if (!DeleteFuncs)
+	    return FALSE;
+	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+        if(ResourceNames)
+            xfree(ResourceNames);
+        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+        if(!ResourceNames)
+           return FALSE;
+#endif
+    }
+    clientTable[i = client->index].resources =
+	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+    if (!clientTable[i].resources)
+	return FALSE;
+    clientTable[i].buckets = INITBUCKETS;
+    clientTable[i].elements = 0;
+    clientTable[i].hashsize = INITHASHSIZE;
+    /* Many IDs allocated from the server client are visible to clients,
+     * so we don't use the SERVER_BIT for them, but we have to start
+     * past the magic value constants used in the protocol.  For normal
+     * clients, we can start from zero, with SERVER_BIT set.
+     */
+    clientTable[i].fakeID = client->clientAsMask |
+			    (client->index ? SERVER_BIT : SERVER_MINID);
+    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+    clientTable[i].expectID = client->clientAsMask;
+    for (j=0; j<INITBUCKETS; j++) 
+    {
+        clientTable[i].resources[j] = NullResource;
+    }
+    return TRUE;
+}
+
+
+static int
+#if NeedFunctionPrototypes
+Hash(int client, register XID id)
+#else
+Hash(client, id)
+    int client;
+    register XID id;
+#endif
+{
+    id &= RESOURCE_ID_MASK;
+    switch (clientTable[client].hashsize)
+    {
+	case 6:
+	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+	case 7:
+	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+	case 8:
+	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+	case 9:
+	    return ((int)(0x1FF & (id ^ (id>>9))));
+	case 10:
+	    return ((int)(0x3FF & (id ^ (id>>10))));
+	case 11:
+	    return ((int)(0x7FF & (id ^ (id>>11))));
+    }
+    return -1;
+}
+
+static XID
+#if NeedFunctionPrototypes
+AvailableID(
+    register int client,
+    register XID id,
+    register XID maxid,
+    register XID goodid)
+#else
+AvailableID(client, id, maxid, goodid)
+    register int client;
+    register XID id, maxid, goodid;
+#endif
+{
+    register ResourcePtr res;
+
+    if ((goodid >= id) && (goodid <= maxid))
+	return goodid;
+    for (; id <= maxid; id++)
+    {
+	res = clientTable[client].resources[Hash(client, id)];
+	while (res && (res->id != id))
+	    res = res->next;
+	if (!res)
+	    return id;
+    }
+    return 0;
+}
+
+void
+GetXIDRange(client, server, minp, maxp)
+    int client;
+    Bool server;
+    XID *minp, *maxp;
+{
+    register XID id, maxid;
+    register ResourcePtr *resp;
+    register ResourcePtr res;
+    register int i;
+    XID goodid;
+
+    id = (Mask)client << CLIENTOFFSET;
+    if (server)
+	id |= client ? SERVER_BIT : SERVER_MINID;
+    maxid = id | RESOURCE_ID_MASK;
+    goodid = 0;
+    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+	 --i >= 0;)
+    {
+	for (res = *resp++; res; res = res->next)
+	{
+	    if ((res->id < id) || (res->id > maxid))
+		continue;
+	    if (((res->id - id) >= (maxid - res->id)) ?
+		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
+		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+		maxid = res->id - 1;
+	    else
+		id = res->id + 1;
+	}
+    }
+    if (id > maxid)
+	id = maxid = 0;
+    *minp = id;
+    *maxp = maxid;
+}
+
+/*  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ *  This function tries to find count unused XIDs for the given client.  It 
+ *  puts the IDs in the array pids and returns the number found, which should
+ *  almost always be the number requested.
+ *
+ *  The circumstances that lead to a call to this function are very rare.
+ *  Xlib must run out of IDs while trying to generate a request that wants
+ *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ *  No rocket science in the implementation; just iterate over all
+ *  possible IDs for the given client and pick the first count IDs
+ *  that aren't in use.  A more efficient algorithm could probably be
+ *  invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(pClient, count, pids)
+    ClientPtr pClient;
+    unsigned int count;
+    XID *pids;
+{
+    unsigned int found = 0;
+    XID id = pClient->clientAsMask;
+    XID maxid;
+
+    maxid = id | RESOURCE_ID_MASK;
+    while ( (found < count) && (id <= maxid) )
+    {
+	if (!LookupIDByClass(id, RC_ANY))
+	{
+	    pids[found++] = id;
+	}
+	id++;
+    }
+    return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(client)
+    register int client;
+{
+    XID id, maxid;
+
+    id = clientTable[client].fakeID++;
+    if (id != clientTable[client].endFakeID)
+	return id;
+    GetXIDRange(client, TRUE, &id, &maxid);
+    if (!id) {
+	if (!client)
+	    FatalError("FakeClientID: server internal ids exhausted\n");
+	MarkClientException(clients[client]);
+	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+	maxid = id | RESOURCE_ID_MASK;
+    }
+    clientTable[client].fakeID = id + 1;
+    clientTable[client].endFakeID = maxid + 1;
+    return id;
+}
+
+#ifdef NXAGENT_SERVER
+
+int nxagentFindClientResource(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  int i;
+
+  for (i = 0; i < clientTable[client].buckets; i++)
+  {
+    resources = clientTable[client].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == type && pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+                    "for client [%d].\n", (void *) value,
+                        pResource -> type, client);
+        #endif
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  RESTYPE internalType = 0;
+
+  int i;
+
+  if (type == RT_PIXMAP)
+  {
+    internalType = RT_NX_PIXMAP;
+  }
+  else if (type == RT_GC)
+  {
+    internalType = RT_NX_GC;
+  }
+  else if (type == RT_FONT)
+  {
+    internalType = RT_NX_FONT;
+  }
+  else
+  {
+    return 0;
+  }
+
+  if (client == serverClient -> index)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+                client);
+    #endif
+
+    return 0;
+  }
+
+  for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+  {
+    resources = clientTable[serverClient -> index].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == internalType &&
+              pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+                    "[%lu] for server client [%d].\n", (void *) value,
+                        (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+        #endif
+
+        FreeResource(pResource -> id, RT_NONE);
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+#endif
+
+Bool
+AddResource(id, type, value)
+    XID id;
+    RESTYPE type;
+    pointer value;
+{
+    int client;
+    register ClientResourceRec *rrec;
+    register ResourcePtr res, *head;
+    	
+    client = CLIENT_ID(id);
+    rrec = &clientTable[client];
+    if (!rrec->buckets)
+    {
+	ErrorF("AddResource(%x, %x, %x), client=%d \n",
+		id, type, (unsigned long)value, client);
+        FatalError("client not in use\n");
+    }
+
+#ifdef NXAGENT_SERVER
+
+    nxagentSwitchResourceType(client, type, value);
+
+    #ifdef TEST
+    fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+                client, (unsigned long) type, (void *) value, (unsigned long) id);
+    #endif
+
+#endif
+
+    if ((rrec->elements >= 4*rrec->buckets) &&
+	(rrec->hashsize < MAXHASHSIZE))
+	RebuildTable(client);
+    head = &rrec->resources[Hash(client, id)];
+    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+    if (!res)
+    {
+	(*DeleteFuncs[type & TypeMask])(value, id);
+	return FALSE;
+    }
+    res->next = *head;
+    res->id = id;
+    res->type = type;
+    res->value = value;
+    *head = res;
+    rrec->elements++;
+    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+	rrec->expectID = id + 1;
+    return TRUE;
+}
+
+static void
+RebuildTable(client)
+    int client;
+{
+    register int j;
+    register ResourcePtr res, next;
+    ResourcePtr **tails, *resources;
+    register ResourcePtr **tptr, *rptr;
+
+    /*
+     * For now, preserve insertion order, since some ddx layers depend
+     * on resources being free in the opposite order they are added.
+     */
+
+    j = 2 * clientTable[client].buckets;
+    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+    if (!tails)
+	return;
+    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+    if (!resources)
+    {
+	DEALLOCATE_LOCAL(tails);
+	return;
+    }
+    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+    {
+	*rptr = NullResource;
+	*tptr = rptr;
+    }
+    clientTable[client].hashsize++;
+    for (j = clientTable[client].buckets,
+	 rptr = clientTable[client].resources;
+	 --j >= 0;
+	 rptr++)
+    {
+	for (res = *rptr; res; res = next)
+	{
+	    next = res->next;
+	    res->next = NullResource;
+	    tptr = &tails[Hash(client, res->id)];
+	    **tptr = res;
+	    *tptr = &res->next;
+	}
+    }
+    DEALLOCATE_LOCAL(tails);
+    clientTable[client].buckets *= 2;
+    xfree(clientTable[client].resources);
+    clientTable[client].resources = resources;
+}
+
+void
+FreeResource(id, skipDeleteFuncType)
+    XID id;
+    RESTYPE skipDeleteFuncType;
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    register	int *eltptr;
+    int		elements;
+    Bool	gotOne = FALSE;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+	eltptr = &clientTable[cid].elements;
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id)
+	    {
+		RESTYPE rtype = res->type;
+		*prev = res->next;
+		elements = --*eltptr;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (rtype != skipDeleteFuncType)
+		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+		xfree(res);
+		if (*eltptr != elements)
+		    prev = head; /* prev may no longer be valid */
+		gotOne = TRUE;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+    if (!gotOne)
+	FatalError("Freeing resource id=%X which isn't there", id);
+}
+
+
+void
+FreeResourceByType(id, type, skipFree)
+    XID id;
+    RESTYPE type;
+    Bool    skipFree;
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id && res->type == type)
+	    {
+		*prev = res->next;
+		if (type & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (!skipFree)
+		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+		xfree(res);
+		break;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+}
+
+/*
+ * Change the value associated with a resource id.  Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (id, rtype, value)
+    XID	id;
+    RESTYPE rtype;
+    pointer value;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		res->value = value;
+		return TRUE;
+	    }
+    }
+    return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources.  If func adds new resources,
+ * func might or might not get called for them.  func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+    ClientPtr client,
+    RESTYPE type,
+    FindResType func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++) 
+    {
+        for (this = resources[i]; this; this = next)
+	{
+	    next = this->next;
+	    if (!type || this->type == type) {
+		elements = *eltptr;
+		(*func)(this->value, this->id, cdata);
+		if (*eltptr != elements)
+		    next = resources[i]; /* start over */
+	    }
+	}
+    }
+}
+
+void
+FindAllClientResources(
+    ClientPtr client,
+    FindAllRes func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+        client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++)
+    {
+        for (this = resources[i]; this; this = next)
+        {
+            next = this->next;
+            elements = *eltptr;
+            (*func)(this->value, this->id, this->type, cdata);
+            if (*eltptr != elements)
+                next = resources[i]; /* start over */
+        }
+    }
+}
+
+
+pointer
+LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata
+){
+    ResourcePtr *resources;
+    ResourcePtr this;
+    int i;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    for (i = 0; i < clientTable[client->index].buckets; i++) {
+        for (this = resources[i]; this; this = this->next) {
+	    if (!type || this->type == type) {
+		if((*func)(this->value, this->id, cdata))
+		    return this->value;
+	    }
+	}
+    }
+    return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+    ResourcePtr *resources;
+    ResourcePtr this;
+    ResourcePtr *prev;
+    int j;
+
+    if (!client)
+	return;
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+	prev = &resources[j];
+        while ( (this = *prev) )
+	{
+	    RESTYPE rtype = this->type;
+	    if (rtype & RC_NEVERRETAIN)
+	    {
+		*prev = this->next;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(this->id);
+		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+		xfree(this);	    
+	    }
+	    else
+		prev = &this->next;
+	}
+    }
+}
+
+void
+FreeClientResources(client)
+    ClientPtr client;
+{
+    register ResourcePtr *resources;
+    register ResourcePtr this;
+    int j;
+
+    /* This routine shouldn't be called with a null client, but just in
+	case ... */
+
+    if (!client)
+	return;
+
+    HandleSaveSet(client);
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+        /* It may seem silly to update the head of this resource list as
+	we delete the members, since the entire list will be deleted any way, 
+	but there are some resource deletion functions "FreeClientPixels" for 
+	one which do a LookupID on another resource id (a Colormap id in this
+	case), so the resource list must be kept valid up to the point that
+	it is deleted, so every time we delete a resource, we must update the
+	head, just like in FreeResource. I hope that this doesn't slow down
+	mass deletion appreciably. PRH */
+
+	ResourcePtr *head;
+
+	head = &resources[j];
+
+        for (this = *head; this; this = *head)
+	{
+	    RESTYPE rtype = this->type;
+	    *head = this->next;
+	    if (rtype & RC_CACHED)
+		FlushClientCaches(this->id);
+	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+	    xfree(this);	    
+	}
+    }
+    xfree(clientTable[client->index].resources);
+    clientTable[client->index].resources = NULL;
+    clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+    int	i;
+
+    for (i = currentMaxClients; --i >= 0; ) 
+    {
+        if (clientTable[i].buckets) 
+	    FreeClientResources(clients[i]);
+    }
+}
+
+Bool
+LegalNewID(id, client)
+    XID id;
+    register ClientPtr client;
+{
+
+#ifdef PANORAMIX
+    XID 	minid, maxid;
+
+	if (!noPanoramiXExtension) { 
+	    minid = client->clientAsMask | (client->index ? 
+			                    SERVER_BIT : SERVER_MINID);
+	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+            if ((id >= minid) && (id <= maxid))
+	        return TRUE;
+	}
+#endif /* PANORAMIX */
+	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+	    ((clientTable[client->index].expectID <= id) ||
+	     !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system.  They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(client, id, rtype, mode)
+    ClientPtr client;
+    XID id;
+    RESTYPE rtype;
+    Mask mode;
+{
+    int    cid;
+    register    ResourcePtr res;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert( (rtype & TypeMask) <= lastResourceType);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+    return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(client, id, classes, mode)
+    ClientPtr client;
+    XID id;
+    RESTYPE classes;
+    Mask mode;
+{
+    int    cid;
+    register ResourcePtr res = NULL;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert (classes >= lastResourceClass);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+    return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(id, rtype)
+    XID id;
+    RESTYPE rtype;
+{
+    return SecurityLookupIDByType(NullClient, id, rtype,
+				  SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(id, classes)
+    XID id;
+    RESTYPE classes;
+{
+    return SecurityLookupIDByClass(NullClient, id, classes,
+				   SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ *  LookupIDByType returns the object with the given id and type, else NULL.
+ */ 
+pointer
+LookupIDByType(id, rtype)
+    XID id;
+    RESTYPE rtype;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+/*
+ *  LookupIDByClass returns the object with the given id and any one of the
+ *  given classes, else NULL.
+ */ 
+pointer
+LookupIDByClass(id, classes)
+    XID id;
+    RESTYPE classes;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c.NX.original
new file mode 100644
index 000000000..0c81c81ef
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c.NX.original
@@ -0,0 +1,1103 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXresource.c"
+
+#else
+
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/*	Routines to manage various kinds of resources:
+ *
+ *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ *	FakeClientID, AddResource, FreeResource, FreeClientResources,
+ *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/* 
+ *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ *	off-limits for client-visible resources.  The next 8 bits are
+ *      used as client ID, and the low 22 bits come from the client.
+ *	A resource ID is "hashed" by extracting and xoring subfields
+ *      (varying with the size of the hash table).
+ *
+ *      It is sometimes necessary for the server to create an ID that looks
+ *      like it belongs to a client.  This ID, however,  must not be one
+ *      the client actually can create, or we have the potential for conflict.
+ *      The 31st bit of the ID is reserved for the server's use for this
+ *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ *      resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.12 2002/03/06 21:13:38 mvojkovi Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h" 
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#endif
+
+static void RebuildTable(
+#if NeedFunctionPrototypes
+    int /*client*/
+#endif
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+    struct _Resource	*next;
+    XID			id;
+    RESTYPE		type;
+    pointer		value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+    ResourcePtr *resources;
+    int		elements;
+    int		buckets;
+    int		hashsize;	/* log(2)(buckets) */
+    XID		fakeID;
+    XID		endFakeID;
+    XID		expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(deleteFunc)
+    DeleteType deleteFunc;
+{
+    RESTYPE next = lastResourceType + 1;
+    DeleteType *funcs;
+
+    if (next & lastResourceClass)
+	return 0;
+    funcs = (DeleteType *)xrealloc(DeleteFuncs,
+				   (next + 1) * sizeof(DeleteType));
+    if (!funcs)
+	return 0;
+
+#ifdef XResExtension
+    {
+       Atom *newnames;
+       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+       if(!newnames)
+           return 0;
+       ResourceNames = newnames;
+       ResourceNames[next] = 0;
+    }
+#endif
+
+    lastResourceType = next;
+    DeleteFuncs = funcs;
+    DeleteFuncs[next] = deleteFunc;
+    return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+    RESTYPE next = lastResourceClass >> 1;
+
+    if (next & lastResourceType)
+	return 0;
+    lastResourceClass = next;
+    TypeMask = next - 1;
+    return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ *    When a new client is created, call this to allocate space
+ *    in resource table
+ *****************/
+
+Bool
+InitClientResources(client)
+    ClientPtr client;
+{
+    register int i, j;
+ 
+    if (client == serverClient)
+    {
+	lastResourceType = RT_LASTPREDEF;
+	lastResourceClass = RC_LASTPREDEF;
+	TypeMask = RC_LASTPREDEF - 1;
+	if (DeleteFuncs)
+	    xfree(DeleteFuncs);
+	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+					   sizeof(DeleteType));
+	if (!DeleteFuncs)
+	    return FALSE;
+	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+        if(ResourceNames)
+            xfree(ResourceNames);
+        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+        if(!ResourceNames)
+           return FALSE;
+#endif
+    }
+    clientTable[i = client->index].resources =
+	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+    if (!clientTable[i].resources)
+	return FALSE;
+    clientTable[i].buckets = INITBUCKETS;
+    clientTable[i].elements = 0;
+    clientTable[i].hashsize = INITHASHSIZE;
+    /* Many IDs allocated from the server client are visible to clients,
+     * so we don't use the SERVER_BIT for them, but we have to start
+     * past the magic value constants used in the protocol.  For normal
+     * clients, we can start from zero, with SERVER_BIT set.
+     */
+    clientTable[i].fakeID = client->clientAsMask |
+			    (client->index ? SERVER_BIT : SERVER_MINID);
+    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+    clientTable[i].expectID = client->clientAsMask;
+    for (j=0; j<INITBUCKETS; j++) 
+    {
+        clientTable[i].resources[j] = NullResource;
+    }
+    return TRUE;
+}
+
+
+static int
+#if NeedFunctionPrototypes
+Hash(int client, register XID id)
+#else
+Hash(client, id)
+    int client;
+    register XID id;
+#endif
+{
+    id &= RESOURCE_ID_MASK;
+    switch (clientTable[client].hashsize)
+    {
+	case 6:
+	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+	case 7:
+	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+	case 8:
+	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+	case 9:
+	    return ((int)(0x1FF & (id ^ (id>>9))));
+	case 10:
+	    return ((int)(0x3FF & (id ^ (id>>10))));
+	case 11:
+	    return ((int)(0x7FF & (id ^ (id>>11))));
+    }
+    return -1;
+}
+
+static XID
+#if NeedFunctionPrototypes
+AvailableID(
+    register int client,
+    register XID id,
+    register XID maxid,
+    register XID goodid)
+#else
+AvailableID(client, id, maxid, goodid)
+    register int client;
+    register XID id, maxid, goodid;
+#endif
+{
+    register ResourcePtr res;
+
+    if ((goodid >= id) && (goodid <= maxid))
+	return goodid;
+    for (; id <= maxid; id++)
+    {
+	res = clientTable[client].resources[Hash(client, id)];
+	while (res && (res->id != id))
+	    res = res->next;
+	if (!res)
+	    return id;
+    }
+    return 0;
+}
+
+void
+GetXIDRange(client, server, minp, maxp)
+    int client;
+    Bool server;
+    XID *minp, *maxp;
+{
+    register XID id, maxid;
+    register ResourcePtr *resp;
+    register ResourcePtr res;
+    register int i;
+    XID goodid;
+
+    id = (Mask)client << CLIENTOFFSET;
+    if (server)
+	id |= client ? SERVER_BIT : SERVER_MINID;
+    maxid = id | RESOURCE_ID_MASK;
+    goodid = 0;
+    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+	 --i >= 0;)
+    {
+	for (res = *resp++; res; res = res->next)
+	{
+	    if ((res->id < id) || (res->id > maxid))
+		continue;
+	    if (((res->id - id) >= (maxid - res->id)) ?
+		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
+		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+		maxid = res->id - 1;
+	    else
+		id = res->id + 1;
+	}
+    }
+    if (id > maxid)
+	id = maxid = 0;
+    *minp = id;
+    *maxp = maxid;
+}
+
+/*  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ *  This function tries to find count unused XIDs for the given client.  It 
+ *  puts the IDs in the array pids and returns the number found, which should
+ *  almost always be the number requested.
+ *
+ *  The circumstances that lead to a call to this function are very rare.
+ *  Xlib must run out of IDs while trying to generate a request that wants
+ *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ *  No rocket science in the implementation; just iterate over all
+ *  possible IDs for the given client and pick the first count IDs
+ *  that aren't in use.  A more efficient algorithm could probably be
+ *  invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(pClient, count, pids)
+    ClientPtr pClient;
+    unsigned int count;
+    XID *pids;
+{
+    unsigned int found = 0;
+    XID id = pClient->clientAsMask;
+    XID maxid;
+
+    maxid = id | RESOURCE_ID_MASK;
+    while ( (found < count) && (id <= maxid) )
+    {
+	if (!LookupIDByClass(id, RC_ANY))
+	{
+	    pids[found++] = id;
+	}
+	id++;
+    }
+    return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(client)
+    register int client;
+{
+    XID id, maxid;
+
+    id = clientTable[client].fakeID++;
+    if (id != clientTable[client].endFakeID)
+	return id;
+    GetXIDRange(client, TRUE, &id, &maxid);
+    if (!id) {
+	if (!client)
+	    FatalError("FakeClientID: server internal ids exhausted\n");
+	MarkClientException(clients[client]);
+	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+	maxid = id | RESOURCE_ID_MASK;
+    }
+    clientTable[client].fakeID = id + 1;
+    clientTable[client].endFakeID = maxid + 1;
+    return id;
+}
+
+#ifdef NXAGENT_SERVER
+
+int nxagentFindClientResource(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  int i;
+
+  for (i = 0; i < clientTable[client].buckets; i++)
+  {
+    resources = clientTable[client].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == type && pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+                    "for client [%d].\n", (void *) value,
+                        pResource -> type, client);
+        #endif
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  RESTYPE internalType = 0;
+
+  int i;
+
+  if (type == RT_PIXMAP)
+  {
+    internalType = RT_NX_PIXMAP;
+  }
+  else if (type == RT_GC)
+  {
+    internalType = RT_NX_GC;
+  }
+  else if (type == RT_FONT)
+  {
+    internalType = RT_NX_FONT;
+  }
+  else
+  {
+    return 0;
+  }
+
+  if (client == serverClient -> index)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+                client);
+    #endif
+
+    return 0;
+  }
+
+  for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+  {
+    resources = clientTable[serverClient -> index].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == internalType &&
+              pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+                    "[%lu] for server client [%d].\n", (void *) value,
+                        (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+        #endif
+
+        FreeResource(pResource -> id, RT_NONE);
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+#endif
+
+Bool
+AddResource(id, type, value)
+    XID id;
+    RESTYPE type;
+    pointer value;
+{
+    int client;
+    register ClientResourceRec *rrec;
+    register ResourcePtr res, *head;
+    	
+    client = CLIENT_ID(id);
+    rrec = &clientTable[client];
+    if (!rrec->buckets)
+    {
+	ErrorF("AddResource(%x, %x, %x), client=%d \n",
+		id, type, (unsigned long)value, client);
+        FatalError("client not in use\n");
+    }
+
+#ifdef NXAGENT_SERVER
+
+    nxagentSwitchResourceType(client, type, value);
+
+    #ifdef TEST
+    fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+                client, (unsigned long) type, (void *) value, (unsigned long) id);
+    #endif
+
+#endif
+
+    if ((rrec->elements >= 4*rrec->buckets) &&
+	(rrec->hashsize < MAXHASHSIZE))
+	RebuildTable(client);
+    head = &rrec->resources[Hash(client, id)];
+    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+    if (!res)
+    {
+	(*DeleteFuncs[type & TypeMask])(value, id);
+	return FALSE;
+    }
+    res->next = *head;
+    res->id = id;
+    res->type = type;
+    res->value = value;
+    *head = res;
+    rrec->elements++;
+    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+	rrec->expectID = id + 1;
+    return TRUE;
+}
+
+static void
+RebuildTable(client)
+    int client;
+{
+    register int j;
+    register ResourcePtr res, next;
+    ResourcePtr **tails, *resources;
+    register ResourcePtr **tptr, *rptr;
+
+    /*
+     * For now, preserve insertion order, since some ddx layers depend
+     * on resources being free in the opposite order they are added.
+     */
+
+    j = 2 * clientTable[client].buckets;
+    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+    if (!tails)
+	return;
+    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+    if (!resources)
+    {
+	DEALLOCATE_LOCAL(tails);
+	return;
+    }
+    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+    {
+	*rptr = NullResource;
+	*tptr = rptr;
+    }
+    clientTable[client].hashsize++;
+    for (j = clientTable[client].buckets,
+	 rptr = clientTable[client].resources;
+	 --j >= 0;
+	 rptr++)
+    {
+	for (res = *rptr; res; res = next)
+	{
+	    next = res->next;
+	    res->next = NullResource;
+	    tptr = &tails[Hash(client, res->id)];
+	    **tptr = res;
+	    *tptr = &res->next;
+	}
+    }
+    DEALLOCATE_LOCAL(tails);
+    clientTable[client].buckets *= 2;
+    xfree(clientTable[client].resources);
+    clientTable[client].resources = resources;
+}
+
+void
+FreeResource(id, skipDeleteFuncType)
+    XID id;
+    RESTYPE skipDeleteFuncType;
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    register	int *eltptr;
+    int		elements;
+    Bool	gotOne = FALSE;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+	eltptr = &clientTable[cid].elements;
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id)
+	    {
+		RESTYPE rtype = res->type;
+		*prev = res->next;
+		elements = --*eltptr;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (rtype != skipDeleteFuncType)
+		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+		xfree(res);
+		if (*eltptr != elements)
+		    prev = head; /* prev may no longer be valid */
+		gotOne = TRUE;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+    if (!gotOne)
+	FatalError("Freeing resource id=%X which isn't there", id);
+}
+
+
+void
+FreeResourceByType(id, type, skipFree)
+    XID id;
+    RESTYPE type;
+    Bool    skipFree;
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id && res->type == type)
+	    {
+		*prev = res->next;
+		if (type & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (!skipFree)
+		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+		xfree(res);
+		break;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+}
+
+/*
+ * Change the value associated with a resource id.  Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (id, rtype, value)
+    XID	id;
+    RESTYPE rtype;
+    pointer value;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		res->value = value;
+		return TRUE;
+	    }
+    }
+    return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources.  If func adds new resources,
+ * func might or might not get called for them.  func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+    ClientPtr client,
+    RESTYPE type,
+    FindResType func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++) 
+    {
+        for (this = resources[i]; this; this = next)
+	{
+	    next = this->next;
+	    if (!type || this->type == type) {
+		elements = *eltptr;
+		(*func)(this->value, this->id, cdata);
+		if (*eltptr != elements)
+		    next = resources[i]; /* start over */
+	    }
+	}
+    }
+}
+
+void
+FindAllClientResources(
+    ClientPtr client,
+    FindAllRes func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+        client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++)
+    {
+        for (this = resources[i]; this; this = next)
+        {
+            next = this->next;
+            elements = *eltptr;
+            (*func)(this->value, this->id, this->type, cdata);
+            if (*eltptr != elements)
+                next = resources[i]; /* start over */
+        }
+    }
+}
+
+
+pointer
+LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata
+){
+    ResourcePtr *resources;
+    ResourcePtr this;
+    int i;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    for (i = 0; i < clientTable[client->index].buckets; i++) {
+        for (this = resources[i]; this; this = this->next) {
+	    if (!type || this->type == type) {
+		if((*func)(this->value, this->id, cdata))
+		    return this->value;
+	    }
+	}
+    }
+    return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+    ResourcePtr *resources;
+    ResourcePtr this;
+    ResourcePtr *prev;
+    int j;
+
+    if (!client)
+	return;
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+	prev = &resources[j];
+        while ( (this = *prev) )
+	{
+	    RESTYPE rtype = this->type;
+	    if (rtype & RC_NEVERRETAIN)
+	    {
+		*prev = this->next;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(this->id);
+		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+		xfree(this);	    
+	    }
+	    else
+		prev = &this->next;
+	}
+    }
+}
+
+void
+FreeClientResources(client)
+    ClientPtr client;
+{
+    register ResourcePtr *resources;
+    register ResourcePtr this;
+    int j;
+
+    /* This routine shouldn't be called with a null client, but just in
+	case ... */
+
+    if (!client)
+	return;
+
+    HandleSaveSet(client);
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+        /* It may seem silly to update the head of this resource list as
+	we delete the members, since the entire list will be deleted any way, 
+	but there are some resource deletion functions "FreeClientPixels" for 
+	one which do a LookupID on another resource id (a Colormap id in this
+	case), so the resource list must be kept valid up to the point that
+	it is deleted, so every time we delete a resource, we must update the
+	head, just like in FreeResource. I hope that this doesn't slow down
+	mass deletion appreciably. PRH */
+
+	ResourcePtr *head;
+
+	head = &resources[j];
+
+        for (this = *head; this; this = *head)
+	{
+	    RESTYPE rtype = this->type;
+	    *head = this->next;
+	    if (rtype & RC_CACHED)
+		FlushClientCaches(this->id);
+	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+	    xfree(this);	    
+	}
+    }
+    xfree(clientTable[client->index].resources);
+    clientTable[client->index].resources = NULL;
+    clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+    int	i;
+
+    for (i = currentMaxClients; --i >= 0; ) 
+    {
+        if (clientTable[i].buckets) 
+	    FreeClientResources(clients[i]);
+    }
+}
+
+Bool
+LegalNewID(id, client)
+    XID id;
+    register ClientPtr client;
+{
+
+#ifdef PANORAMIX
+    XID 	minid, maxid;
+
+	if (!noPanoramiXExtension) { 
+	    minid = client->clientAsMask | (client->index ? 
+			                    SERVER_BIT : SERVER_MINID);
+	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+            if ((id >= minid) && (id <= maxid))
+	        return TRUE;
+	}
+#endif /* PANORAMIX */
+	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+	    ((clientTable[client->index].expectID <= id) ||
+	     !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system.  They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(client, id, rtype, mode)
+    ClientPtr client;
+    XID id;
+    RESTYPE rtype;
+    Mask mode;
+{
+    int    cid;
+    register    ResourcePtr res;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert( (rtype & TypeMask) <= lastResourceType);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+    return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(client, id, classes, mode)
+    ClientPtr client;
+    XID id;
+    RESTYPE classes;
+    Mask mode;
+{
+    int    cid;
+    register ResourcePtr res = NULL;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert (classes >= lastResourceClass);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+    return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(id, rtype)
+    XID id;
+    RESTYPE rtype;
+{
+    return SecurityLookupIDByType(NullClient, id, rtype,
+				  SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(id, classes)
+    XID id;
+    RESTYPE classes;
+{
+    return SecurityLookupIDByClass(NullClient, id, classes,
+				   SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ *  LookupIDByType returns the object with the given id and type, else NULL.
+ */ 
+pointer
+LookupIDByType(id, rtype)
+    XID id;
+    RESTYPE rtype;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+/*
+ *  LookupIDByClass returns the object with the given id and any one of the
+ *  given classes, else NULL.
+ */ 
+pointer
+LookupIDByClass(id, classes)
+    XID id;
+    RESTYPE classes;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXresource.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c.XF86.original
new file mode 100644
index 000000000..d17586a77
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXresource.c.XF86.original
@@ -0,0 +1,975 @@
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+********************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/*	Routines to manage various kinds of resources:
+ *
+ *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ *	FakeClientID, AddResource, FreeResource, FreeClientResources,
+ *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/* 
+ *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ *	off-limits for client-visible resources.  The next 8 bits are
+ *      used as client ID, and the low 22 bits come from the client.
+ *	A resource ID is "hashed" by extracting and xoring subfields
+ *      (varying with the size of the hash table).
+ *
+ *      It is sometimes necessary for the server to create an ID that looks
+ *      like it belongs to a client.  This ID, however,  must not be one
+ *      the client actually can create, or we have the potential for conflict.
+ *      The 31st bit of the ID is reserved for the server's use for this
+ *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ *      resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.12 2002/03/06 21:13:38 mvojkovi Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h" 
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+static void RebuildTable(
+#if NeedFunctionPrototypes
+    int /*client*/
+#endif
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+    struct _Resource	*next;
+    XID			id;
+    RESTYPE		type;
+    pointer		value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+    ResourcePtr *resources;
+    int		elements;
+    int		buckets;
+    int		hashsize;	/* log(2)(buckets) */
+    XID		fakeID;
+    XID		endFakeID;
+    XID		expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(deleteFunc)
+    DeleteType deleteFunc;
+{
+    RESTYPE next = lastResourceType + 1;
+    DeleteType *funcs;
+
+    if (next & lastResourceClass)
+	return 0;
+    funcs = (DeleteType *)xrealloc(DeleteFuncs,
+				   (next + 1) * sizeof(DeleteType));
+    if (!funcs)
+	return 0;
+
+#ifdef XResExtension
+    {
+       Atom *newnames;
+       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+       if(!newnames)
+           return 0;
+       ResourceNames = newnames;
+       ResourceNames[next] = 0;
+    }
+#endif
+
+    lastResourceType = next;
+    DeleteFuncs = funcs;
+    DeleteFuncs[next] = deleteFunc;
+    return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+    RESTYPE next = lastResourceClass >> 1;
+
+    if (next & lastResourceType)
+	return 0;
+    lastResourceClass = next;
+    TypeMask = next - 1;
+    return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ *    When a new client is created, call this to allocate space
+ *    in resource table
+ *****************/
+
+Bool
+InitClientResources(client)
+    ClientPtr client;
+{
+    register int i, j;
+ 
+    if (client == serverClient)
+    {
+	lastResourceType = RT_LASTPREDEF;
+	lastResourceClass = RC_LASTPREDEF;
+	TypeMask = RC_LASTPREDEF - 1;
+	if (DeleteFuncs)
+	    xfree(DeleteFuncs);
+	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+					   sizeof(DeleteType));
+	if (!DeleteFuncs)
+	    return FALSE;
+	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+        if(ResourceNames)
+            xfree(ResourceNames);
+        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+        if(!ResourceNames)
+           return FALSE;
+#endif
+    }
+    clientTable[i = client->index].resources =
+	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+    if (!clientTable[i].resources)
+	return FALSE;
+    clientTable[i].buckets = INITBUCKETS;
+    clientTable[i].elements = 0;
+    clientTable[i].hashsize = INITHASHSIZE;
+    /* Many IDs allocated from the server client are visible to clients,
+     * so we don't use the SERVER_BIT for them, but we have to start
+     * past the magic value constants used in the protocol.  For normal
+     * clients, we can start from zero, with SERVER_BIT set.
+     */
+    clientTable[i].fakeID = client->clientAsMask |
+			    (client->index ? SERVER_BIT : SERVER_MINID);
+    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+    clientTable[i].expectID = client->clientAsMask;
+    for (j=0; j<INITBUCKETS; j++) 
+    {
+        clientTable[i].resources[j] = NullResource;
+    }
+    return TRUE;
+}
+
+
+static int
+#if NeedFunctionPrototypes
+Hash(int client, register XID id)
+#else
+Hash(client, id)
+    int client;
+    register XID id;
+#endif
+{
+    id &= RESOURCE_ID_MASK;
+    switch (clientTable[client].hashsize)
+    {
+	case 6:
+	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+	case 7:
+	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+	case 8:
+	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+	case 9:
+	    return ((int)(0x1FF & (id ^ (id>>9))));
+	case 10:
+	    return ((int)(0x3FF & (id ^ (id>>10))));
+	case 11:
+	    return ((int)(0x7FF & (id ^ (id>>11))));
+    }
+    return -1;
+}
+
+static XID
+#if NeedFunctionPrototypes
+AvailableID(
+    register int client,
+    register XID id,
+    register XID maxid,
+    register XID goodid)
+#else
+AvailableID(client, id, maxid, goodid)
+    register int client;
+    register XID id, maxid, goodid;
+#endif
+{
+    register ResourcePtr res;
+
+    if ((goodid >= id) && (goodid <= maxid))
+	return goodid;
+    for (; id <= maxid; id++)
+    {
+	res = clientTable[client].resources[Hash(client, id)];
+	while (res && (res->id != id))
+	    res = res->next;
+	if (!res)
+	    return id;
+    }
+    return 0;
+}
+
+void
+GetXIDRange(client, server, minp, maxp)
+    int client;
+    Bool server;
+    XID *minp, *maxp;
+{
+    register XID id, maxid;
+    register ResourcePtr *resp;
+    register ResourcePtr res;
+    register int i;
+    XID goodid;
+
+    id = (Mask)client << CLIENTOFFSET;
+    if (server)
+	id |= client ? SERVER_BIT : SERVER_MINID;
+    maxid = id | RESOURCE_ID_MASK;
+    goodid = 0;
+    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+	 --i >= 0;)
+    {
+	for (res = *resp++; res; res = res->next)
+	{
+	    if ((res->id < id) || (res->id > maxid))
+		continue;
+	    if (((res->id - id) >= (maxid - res->id)) ?
+		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
+		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+		maxid = res->id - 1;
+	    else
+		id = res->id + 1;
+	}
+    }
+    if (id > maxid)
+	id = maxid = 0;
+    *minp = id;
+    *maxp = maxid;
+}
+
+/*  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ *  This function tries to find count unused XIDs for the given client.  It 
+ *  puts the IDs in the array pids and returns the number found, which should
+ *  almost always be the number requested.
+ *
+ *  The circumstances that lead to a call to this function are very rare.
+ *  Xlib must run out of IDs while trying to generate a request that wants
+ *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ *  No rocket science in the implementation; just iterate over all
+ *  possible IDs for the given client and pick the first count IDs
+ *  that aren't in use.  A more efficient algorithm could probably be
+ *  invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(pClient, count, pids)
+    ClientPtr pClient;
+    unsigned int count;
+    XID *pids;
+{
+    unsigned int found = 0;
+    XID id = pClient->clientAsMask;
+    XID maxid;
+
+    maxid = id | RESOURCE_ID_MASK;
+    while ( (found < count) && (id <= maxid) )
+    {
+	if (!LookupIDByClass(id, RC_ANY))
+	{
+	    pids[found++] = id;
+	}
+	id++;
+    }
+    return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(client)
+    register int client;
+{
+    XID id, maxid;
+
+    id = clientTable[client].fakeID++;
+    if (id != clientTable[client].endFakeID)
+	return id;
+    GetXIDRange(client, TRUE, &id, &maxid);
+    if (!id) {
+	if (!client)
+	    FatalError("FakeClientID: server internal ids exhausted\n");
+	MarkClientException(clients[client]);
+	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+	maxid = id | RESOURCE_ID_MASK;
+    }
+    clientTable[client].fakeID = id + 1;
+    clientTable[client].endFakeID = maxid + 1;
+    return id;
+}
+
+Bool
+AddResource(id, type, value)
+    XID id;
+    RESTYPE type;
+    pointer value;
+{
+    int client;
+    register ClientResourceRec *rrec;
+    register ResourcePtr res, *head;
+    	
+    client = CLIENT_ID(id);
+    rrec = &clientTable[client];
+    if (!rrec->buckets)
+    {
+	ErrorF("AddResource(%x, %x, %x), client=%d \n",
+		id, type, (unsigned long)value, client);
+        FatalError("client not in use\n");
+    }
+    if ((rrec->elements >= 4*rrec->buckets) &&
+	(rrec->hashsize < MAXHASHSIZE))
+	RebuildTable(client);
+    head = &rrec->resources[Hash(client, id)];
+    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+    if (!res)
+    {
+	(*DeleteFuncs[type & TypeMask])(value, id);
+	return FALSE;
+    }
+    res->next = *head;
+    res->id = id;
+    res->type = type;
+    res->value = value;
+    *head = res;
+    rrec->elements++;
+    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+	rrec->expectID = id + 1;
+    return TRUE;
+}
+
+static void
+RebuildTable(client)
+    int client;
+{
+    register int j;
+    register ResourcePtr res, next;
+    ResourcePtr **tails, *resources;
+    register ResourcePtr **tptr, *rptr;
+
+    /*
+     * For now, preserve insertion order, since some ddx layers depend
+     * on resources being free in the opposite order they are added.
+     */
+
+    j = 2 * clientTable[client].buckets;
+    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+    if (!tails)
+	return;
+    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+    if (!resources)
+    {
+	DEALLOCATE_LOCAL(tails);
+	return;
+    }
+    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+    {
+	*rptr = NullResource;
+	*tptr = rptr;
+    }
+    clientTable[client].hashsize++;
+    for (j = clientTable[client].buckets,
+	 rptr = clientTable[client].resources;
+	 --j >= 0;
+	 rptr++)
+    {
+	for (res = *rptr; res; res = next)
+	{
+	    next = res->next;
+	    res->next = NullResource;
+	    tptr = &tails[Hash(client, res->id)];
+	    **tptr = res;
+	    *tptr = &res->next;
+	}
+    }
+    DEALLOCATE_LOCAL(tails);
+    clientTable[client].buckets *= 2;
+    xfree(clientTable[client].resources);
+    clientTable[client].resources = resources;
+}
+
+void
+FreeResource(id, skipDeleteFuncType)
+    XID id;
+    RESTYPE skipDeleteFuncType;
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    register	int *eltptr;
+    int		elements;
+    Bool	gotOne = FALSE;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+	eltptr = &clientTable[cid].elements;
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id)
+	    {
+		RESTYPE rtype = res->type;
+		*prev = res->next;
+		elements = --*eltptr;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (rtype != skipDeleteFuncType)
+		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+		xfree(res);
+		if (*eltptr != elements)
+		    prev = head; /* prev may no longer be valid */
+		gotOne = TRUE;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+    if (!gotOne)
+	FatalError("Freeing resource id=%X which isn't there", id);
+}
+
+
+void
+FreeResourceByType(id, type, skipFree)
+    XID id;
+    RESTYPE type;
+    Bool    skipFree;
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id && res->type == type)
+	    {
+		*prev = res->next;
+		if (type & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (!skipFree)
+		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+		xfree(res);
+		break;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+}
+
+/*
+ * Change the value associated with a resource id.  Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (id, rtype, value)
+    XID	id;
+    RESTYPE rtype;
+    pointer value;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		res->value = value;
+		return TRUE;
+	    }
+    }
+    return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources.  If func adds new resources,
+ * func might or might not get called for them.  func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+    ClientPtr client,
+    RESTYPE type,
+    FindResType func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++) 
+    {
+        for (this = resources[i]; this; this = next)
+	{
+	    next = this->next;
+	    if (!type || this->type == type) {
+		elements = *eltptr;
+		(*func)(this->value, this->id, cdata);
+		if (*eltptr != elements)
+		    next = resources[i]; /* start over */
+	    }
+	}
+    }
+}
+
+void
+FindAllClientResources(
+    ClientPtr client,
+    FindAllRes func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+        client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++)
+    {
+        for (this = resources[i]; this; this = next)
+        {
+            next = this->next;
+            elements = *eltptr;
+            (*func)(this->value, this->id, this->type, cdata);
+            if (*eltptr != elements)
+                next = resources[i]; /* start over */
+        }
+    }
+}
+
+
+pointer
+LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata
+){
+    ResourcePtr *resources;
+    ResourcePtr this;
+    int i;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    for (i = 0; i < clientTable[client->index].buckets; i++) {
+        for (this = resources[i]; this; this = this->next) {
+	    if (!type || this->type == type) {
+		if((*func)(this->value, this->id, cdata))
+		    return this->value;
+	    }
+	}
+    }
+    return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+    ResourcePtr *resources;
+    ResourcePtr this;
+    ResourcePtr *prev;
+    int j;
+
+    if (!client)
+	return;
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+	prev = &resources[j];
+        while ( (this = *prev) )
+	{
+	    RESTYPE rtype = this->type;
+	    if (rtype & RC_NEVERRETAIN)
+	    {
+		*prev = this->next;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(this->id);
+		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+		xfree(this);	    
+	    }
+	    else
+		prev = &this->next;
+	}
+    }
+}
+
+void
+FreeClientResources(client)
+    ClientPtr client;
+{
+    register ResourcePtr *resources;
+    register ResourcePtr this;
+    int j;
+
+    /* This routine shouldn't be called with a null client, but just in
+	case ... */
+
+    if (!client)
+	return;
+
+    HandleSaveSet(client);
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+        /* It may seem silly to update the head of this resource list as
+	we delete the members, since the entire list will be deleted any way, 
+	but there are some resource deletion functions "FreeClientPixels" for 
+	one which do a LookupID on another resource id (a Colormap id in this
+	case), so the resource list must be kept valid up to the point that
+	it is deleted, so every time we delete a resource, we must update the
+	head, just like in FreeResource. I hope that this doesn't slow down
+	mass deletion appreciably. PRH */
+
+	ResourcePtr *head;
+
+	head = &resources[j];
+
+        for (this = *head; this; this = *head)
+	{
+	    RESTYPE rtype = this->type;
+	    *head = this->next;
+	    if (rtype & RC_CACHED)
+		FlushClientCaches(this->id);
+	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+	    xfree(this);	    
+	}
+    }
+    xfree(clientTable[client->index].resources);
+    clientTable[client->index].resources = NULL;
+    clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+    int	i;
+
+    for (i = currentMaxClients; --i >= 0; ) 
+    {
+        if (clientTable[i].buckets) 
+	    FreeClientResources(clients[i]);
+    }
+}
+
+Bool
+LegalNewID(id, client)
+    XID id;
+    register ClientPtr client;
+{
+
+#ifdef PANORAMIX
+    XID 	minid, maxid;
+
+	if (!noPanoramiXExtension) { 
+	    minid = client->clientAsMask | (client->index ? 
+			                    SERVER_BIT : SERVER_MINID);
+	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+            if ((id >= minid) && (id <= maxid))
+	        return TRUE;
+	}
+#endif /* PANORAMIX */
+	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+	    ((clientTable[client->index].expectID <= id) ||
+	     !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system.  They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(client, id, rtype, mode)
+    ClientPtr client;
+    XID id;
+    RESTYPE rtype;
+    Mask mode;
+{
+    int    cid;
+    register    ResourcePtr res;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert( (rtype & TypeMask) <= lastResourceType);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+    return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(client, id, classes, mode)
+    ClientPtr client;
+    XID id;
+    RESTYPE classes;
+    Mask mode;
+{
+    int    cid;
+    register ResourcePtr res = NULL;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert (classes >= lastResourceClass);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+    return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(id, rtype)
+    XID id;
+    RESTYPE rtype;
+{
+    return SecurityLookupIDByType(NullClient, id, rtype,
+				  SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(id, classes)
+    XID id;
+    RESTYPE classes;
+{
+    return SecurityLookupIDByClass(NullClient, id, classes,
+				   SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ *  LookupIDByType returns the object with the given id and type, else NULL.
+ */ 
+pointer
+LookupIDByType(id, rtype)
+    XID id;
+    RESTYPE rtype;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+/*
+ *  LookupIDByClass returns the object with the given id and any one of the
+ *  given classes, else NULL.
+ */ 
+pointer
+LookupIDByClass(id, classes)
+    XID id;
+    RESTYPE classes;
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c
new file mode 100644
index 000000000..e70415a7d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c
@@ -0,0 +1,1425 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXshm.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.36 2002/04/03 19:51:11 herrb Exp $ */
+/************************************************************
+
+Copyright 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#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 "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include "shmstr.h"
+#include "Xfuncproto.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "Trap.h"
+#include "Agent.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
+                           unsigned int format, unsigned long planeMask, char *d);
+
+extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+                            int x, int y, int w, int h, int leftPad, int format,
+                                char *pImage);
+
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+#if NeedFunctionPrototypes
+    pointer		/* value */,
+    XID			/* shmseg */
+#endif
+    );
+static void ShmResetProc(
+#if NeedFunctionPrototypes
+    ExtensionEntry *	/* extEntry */
+#endif
+    );
+static void SShmCompletionEvent(
+#if NeedFunctionPrototypes
+    xShmCompletionEvent * /* from */,
+    xShmCompletionEvent * /* to */
+#endif
+    );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int  shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+    shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+    if (!shmdesc) \
+    { \
+	client->errorValue = shmseg; \
+	return BadShmSegCode; \
+    } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+    VERIFY_SHMSEG(shmseg, shmdesc, client); \
+    if ((offset & 3) || (offset > shmdesc->size)) \
+    { \
+	client->errorValue = offset; \
+	return BadValue; \
+    } \
+    if (needwrite && !shmdesc->writable) \
+	return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+    if ((offset + len) > shmdesc->size) \
+    { \
+	return BadAccess; \
+    } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+    badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+    void (*oldHandler)();
+    int shmid = -1;
+
+    /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+    oldHandler = signal(SIGSYS, SigSysHandler);
+
+    badSysCall = FALSE;
+    shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+    /* Clean up */
+    if (shmid != -1)
+    {
+	shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+    }
+    signal(SIGSYS, oldHandler);
+    return(!badSysCall);
+}
+#endif
+    
+void
+ShmExtensionInit()
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+    if (!CheckForShmSyscall())
+    {
+	ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+	return;
+    }
+#endif
+
+    if (nxagentOption(SharedMemory) == False)
+    {
+      return;
+    }
+
+    sharedPixmaps = xFalse;
+    pixmapFormat = 0;
+    {
+      sharedPixmaps = nxagentOption(SharedPixmaps);
+      pixmapFormat = shmPixFormat[0];
+      for (i = 0; i < screenInfo.numScreens; i++)
+      {
+	if (!shmFuncs[i])
+        {
+            #ifdef TEST
+            fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
+            #endif
+	    shmFuncs[i] = &miFuncs;
+        }
+	if (!shmFuncs[i]->CreatePixmap)
+	    sharedPixmaps = xFalse;
+	if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+	{
+	    sharedPixmaps = xFalse;
+	    pixmapFormat = 0;
+	}
+      }
+      if (!pixmapFormat)
+	pixmapFormat = ZPixmap;
+      if (sharedPixmaps)
+      {
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+	    screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+	}
+#ifdef PIXPRIV
+	shmPixmapPrivate = AllocatePixmapPrivateIndex();
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    if (!AllocatePixmapPrivate(screenInfo.screens[i],
+				       shmPixmapPrivate, 0))
+		return;
+	}
+#endif
+      }
+    }
+    ShmSegType = CreateNewResourceType(ShmDetachSegment);
+    if (ShmSegType &&
+	(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+				 ProcShmDispatch, SProcShmDispatch,
+				 ShmResetProc, StandardMinorOpcode)))
+    {
+	ShmReqCode = (unsigned char)extEntry->base;
+	ShmCompletionCode = extEntry->eventBase;
+	BadShmSegCode = extEntry->errorBase;
+	EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+    }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry	*extEntry;
+{
+    int i;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+	shmFuncs[i] = (ShmFuncsPtr)NULL;
+	shmPixFormat[i] = 0;
+    }
+}
+
+void
+ShmRegisterFuncs(pScreen, funcs)
+    ScreenPtr pScreen;
+    ShmFuncsPtr funcs;
+{
+    shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(pScreen, format)
+    ScreenPtr pScreen;
+    int format;
+{
+    shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	    pScreen = pPixmap->drawable.pScreen;
+    Bool	    ret;
+    if (pPixmap->refcnt == 1)
+    {
+	ShmDescPtr  shmdesc;
+#ifdef PIXPRIV
+	shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+	char	*base = (char *) pPixmap->devPrivate.ptr;
+	
+	if (base != (pointer) (pPixmap + 1))
+	{
+	    for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+	    {
+		if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+		    break;
+	    }
+	}
+	else
+	    shmdesc = 0;
+#endif
+	if (shmdesc)
+	    ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+    }
+    
+    pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+    ret = (*pScreen->DestroyPixmap) (pPixmap);
+    destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+    pScreen->DestroyPixmap = ShmDestroyPixmap;
+    return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+    ScreenPtr pScreen;
+{
+    #ifdef TEST
+    fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+    #endif
+    shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+    register ClientPtr client;
+{
+    xShmQueryVersionReply rep;
+    register int n;
+
+    REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.sharedPixmaps = sharedPixmaps;
+    rep.pixmapFormat = pixmapFormat;
+    rep.majorVersion = SHM_MAJOR_VERSION;
+    rep.minorVersion = SHM_MINOR_VERSION;
+    rep.uid = geteuid();
+    rep.gid = getegid();
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+	swaps(&rep.uid, n);
+	swaps(&rep.gid, n);
+    }
+    WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+    int uid, gid;
+    mode_t mask;
+
+    if (LocalClientCred(client, &uid, &gid) != -1) {
+	
+	/* User id 0 always gets access */
+	if (uid == 0) {
+	    return 0;
+	}
+	/* Check the owner */
+	if (perm->uid == uid || perm->cuid == uid) {
+	    mask = S_IRUSR;
+	    if (!readonly) {
+		mask |= S_IWUSR;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+	/* Check the group */
+	if (perm->gid == gid || perm->cgid == gid) {
+	    mask = S_IRGRP;
+	    if (!readonly) {
+		mask |= S_IWGRP;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+    }
+    /* Otherwise, check everyone else */
+    mask = S_IROTH;
+    if (!readonly) {
+	mask |= S_IWOTH;
+    }
+    return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+    register ClientPtr client;
+{
+    struct shmid_ds buf;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmAttachReq);
+
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+    if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+    {
+	client->errorValue = stuff->readOnly;
+        return(BadValue);
+    }
+    for (shmdesc = Shmsegs;
+	 shmdesc && (shmdesc->shmid != stuff->shmid);
+	 shmdesc = shmdesc->next)
+	;
+    if (shmdesc)
+    {
+	if (!stuff->readOnly && !shmdesc->writable)
+	    return BadAccess;
+	shmdesc->refcnt++;
+    }
+    else
+    {
+	shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+	if (!shmdesc)
+	    return BadAlloc;
+	shmdesc->addr = shmat(stuff->shmid, 0,
+			      stuff->readOnly ? SHM_RDONLY : 0);
+	if ((shmdesc->addr == ((char *)-1)) ||
+	    shmctl(stuff->shmid, IPC_STAT, &buf))
+	{
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	/* The attach was performed with root privs. We must
+	 * do manual checking of access rights for the credentials 
+	 * of the client */
+
+	if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+	    shmdt(shmdesc->addr);
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	shmdesc->shmid = stuff->shmid;
+	shmdesc->refcnt = 1;
+	shmdesc->writable = !stuff->readOnly;
+	shmdesc->size = buf.shm_segsz;
+	shmdesc->next = Shmsegs;
+	Shmsegs = shmdesc;
+    }
+    if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+	return BadAlloc;
+    return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+    pointer value; /* must conform to DeleteType */
+    XID shmseg;
+{
+    ShmDescPtr shmdesc = (ShmDescPtr)value;
+    ShmDescPtr *prev;
+
+    if (--shmdesc->refcnt)
+	return TRUE;
+    shmdt(shmdesc->addr);
+    for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+	;
+    *prev = shmdesc->next;
+    xfree(shmdesc);
+    return Success;
+}
+
+static int
+ProcShmDetach(client)
+    register ClientPtr client;
+{
+    ShmDescPtr shmdesc;
+    REQUEST(xShmDetachReq);
+
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+    FreeResource(stuff->shmseg, RT_NONE);
+    return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    PixmapPtr pmap;
+    GCPtr putGC;
+
+    nxagentShmTrap = 0;
+    putGC = GetScratchGC(depth, dst->pScreen);
+    if (!putGC)
+    {
+        nxagentShmTrap = 1;
+	return;
+    }
+    pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+    if (!pmap)
+    {
+        nxagentShmTrap = 1;
+	FreeScratchGC(putGC);
+	return;
+    }
+    ValidateGC((DrawablePtr)pmap, putGC);
+    (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+			    (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+    FreeScratchGC(putGC);
+    if (format == XYBitmap)
+	(void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				     dx, dy, 1L);
+    else
+	(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				    dx, dy);
+    (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+    nxagentShmTrap = 1;
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    int length;
+    char *newdata;
+    extern int nxagentImageLength(int, int, int, int, int);
+
+    #ifdef TEST
+    fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
+                (void *) dst, (void *) pGC, (void *) data);
+    #endif
+
+    if ((format == ZPixmap) || (depth == 1))
+    {
+	PixmapPtr pPixmap;
+
+	pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+		BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+	if (!pPixmap)
+	    return;
+	if (format == XYBitmap)
+	    (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+					 sx, sy, sw, sh, dx, dy, 1L);
+	else
+	    (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+					sx, sy, sw, sh, dx, dy);
+
+        /*
+         * We updated the internal framebuffer,
+         * now we want to go on the real X.
+         */
+
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
+                    " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
+                        " sh [%d] dx [%d].\n", depth, format, w, h,
+                            sx, sy, sw, sh, dx);
+        #endif
+
+        length = nxagentImageLength(sw, sh, format, 0, depth);
+
+        if ((newdata = xalloc(length)) != NULL)
+        {
+          fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
+          (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
+
+          xfree(newdata);
+        }
+        else
+        {
+          #ifdef WARNING
+          fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
+          #endif
+        }
+
+	FreeScratchPixmapHeader(pPixmap);
+    }
+    else
+    {
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
+        #endif
+	miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+		      data);
+    }
+}
+
+
+#ifdef PANORAMIX
+static int 
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+    int			 j, result = 0, orig_x, orig_y;
+    PanoramiXRes	*draw, *gc;
+    Bool		 sendEvent, isRoot;
+
+    REQUEST(xShmPutImageReq);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+		(stuff->drawable == WindowTable[0]->drawable.id);
+
+    orig_x = stuff->dstX;
+    orig_y = stuff->dstY;
+    sendEvent = stuff->sendEvent;
+    stuff->sendEvent = 0;
+    FOR_NSCREENS(j) {
+	if(!j) stuff->sendEvent = sendEvent;
+	stuff->drawable = draw->info[j].id;
+	stuff->gc = gc->info[j].id;
+	if (isRoot) {
+	    stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+	    stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+	}
+	result = ProcShmPutImage(client);
+	if(result != client->noClientException) break;
+    }
+    return(result);
+}
+
+static int 
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+    PanoramiXRes	*draw;
+    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	pDraw;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int         	i, x, y, w, h, format;
+    Mask		plane = 0, planemask;
+    long		lenPer = 0, length, widthBytesLine;
+    Bool		isRoot;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+
+    if (draw->type == XRT_PIXMAP)
+	return ProcShmGetImage(client);
+
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+    x = stuff->x;
+    y = stuff->y;
+    w = stuff->width;
+    h = stuff->height;
+    format = stuff->format;
+    planemask = stuff->planeMask;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+		(stuff->drawable == WindowTable[0]->drawable.id);
+
+    if(isRoot) {
+      if( /* check for being onscreen */
+	x < 0 || x + w > PanoramiXPixWidth ||
+	y < 0 || y + h > PanoramiXPixHeight )
+	    return(BadMatch);
+    } else {
+      if( /* check for being onscreen */
+	panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+	panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+        panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+	panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+	 /* check for being inside of border */
+       	x < - wBorderWidth((WindowPtr)pDraw) ||
+	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+	y < -wBorderWidth((WindowPtr)pDraw) ||
+	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+	    return(BadMatch);
+    }
+
+    drawables[0] = pDraw;
+    for(i = 1; i < PanoramiXNumScreens; i++)
+	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+    xgi.visual = wVisual(((WindowPtr)pDraw));
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+
+    if(format == ZPixmap) {
+	widthBytesLine = PixmapBytePad(w, pDraw->depth);
+	length = widthBytesLine * h;
+    } else {
+	widthBytesLine = PixmapBytePad(w, 1);
+	lenPer = widthBytesLine * h;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	length = lenPer * Ones(planemask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0) {/* nothing to do */ }
+    else if (format == ZPixmap) {
+	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+					shmdesc->addr + stuff->offset,
+					widthBytesLine, isRoot);
+    } else {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1) {
+	    if (planemask & plane) {
+		XineramaGetImageData(drawables, x, y, w, h, 
+				     format, plane, shmdesc->addr + length,
+				     widthBytesLine, isRoot);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+	register int n;
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    ScreenPtr pScreen = NULL;
+    PixmapPtr pMap = NULL;
+    DrawablePtr pDraw;
+    DepthPtr pDepth;
+    int i, j, result;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+    PanoramiXRes *newPix;
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+
+    if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+
+    newPix->type = XRT_PIXMAP;
+    newPix->u.pix.shared = TRUE;
+    newPix->info[0].id = stuff->pid;
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPix->info[j].id = FakeClientID(client->index);
+
+    result = (client->noClientException);
+
+    FOR_NSCREENS(j) {
+	pScreen = screenInfo.screens[j];
+
+	pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, 
+				stuff->width, stuff->height, stuff->depth,
+				shmdesc->addr + stuff->offset);
+
+	if (pMap) {
+#ifdef PIXPRIV
+            pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+            shmdesc->refcnt++;
+	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    pMap->drawable.id = newPix->info[j].id;
+	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
+		(*pScreen->DestroyPixmap)(pMap);
+		result = BadAlloc;
+		break;
+	    }
+	} else {
+	   result = BadAlloc;
+	   break;
+	}
+    }
+
+    if(result == BadAlloc) {
+	while(j--) {
+	    (*pScreen->DestroyPixmap)(pMap);
+	    FreeResource(newPix->info[j].id, RT_NONE);
+	}
+	xfree(newPix);
+    } else 
+	AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+    return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+    register ClientPtr client;
+{
+    register GCPtr pGC;
+    register DrawablePtr pDraw;
+    long length;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmPutImageReq);
+
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+    if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+	return BadValue;
+    if (stuff->format == XYBitmap)
+    {
+        if (stuff->depth != 1)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+	length *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
+    if (stuff->srcX > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcX;
+	return BadValue;
+    }
+    if (stuff->srcY > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcY;
+	return BadValue;
+    }
+    if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcWidth;
+	return BadValue;
+    }
+    if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcHeight;
+	return BadValue;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
+                "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
+                    stuff->srcY, stuff->totalWidth, stuff->totalHeight);
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
+    #endif
+
+    (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+                               pDraw, pGC, stuff->depth, stuff->format,
+                               stuff->totalWidth, stuff->totalHeight,
+                               stuff->srcX, stuff->srcY,
+                               stuff->srcWidth, stuff->srcHeight,
+                               stuff->dstX, stuff->dstY,
+                               shmdesc->addr + stuff->offset);
+
+    if (stuff->sendEvent)
+    {
+	xShmCompletionEvent ev;
+
+	ev.type = ShmCompletionCode;
+	ev.drawable = stuff->drawable;
+	ev.sequenceNumber = client->sequence;
+	ev.minorEvent = X_ShmPutImage;
+	ev.majorEvent = ShmReqCode;
+	ev.shmseg = stuff->shmseg;
+	ev.offset = stuff->offset;
+	WriteEventsToClient(client, 1, (xEvent *) &ev);
+    }
+
+    return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDraw;
+    long		lenPer = 0, length;
+    Mask		plane = 0;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int			n;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+    {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + stuff->x < 0 ||
+ 	 pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+         pDraw->y + stuff->y < 0 ||
+         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+         stuff->x + (int)stuff->width >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+         stuff->y + (int)stuff->height >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual(((WindowPtr)pDraw));
+    }
+    else
+    {
+	if (stuff->x < 0 ||
+	    stuff->x+(int)stuff->width > pDraw->width ||
+	    stuff->y < 0 ||
+	    stuff->y+(int)stuff->height > pDraw->height
+	    )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(stuff->format == ZPixmap)
+    {
+	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+    }
+    else 
+    {
+	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0)
+    {
+	/* nothing to do */
+    }
+    else if (stuff->format == ZPixmap)
+    {
+	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+				    stuff->width, stuff->height,
+				    stuff->format, stuff->planeMask,
+				    shmdesc->addr + stuff->offset);
+    }
+    else
+    {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1)
+	{
+	    if (stuff->planeMask & plane)
+	    {
+		(*pDraw->pScreen->GetImage)(pDraw,
+					    stuff->x, stuff->y,
+					    stuff->width, stuff->height,
+					    stuff->format, plane,
+					    shmdesc->addr + length);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+    ScreenPtr	pScreen;
+    int		width;
+    int		height;
+    int		depth;
+    char	*addr;
+{
+    register PixmapPtr pPixmap;
+
+    nxagentShmPixmapTrap = 1;
+
+    pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth);
+
+    if (!pPixmap)
+    {
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    #ifdef TEST
+    fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth);
+    #endif
+
+    if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) 
+    {
+      #ifdef WARNING
+      fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
+      #endif
+
+      (*pScreen->DestroyPixmap)(pPixmap);
+
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    nxagentShmPixmapTrap = 0;
+
+    return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    DepthPtr pDepth;
+    register int i;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+    pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+			    pDraw->pScreen, stuff->width,
+			    stuff->height, stuff->depth,
+			    shmdesc->addr + stuff->offset);
+    if (pMap)
+    {
+#ifdef PIXPRIV
+	pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+	shmdesc->refcnt++;
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	{
+	    return(client->noClientException);
+	}
+    }
+    return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return ProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return ProcShmAttach(client);
+    case X_ShmDetach:
+	return ProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+        {
+           result = ProcPanoramiXShmPutImage(client);
+
+           nxagentShmTrap = 0;
+
+           return result;
+        }
+#endif
+
+        result = ProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmGetImage(client);
+#endif
+	return ProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmCreatePixmap(client);
+#endif
+	   return ProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static void
+SShmCompletionEvent(from, to)
+    xShmCompletionEvent *from, *to;
+{
+    to->type = from->type;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->drawable, to->drawable);
+    cpswaps(from->minorEvent, to->minorEvent);
+    to->majorEvent = from->majorEvent;
+    cpswapl(from->shmseg, to->shmseg);
+    cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+    register ClientPtr	client;
+{
+    register int n;
+    REQUEST(xShmQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmAttachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->shmid, n);
+    return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmDetachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    swapl(&stuff->shmseg, n);
+    return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmPutImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->gc, n);
+    swaps(&stuff->totalWidth, n);
+    swaps(&stuff->totalHeight, n);
+    swaps(&stuff->srcX, n);
+    swaps(&stuff->srcY, n);
+    swaps(&stuff->srcWidth, n);
+    swaps(&stuff->srcHeight, n);
+    swaps(&stuff->dstX, n);
+    swaps(&stuff->dstY, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmGetImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->planeMask, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmCreatePixmapReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return SProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return SProcShmAttach(client);
+    case X_ShmDetach:
+	return SProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+        result = SProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+	return SProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+	return SProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c.NX.original
new file mode 100644
index 000000000..e70415a7d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c.NX.original
@@ -0,0 +1,1425 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXshm.c"
+
+#else
+
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.36 2002/04/03 19:51:11 herrb Exp $ */
+/************************************************************
+
+Copyright 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#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 "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include "shmstr.h"
+#include "Xfuncproto.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "Trap.h"
+#include "Agent.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
+                           unsigned int format, unsigned long planeMask, char *d);
+
+extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+                            int x, int y, int w, int h, int leftPad, int format,
+                                char *pImage);
+
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+#if NeedFunctionPrototypes
+    pointer		/* value */,
+    XID			/* shmseg */
+#endif
+    );
+static void ShmResetProc(
+#if NeedFunctionPrototypes
+    ExtensionEntry *	/* extEntry */
+#endif
+    );
+static void SShmCompletionEvent(
+#if NeedFunctionPrototypes
+    xShmCompletionEvent * /* from */,
+    xShmCompletionEvent * /* to */
+#endif
+    );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int  shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+    shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+    if (!shmdesc) \
+    { \
+	client->errorValue = shmseg; \
+	return BadShmSegCode; \
+    } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+    VERIFY_SHMSEG(shmseg, shmdesc, client); \
+    if ((offset & 3) || (offset > shmdesc->size)) \
+    { \
+	client->errorValue = offset; \
+	return BadValue; \
+    } \
+    if (needwrite && !shmdesc->writable) \
+	return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+    if ((offset + len) > shmdesc->size) \
+    { \
+	return BadAccess; \
+    } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+    badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+    void (*oldHandler)();
+    int shmid = -1;
+
+    /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+    oldHandler = signal(SIGSYS, SigSysHandler);
+
+    badSysCall = FALSE;
+    shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+    /* Clean up */
+    if (shmid != -1)
+    {
+	shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+    }
+    signal(SIGSYS, oldHandler);
+    return(!badSysCall);
+}
+#endif
+    
+void
+ShmExtensionInit()
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+    if (!CheckForShmSyscall())
+    {
+	ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+	return;
+    }
+#endif
+
+    if (nxagentOption(SharedMemory) == False)
+    {
+      return;
+    }
+
+    sharedPixmaps = xFalse;
+    pixmapFormat = 0;
+    {
+      sharedPixmaps = nxagentOption(SharedPixmaps);
+      pixmapFormat = shmPixFormat[0];
+      for (i = 0; i < screenInfo.numScreens; i++)
+      {
+	if (!shmFuncs[i])
+        {
+            #ifdef TEST
+            fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
+            #endif
+	    shmFuncs[i] = &miFuncs;
+        }
+	if (!shmFuncs[i]->CreatePixmap)
+	    sharedPixmaps = xFalse;
+	if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+	{
+	    sharedPixmaps = xFalse;
+	    pixmapFormat = 0;
+	}
+      }
+      if (!pixmapFormat)
+	pixmapFormat = ZPixmap;
+      if (sharedPixmaps)
+      {
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+	    screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+	}
+#ifdef PIXPRIV
+	shmPixmapPrivate = AllocatePixmapPrivateIndex();
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    if (!AllocatePixmapPrivate(screenInfo.screens[i],
+				       shmPixmapPrivate, 0))
+		return;
+	}
+#endif
+      }
+    }
+    ShmSegType = CreateNewResourceType(ShmDetachSegment);
+    if (ShmSegType &&
+	(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+				 ProcShmDispatch, SProcShmDispatch,
+				 ShmResetProc, StandardMinorOpcode)))
+    {
+	ShmReqCode = (unsigned char)extEntry->base;
+	ShmCompletionCode = extEntry->eventBase;
+	BadShmSegCode = extEntry->errorBase;
+	EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+    }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry	*extEntry;
+{
+    int i;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+	shmFuncs[i] = (ShmFuncsPtr)NULL;
+	shmPixFormat[i] = 0;
+    }
+}
+
+void
+ShmRegisterFuncs(pScreen, funcs)
+    ScreenPtr pScreen;
+    ShmFuncsPtr funcs;
+{
+    shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(pScreen, format)
+    ScreenPtr pScreen;
+    int format;
+{
+    shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	    pScreen = pPixmap->drawable.pScreen;
+    Bool	    ret;
+    if (pPixmap->refcnt == 1)
+    {
+	ShmDescPtr  shmdesc;
+#ifdef PIXPRIV
+	shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+	char	*base = (char *) pPixmap->devPrivate.ptr;
+	
+	if (base != (pointer) (pPixmap + 1))
+	{
+	    for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+	    {
+		if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+		    break;
+	    }
+	}
+	else
+	    shmdesc = 0;
+#endif
+	if (shmdesc)
+	    ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+    }
+    
+    pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+    ret = (*pScreen->DestroyPixmap) (pPixmap);
+    destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+    pScreen->DestroyPixmap = ShmDestroyPixmap;
+    return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+    ScreenPtr pScreen;
+{
+    #ifdef TEST
+    fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+    #endif
+    shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+    register ClientPtr client;
+{
+    xShmQueryVersionReply rep;
+    register int n;
+
+    REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.sharedPixmaps = sharedPixmaps;
+    rep.pixmapFormat = pixmapFormat;
+    rep.majorVersion = SHM_MAJOR_VERSION;
+    rep.minorVersion = SHM_MINOR_VERSION;
+    rep.uid = geteuid();
+    rep.gid = getegid();
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+	swaps(&rep.uid, n);
+	swaps(&rep.gid, n);
+    }
+    WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+    int uid, gid;
+    mode_t mask;
+
+    if (LocalClientCred(client, &uid, &gid) != -1) {
+	
+	/* User id 0 always gets access */
+	if (uid == 0) {
+	    return 0;
+	}
+	/* Check the owner */
+	if (perm->uid == uid || perm->cuid == uid) {
+	    mask = S_IRUSR;
+	    if (!readonly) {
+		mask |= S_IWUSR;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+	/* Check the group */
+	if (perm->gid == gid || perm->cgid == gid) {
+	    mask = S_IRGRP;
+	    if (!readonly) {
+		mask |= S_IWGRP;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+    }
+    /* Otherwise, check everyone else */
+    mask = S_IROTH;
+    if (!readonly) {
+	mask |= S_IWOTH;
+    }
+    return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+    register ClientPtr client;
+{
+    struct shmid_ds buf;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmAttachReq);
+
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+    if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+    {
+	client->errorValue = stuff->readOnly;
+        return(BadValue);
+    }
+    for (shmdesc = Shmsegs;
+	 shmdesc && (shmdesc->shmid != stuff->shmid);
+	 shmdesc = shmdesc->next)
+	;
+    if (shmdesc)
+    {
+	if (!stuff->readOnly && !shmdesc->writable)
+	    return BadAccess;
+	shmdesc->refcnt++;
+    }
+    else
+    {
+	shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+	if (!shmdesc)
+	    return BadAlloc;
+	shmdesc->addr = shmat(stuff->shmid, 0,
+			      stuff->readOnly ? SHM_RDONLY : 0);
+	if ((shmdesc->addr == ((char *)-1)) ||
+	    shmctl(stuff->shmid, IPC_STAT, &buf))
+	{
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	/* The attach was performed with root privs. We must
+	 * do manual checking of access rights for the credentials 
+	 * of the client */
+
+	if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+	    shmdt(shmdesc->addr);
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	shmdesc->shmid = stuff->shmid;
+	shmdesc->refcnt = 1;
+	shmdesc->writable = !stuff->readOnly;
+	shmdesc->size = buf.shm_segsz;
+	shmdesc->next = Shmsegs;
+	Shmsegs = shmdesc;
+    }
+    if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+	return BadAlloc;
+    return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+    pointer value; /* must conform to DeleteType */
+    XID shmseg;
+{
+    ShmDescPtr shmdesc = (ShmDescPtr)value;
+    ShmDescPtr *prev;
+
+    if (--shmdesc->refcnt)
+	return TRUE;
+    shmdt(shmdesc->addr);
+    for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+	;
+    *prev = shmdesc->next;
+    xfree(shmdesc);
+    return Success;
+}
+
+static int
+ProcShmDetach(client)
+    register ClientPtr client;
+{
+    ShmDescPtr shmdesc;
+    REQUEST(xShmDetachReq);
+
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+    FreeResource(stuff->shmseg, RT_NONE);
+    return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    PixmapPtr pmap;
+    GCPtr putGC;
+
+    nxagentShmTrap = 0;
+    putGC = GetScratchGC(depth, dst->pScreen);
+    if (!putGC)
+    {
+        nxagentShmTrap = 1;
+	return;
+    }
+    pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+    if (!pmap)
+    {
+        nxagentShmTrap = 1;
+	FreeScratchGC(putGC);
+	return;
+    }
+    ValidateGC((DrawablePtr)pmap, putGC);
+    (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+			    (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+    FreeScratchGC(putGC);
+    if (format == XYBitmap)
+	(void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				     dx, dy, 1L);
+    else
+	(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				    dx, dy);
+    (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+    nxagentShmTrap = 1;
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    int length;
+    char *newdata;
+    extern int nxagentImageLength(int, int, int, int, int);
+
+    #ifdef TEST
+    fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
+                (void *) dst, (void *) pGC, (void *) data);
+    #endif
+
+    if ((format == ZPixmap) || (depth == 1))
+    {
+	PixmapPtr pPixmap;
+
+	pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+		BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+	if (!pPixmap)
+	    return;
+	if (format == XYBitmap)
+	    (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+					 sx, sy, sw, sh, dx, dy, 1L);
+	else
+	    (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+					sx, sy, sw, sh, dx, dy);
+
+        /*
+         * We updated the internal framebuffer,
+         * now we want to go on the real X.
+         */
+
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
+                    " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
+                        " sh [%d] dx [%d].\n", depth, format, w, h,
+                            sx, sy, sw, sh, dx);
+        #endif
+
+        length = nxagentImageLength(sw, sh, format, 0, depth);
+
+        if ((newdata = xalloc(length)) != NULL)
+        {
+          fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
+          (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
+
+          xfree(newdata);
+        }
+        else
+        {
+          #ifdef WARNING
+          fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
+          #endif
+        }
+
+	FreeScratchPixmapHeader(pPixmap);
+    }
+    else
+    {
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
+        #endif
+	miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+		      data);
+    }
+}
+
+
+#ifdef PANORAMIX
+static int 
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+    int			 j, result = 0, orig_x, orig_y;
+    PanoramiXRes	*draw, *gc;
+    Bool		 sendEvent, isRoot;
+
+    REQUEST(xShmPutImageReq);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+		(stuff->drawable == WindowTable[0]->drawable.id);
+
+    orig_x = stuff->dstX;
+    orig_y = stuff->dstY;
+    sendEvent = stuff->sendEvent;
+    stuff->sendEvent = 0;
+    FOR_NSCREENS(j) {
+	if(!j) stuff->sendEvent = sendEvent;
+	stuff->drawable = draw->info[j].id;
+	stuff->gc = gc->info[j].id;
+	if (isRoot) {
+	    stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+	    stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+	}
+	result = ProcShmPutImage(client);
+	if(result != client->noClientException) break;
+    }
+    return(result);
+}
+
+static int 
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+    PanoramiXRes	*draw;
+    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	pDraw;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int         	i, x, y, w, h, format;
+    Mask		plane = 0, planemask;
+    long		lenPer = 0, length, widthBytesLine;
+    Bool		isRoot;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+
+    if (draw->type == XRT_PIXMAP)
+	return ProcShmGetImage(client);
+
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+    x = stuff->x;
+    y = stuff->y;
+    w = stuff->width;
+    h = stuff->height;
+    format = stuff->format;
+    planemask = stuff->planeMask;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+		(stuff->drawable == WindowTable[0]->drawable.id);
+
+    if(isRoot) {
+      if( /* check for being onscreen */
+	x < 0 || x + w > PanoramiXPixWidth ||
+	y < 0 || y + h > PanoramiXPixHeight )
+	    return(BadMatch);
+    } else {
+      if( /* check for being onscreen */
+	panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+	panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+        panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+	panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+	 /* check for being inside of border */
+       	x < - wBorderWidth((WindowPtr)pDraw) ||
+	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+	y < -wBorderWidth((WindowPtr)pDraw) ||
+	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+	    return(BadMatch);
+    }
+
+    drawables[0] = pDraw;
+    for(i = 1; i < PanoramiXNumScreens; i++)
+	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+    xgi.visual = wVisual(((WindowPtr)pDraw));
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+
+    if(format == ZPixmap) {
+	widthBytesLine = PixmapBytePad(w, pDraw->depth);
+	length = widthBytesLine * h;
+    } else {
+	widthBytesLine = PixmapBytePad(w, 1);
+	lenPer = widthBytesLine * h;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	length = lenPer * Ones(planemask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0) {/* nothing to do */ }
+    else if (format == ZPixmap) {
+	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+					shmdesc->addr + stuff->offset,
+					widthBytesLine, isRoot);
+    } else {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1) {
+	    if (planemask & plane) {
+		XineramaGetImageData(drawables, x, y, w, h, 
+				     format, plane, shmdesc->addr + length,
+				     widthBytesLine, isRoot);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+	register int n;
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    ScreenPtr pScreen = NULL;
+    PixmapPtr pMap = NULL;
+    DrawablePtr pDraw;
+    DepthPtr pDepth;
+    int i, j, result;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+    PanoramiXRes *newPix;
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+
+    if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+
+    newPix->type = XRT_PIXMAP;
+    newPix->u.pix.shared = TRUE;
+    newPix->info[0].id = stuff->pid;
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPix->info[j].id = FakeClientID(client->index);
+
+    result = (client->noClientException);
+
+    FOR_NSCREENS(j) {
+	pScreen = screenInfo.screens[j];
+
+	pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, 
+				stuff->width, stuff->height, stuff->depth,
+				shmdesc->addr + stuff->offset);
+
+	if (pMap) {
+#ifdef PIXPRIV
+            pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+            shmdesc->refcnt++;
+	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    pMap->drawable.id = newPix->info[j].id;
+	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
+		(*pScreen->DestroyPixmap)(pMap);
+		result = BadAlloc;
+		break;
+	    }
+	} else {
+	   result = BadAlloc;
+	   break;
+	}
+    }
+
+    if(result == BadAlloc) {
+	while(j--) {
+	    (*pScreen->DestroyPixmap)(pMap);
+	    FreeResource(newPix->info[j].id, RT_NONE);
+	}
+	xfree(newPix);
+    } else 
+	AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+    return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+    register ClientPtr client;
+{
+    register GCPtr pGC;
+    register DrawablePtr pDraw;
+    long length;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmPutImageReq);
+
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+    if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+	return BadValue;
+    if (stuff->format == XYBitmap)
+    {
+        if (stuff->depth != 1)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+	length *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
+    if (stuff->srcX > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcX;
+	return BadValue;
+    }
+    if (stuff->srcY > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcY;
+	return BadValue;
+    }
+    if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcWidth;
+	return BadValue;
+    }
+    if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcHeight;
+	return BadValue;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
+                "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
+                    stuff->srcY, stuff->totalWidth, stuff->totalHeight);
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
+    #endif
+
+    (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+                               pDraw, pGC, stuff->depth, stuff->format,
+                               stuff->totalWidth, stuff->totalHeight,
+                               stuff->srcX, stuff->srcY,
+                               stuff->srcWidth, stuff->srcHeight,
+                               stuff->dstX, stuff->dstY,
+                               shmdesc->addr + stuff->offset);
+
+    if (stuff->sendEvent)
+    {
+	xShmCompletionEvent ev;
+
+	ev.type = ShmCompletionCode;
+	ev.drawable = stuff->drawable;
+	ev.sequenceNumber = client->sequence;
+	ev.minorEvent = X_ShmPutImage;
+	ev.majorEvent = ShmReqCode;
+	ev.shmseg = stuff->shmseg;
+	ev.offset = stuff->offset;
+	WriteEventsToClient(client, 1, (xEvent *) &ev);
+    }
+
+    return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDraw;
+    long		lenPer = 0, length;
+    Mask		plane = 0;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int			n;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+    {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + stuff->x < 0 ||
+ 	 pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+         pDraw->y + stuff->y < 0 ||
+         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+         stuff->x + (int)stuff->width >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+         stuff->y + (int)stuff->height >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual(((WindowPtr)pDraw));
+    }
+    else
+    {
+	if (stuff->x < 0 ||
+	    stuff->x+(int)stuff->width > pDraw->width ||
+	    stuff->y < 0 ||
+	    stuff->y+(int)stuff->height > pDraw->height
+	    )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(stuff->format == ZPixmap)
+    {
+	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+    }
+    else 
+    {
+	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0)
+    {
+	/* nothing to do */
+    }
+    else if (stuff->format == ZPixmap)
+    {
+	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+				    stuff->width, stuff->height,
+				    stuff->format, stuff->planeMask,
+				    shmdesc->addr + stuff->offset);
+    }
+    else
+    {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1)
+	{
+	    if (stuff->planeMask & plane)
+	    {
+		(*pDraw->pScreen->GetImage)(pDraw,
+					    stuff->x, stuff->y,
+					    stuff->width, stuff->height,
+					    stuff->format, plane,
+					    shmdesc->addr + length);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+    ScreenPtr	pScreen;
+    int		width;
+    int		height;
+    int		depth;
+    char	*addr;
+{
+    register PixmapPtr pPixmap;
+
+    nxagentShmPixmapTrap = 1;
+
+    pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth);
+
+    if (!pPixmap)
+    {
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    #ifdef TEST
+    fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth);
+    #endif
+
+    if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) 
+    {
+      #ifdef WARNING
+      fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
+      #endif
+
+      (*pScreen->DestroyPixmap)(pPixmap);
+
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    nxagentShmPixmapTrap = 0;
+
+    return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    DepthPtr pDepth;
+    register int i;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+    pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+			    pDraw->pScreen, stuff->width,
+			    stuff->height, stuff->depth,
+			    shmdesc->addr + stuff->offset);
+    if (pMap)
+    {
+#ifdef PIXPRIV
+	pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+	shmdesc->refcnt++;
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	{
+	    return(client->noClientException);
+	}
+    }
+    return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return ProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return ProcShmAttach(client);
+    case X_ShmDetach:
+	return ProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+        {
+           result = ProcPanoramiXShmPutImage(client);
+
+           nxagentShmTrap = 0;
+
+           return result;
+        }
+#endif
+
+        result = ProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmGetImage(client);
+#endif
+	return ProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmCreatePixmap(client);
+#endif
+	   return ProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static void
+SShmCompletionEvent(from, to)
+    xShmCompletionEvent *from, *to;
+{
+    to->type = from->type;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->drawable, to->drawable);
+    cpswaps(from->minorEvent, to->minorEvent);
+    to->majorEvent = from->majorEvent;
+    cpswapl(from->shmseg, to->shmseg);
+    cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+    register ClientPtr	client;
+{
+    register int n;
+    REQUEST(xShmQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmAttachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->shmid, n);
+    return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmDetachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    swapl(&stuff->shmseg, n);
+    return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmPutImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->gc, n);
+    swaps(&stuff->totalWidth, n);
+    swaps(&stuff->totalHeight, n);
+    swaps(&stuff->srcX, n);
+    swaps(&stuff->srcY, n);
+    swaps(&stuff->srcWidth, n);
+    swaps(&stuff->srcHeight, n);
+    swaps(&stuff->dstX, n);
+    swaps(&stuff->dstY, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmGetImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->planeMask, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmCreatePixmapReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return SProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return SProcShmAttach(client);
+    case X_ShmDetach:
+	return SProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+        result = SProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+	return SProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+	return SProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXshm.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c.XF86.original
new file mode 100644
index 000000000..3ba9ad2c1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXshm.c.XF86.original
@@ -0,0 +1,1257 @@
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.36 2002/04/03 19:51:11 herrb Exp $ */
+/************************************************************
+
+Copyright 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#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 "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include "shmstr.h"
+#include "Xfuncproto.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+#if NeedFunctionPrototypes
+    pointer		/* value */,
+    XID			/* shmseg */
+#endif
+    );
+static void ShmResetProc(
+#if NeedFunctionPrototypes
+    ExtensionEntry *	/* extEntry */
+#endif
+    );
+static void SShmCompletionEvent(
+#if NeedFunctionPrototypes
+    xShmCompletionEvent * /* from */,
+    xShmCompletionEvent * /* to */
+#endif
+    );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int  shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+    shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+    if (!shmdesc) \
+    { \
+	client->errorValue = shmseg; \
+	return BadShmSegCode; \
+    } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+    VERIFY_SHMSEG(shmseg, shmdesc, client); \
+    if ((offset & 3) || (offset > shmdesc->size)) \
+    { \
+	client->errorValue = offset; \
+	return BadValue; \
+    } \
+    if (needwrite && !shmdesc->writable) \
+	return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+    if ((offset + len) > shmdesc->size) \
+    { \
+	return BadAccess; \
+    } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+    badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+    void (*oldHandler)();
+    int shmid = -1;
+
+    /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+    oldHandler = signal(SIGSYS, SigSysHandler);
+
+    badSysCall = FALSE;
+    shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+    /* Clean up */
+    if (shmid != -1)
+    {
+	shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+    }
+    signal(SIGSYS, oldHandler);
+    return(!badSysCall);
+}
+#endif
+    
+void
+ShmExtensionInit()
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+    if (!CheckForShmSyscall())
+    {
+	ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+	return;
+    }
+#endif
+
+    sharedPixmaps = xFalse;
+    pixmapFormat = 0;
+    {
+      sharedPixmaps = xTrue;
+      pixmapFormat = shmPixFormat[0];
+      for (i = 0; i < screenInfo.numScreens; i++)
+      {
+	if (!shmFuncs[i])
+	    shmFuncs[i] = &miFuncs;
+	if (!shmFuncs[i]->CreatePixmap)
+	    sharedPixmaps = xFalse;
+	if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+	{
+	    sharedPixmaps = xFalse;
+	    pixmapFormat = 0;
+	}
+      }
+      if (!pixmapFormat)
+	pixmapFormat = ZPixmap;
+      if (sharedPixmaps)
+      {
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+	    screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+	}
+#ifdef PIXPRIV
+	shmPixmapPrivate = AllocatePixmapPrivateIndex();
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    if (!AllocatePixmapPrivate(screenInfo.screens[i],
+				       shmPixmapPrivate, 0))
+		return;
+	}
+#endif
+      }
+    }
+    ShmSegType = CreateNewResourceType(ShmDetachSegment);
+    if (ShmSegType &&
+	(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+				 ProcShmDispatch, SProcShmDispatch,
+				 ShmResetProc, StandardMinorOpcode)))
+    {
+	ShmReqCode = (unsigned char)extEntry->base;
+	ShmCompletionCode = extEntry->eventBase;
+	BadShmSegCode = extEntry->errorBase;
+	EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+    }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry	*extEntry;
+{
+    int i;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+	shmFuncs[i] = (ShmFuncsPtr)NULL;
+	shmPixFormat[i] = 0;
+    }
+}
+
+void
+ShmRegisterFuncs(pScreen, funcs)
+    ScreenPtr pScreen;
+    ShmFuncsPtr funcs;
+{
+    shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(pScreen, format)
+    ScreenPtr pScreen;
+    int format;
+{
+    shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	    pScreen = pPixmap->drawable.pScreen;
+    Bool	    ret;
+    if (pPixmap->refcnt == 1)
+    {
+	ShmDescPtr  shmdesc;
+#ifdef PIXPRIV
+	shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+	char	*base = (char *) pPixmap->devPrivate.ptr;
+	
+	if (base != (pointer) (pPixmap + 1))
+	{
+	    for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+	    {
+		if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+		    break;
+	    }
+	}
+	else
+	    shmdesc = 0;
+#endif
+	if (shmdesc)
+	    ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+    }
+    
+    pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+    ret = (*pScreen->DestroyPixmap) (pPixmap);
+    destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+    pScreen->DestroyPixmap = ShmDestroyPixmap;
+    return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+    ScreenPtr pScreen;
+{
+    shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+    register ClientPtr client;
+{
+    xShmQueryVersionReply rep;
+    register int n;
+
+    REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.sharedPixmaps = sharedPixmaps;
+    rep.pixmapFormat = pixmapFormat;
+    rep.majorVersion = SHM_MAJOR_VERSION;
+    rep.minorVersion = SHM_MINOR_VERSION;
+    rep.uid = geteuid();
+    rep.gid = getegid();
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+	swaps(&rep.uid, n);
+	swaps(&rep.gid, n);
+    }
+    WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+    int uid, gid;
+    mode_t mask;
+
+    if (LocalClientCred(client, &uid, &gid) != -1) {
+	
+	/* User id 0 always gets access */
+	if (uid == 0) {
+	    return 0;
+	}
+	/* Check the owner */
+	if (perm->uid == uid || perm->cuid == uid) {
+	    mask = S_IRUSR;
+	    if (!readonly) {
+		mask |= S_IWUSR;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+	/* Check the group */
+	if (perm->gid == gid || perm->cgid == gid) {
+	    mask = S_IRGRP;
+	    if (!readonly) {
+		mask |= S_IWGRP;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+    }
+    /* Otherwise, check everyone else */
+    mask = S_IROTH;
+    if (!readonly) {
+	mask |= S_IWOTH;
+    }
+    return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+    register ClientPtr client;
+{
+    struct shmid_ds buf;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmAttachReq);
+
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+    if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+    {
+	client->errorValue = stuff->readOnly;
+        return(BadValue);
+    }
+    for (shmdesc = Shmsegs;
+	 shmdesc && (shmdesc->shmid != stuff->shmid);
+	 shmdesc = shmdesc->next)
+	;
+    if (shmdesc)
+    {
+	if (!stuff->readOnly && !shmdesc->writable)
+	    return BadAccess;
+	shmdesc->refcnt++;
+    }
+    else
+    {
+	shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+	if (!shmdesc)
+	    return BadAlloc;
+	shmdesc->addr = shmat(stuff->shmid, 0,
+			      stuff->readOnly ? SHM_RDONLY : 0);
+	if ((shmdesc->addr == ((char *)-1)) ||
+	    shmctl(stuff->shmid, IPC_STAT, &buf))
+	{
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	/* The attach was performed with root privs. We must
+	 * do manual checking of access rights for the credentials 
+	 * of the client */
+
+	if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+	    shmdt(shmdesc->addr);
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	shmdesc->shmid = stuff->shmid;
+	shmdesc->refcnt = 1;
+	shmdesc->writable = !stuff->readOnly;
+	shmdesc->size = buf.shm_segsz;
+	shmdesc->next = Shmsegs;
+	Shmsegs = shmdesc;
+    }
+    if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+	return BadAlloc;
+    return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+    pointer value; /* must conform to DeleteType */
+    XID shmseg;
+{
+    ShmDescPtr shmdesc = (ShmDescPtr)value;
+    ShmDescPtr *prev;
+
+    if (--shmdesc->refcnt)
+	return TRUE;
+    shmdt(shmdesc->addr);
+    for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+	;
+    *prev = shmdesc->next;
+    xfree(shmdesc);
+    return Success;
+}
+
+static int
+ProcShmDetach(client)
+    register ClientPtr client;
+{
+    ShmDescPtr shmdesc;
+    REQUEST(xShmDetachReq);
+
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+    FreeResource(stuff->shmseg, RT_NONE);
+    return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    PixmapPtr pmap;
+    GCPtr putGC;
+
+    putGC = GetScratchGC(depth, dst->pScreen);
+    if (!putGC)
+	return;
+    pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+    if (!pmap)
+    {
+	FreeScratchGC(putGC);
+	return;
+    }
+    ValidateGC((DrawablePtr)pmap, putGC);
+    (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+			    (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+    FreeScratchGC(putGC);
+    if (format == XYBitmap)
+	(void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				     dx, dy, 1L);
+    else
+	(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				    dx, dy);
+    (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    if ((format == ZPixmap) || (depth == 1))
+    {
+	PixmapPtr pPixmap;
+
+	pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+		BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+	if (!pPixmap)
+	    return;
+	if (format == XYBitmap)
+	    (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+					 sx, sy, sw, sh, dx, dy, 1L);
+	else
+	    (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+					sx, sy, sw, sh, dx, dy);
+	FreeScratchPixmapHeader(pPixmap);
+    }
+    else
+	miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+		      data);
+}
+
+
+#ifdef PANORAMIX
+static int 
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+    int			 j, result = 0, orig_x, orig_y;
+    PanoramiXRes	*draw, *gc;
+    Bool		 sendEvent, isRoot;
+
+    REQUEST(xShmPutImageReq);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+		(stuff->drawable == WindowTable[0]->drawable.id);
+
+    orig_x = stuff->dstX;
+    orig_y = stuff->dstY;
+    sendEvent = stuff->sendEvent;
+    stuff->sendEvent = 0;
+    FOR_NSCREENS(j) {
+	if(!j) stuff->sendEvent = sendEvent;
+	stuff->drawable = draw->info[j].id;
+	stuff->gc = gc->info[j].id;
+	if (isRoot) {
+	    stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+	    stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+	}
+	result = ProcShmPutImage(client);
+	if(result != client->noClientException) break;
+    }
+    return(result);
+}
+
+static int 
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+    PanoramiXRes	*draw;
+    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	pDraw;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int         	i, x, y, w, h, format;
+    Mask		plane = 0, planemask;
+    long		lenPer = 0, length, widthBytesLine;
+    Bool		isRoot;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+
+    if (draw->type == XRT_PIXMAP)
+	return ProcShmGetImage(client);
+
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+    x = stuff->x;
+    y = stuff->y;
+    w = stuff->width;
+    h = stuff->height;
+    format = stuff->format;
+    planemask = stuff->planeMask;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+		(stuff->drawable == WindowTable[0]->drawable.id);
+
+    if(isRoot) {
+      if( /* check for being onscreen */
+	x < 0 || x + w > PanoramiXPixWidth ||
+	y < 0 || y + h > PanoramiXPixHeight )
+	    return(BadMatch);
+    } else {
+      if( /* check for being onscreen */
+	panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+	panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+        panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+	panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+	 /* check for being inside of border */
+       	x < - wBorderWidth((WindowPtr)pDraw) ||
+	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+	y < -wBorderWidth((WindowPtr)pDraw) ||
+	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+	    return(BadMatch);
+    }
+
+    drawables[0] = pDraw;
+    for(i = 1; i < PanoramiXNumScreens; i++)
+	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+    xgi.visual = wVisual(((WindowPtr)pDraw));
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+
+    if(format == ZPixmap) {
+	widthBytesLine = PixmapBytePad(w, pDraw->depth);
+	length = widthBytesLine * h;
+    } else {
+	widthBytesLine = PixmapBytePad(w, 1);
+	lenPer = widthBytesLine * h;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	length = lenPer * Ones(planemask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0) {/* nothing to do */ }
+    else if (format == ZPixmap) {
+	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+					shmdesc->addr + stuff->offset,
+					widthBytesLine, isRoot);
+    } else {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1) {
+	    if (planemask & plane) {
+		XineramaGetImageData(drawables, x, y, w, h, 
+				     format, plane, shmdesc->addr + length,
+				     widthBytesLine, isRoot);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+	register int n;
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    ScreenPtr pScreen = NULL;
+    PixmapPtr pMap = NULL;
+    DrawablePtr pDraw;
+    DepthPtr pDepth;
+    int i, j, result;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+    PanoramiXRes *newPix;
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+
+    if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+
+    newPix->type = XRT_PIXMAP;
+    newPix->u.pix.shared = TRUE;
+    newPix->info[0].id = stuff->pid;
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPix->info[j].id = FakeClientID(client->index);
+
+    result = (client->noClientException);
+
+    FOR_NSCREENS(j) {
+	pScreen = screenInfo.screens[j];
+
+	pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, 
+				stuff->width, stuff->height, stuff->depth,
+				shmdesc->addr + stuff->offset);
+
+	if (pMap) {
+#ifdef PIXPRIV
+            pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+            shmdesc->refcnt++;
+	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    pMap->drawable.id = newPix->info[j].id;
+	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
+		(*pScreen->DestroyPixmap)(pMap);
+		result = BadAlloc;
+		break;
+	    }
+	} else {
+	   result = BadAlloc;
+	   break;
+	}
+    }
+
+    if(result == BadAlloc) {
+	while(j--) {
+	    (*pScreen->DestroyPixmap)(pMap);
+	    FreeResource(newPix->info[j].id, RT_NONE);
+	}
+	xfree(newPix);
+    } else 
+	AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+    return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+    register ClientPtr client;
+{
+    register GCPtr pGC;
+    register DrawablePtr pDraw;
+    long length;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmPutImageReq);
+
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+    if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+	return BadValue;
+    if (stuff->format == XYBitmap)
+    {
+        if (stuff->depth != 1)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+	length *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
+    if (stuff->srcX > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcX;
+	return BadValue;
+    }
+    if (stuff->srcY > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcY;
+	return BadValue;
+    }
+    if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcWidth;
+	return BadValue;
+    }
+    if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcHeight;
+	return BadValue;
+    }
+
+    if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
+	 ((stuff->format != ZPixmap) &&
+	  (stuff->srcX < screenInfo.bitmapScanlinePad) &&
+	  ((stuff->format == XYBitmap) ||
+	   ((stuff->srcY == 0) &&
+	    (stuff->srcHeight == stuff->totalHeight))))) &&
+	((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
+	(*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
+			       stuff->dstX, stuff->dstY,
+			       stuff->totalWidth, stuff->srcHeight, 
+			       stuff->srcX, stuff->format, 
+			       shmdesc->addr + stuff->offset +
+			       (stuff->srcY * length));
+    else
+	(*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+			       pDraw, pGC, stuff->depth, stuff->format,
+			       stuff->totalWidth, stuff->totalHeight,
+			       stuff->srcX, stuff->srcY,
+			       stuff->srcWidth, stuff->srcHeight,
+			       stuff->dstX, stuff->dstY,
+                               shmdesc->addr + stuff->offset);
+
+    if (stuff->sendEvent)
+    {
+	xShmCompletionEvent ev;
+
+	ev.type = ShmCompletionCode;
+	ev.drawable = stuff->drawable;
+	ev.sequenceNumber = client->sequence;
+	ev.minorEvent = X_ShmPutImage;
+	ev.majorEvent = ShmReqCode;
+	ev.shmseg = stuff->shmseg;
+	ev.offset = stuff->offset;
+	WriteEventsToClient(client, 1, (xEvent *) &ev);
+    }
+
+    return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDraw;
+    long		lenPer = 0, length;
+    Mask		plane = 0;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int			n;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+    {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + stuff->x < 0 ||
+ 	 pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+         pDraw->y + stuff->y < 0 ||
+         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+         stuff->x + (int)stuff->width >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+         stuff->y + (int)stuff->height >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual(((WindowPtr)pDraw));
+    }
+    else
+    {
+	if (stuff->x < 0 ||
+	    stuff->x+(int)stuff->width > pDraw->width ||
+	    stuff->y < 0 ||
+	    stuff->y+(int)stuff->height > pDraw->height
+	    )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(stuff->format == ZPixmap)
+    {
+	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+    }
+    else 
+    {
+	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0)
+    {
+	/* nothing to do */
+    }
+    else if (stuff->format == ZPixmap)
+    {
+	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+				    stuff->width, stuff->height,
+				    stuff->format, stuff->planeMask,
+				    shmdesc->addr + stuff->offset);
+    }
+    else
+    {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1)
+	{
+	    if (stuff->planeMask & plane)
+	    {
+		(*pDraw->pScreen->GetImage)(pDraw,
+					    stuff->x, stuff->y,
+					    stuff->width, stuff->height,
+					    stuff->format, plane,
+					    shmdesc->addr + length);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+    ScreenPtr	pScreen;
+    int		width;
+    int		height;
+    int		depth;
+    char	*addr;
+{
+    register PixmapPtr pPixmap;
+
+    pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
+    if (!pPixmap)
+	return NullPixmap;
+
+    if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
+	(*pScreen->DestroyPixmap)(pPixmap);
+	return NullPixmap;
+    }
+    return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    DepthPtr pDepth;
+    register int i;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+    pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+			    pDraw->pScreen, stuff->width,
+			    stuff->height, stuff->depth,
+			    shmdesc->addr + stuff->offset);
+    if (pMap)
+    {
+#ifdef PIXPRIV
+	pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+	shmdesc->refcnt++;
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	{
+	    return(client->noClientException);
+	}
+    }
+    return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return ProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return ProcShmAttach(client);
+    case X_ShmDetach:
+	return ProcShmDetach(client);
+    case X_ShmPutImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmPutImage(client);
+#endif
+	return ProcShmPutImage(client);
+    case X_ShmGetImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmGetImage(client);
+#endif
+	return ProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmCreatePixmap(client);
+#endif
+	   return ProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static void
+SShmCompletionEvent(from, to)
+    xShmCompletionEvent *from, *to;
+{
+    to->type = from->type;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->drawable, to->drawable);
+    cpswaps(from->minorEvent, to->minorEvent);
+    to->majorEvent = from->majorEvent;
+    cpswapl(from->shmseg, to->shmseg);
+    cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+    register ClientPtr	client;
+{
+    register int n;
+    REQUEST(xShmQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmAttachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->shmid, n);
+    return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmDetachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    swapl(&stuff->shmseg, n);
+    return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmPutImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->gc, n);
+    swaps(&stuff->totalWidth, n);
+    swaps(&stuff->totalHeight, n);
+    swaps(&stuff->srcX, n);
+    swaps(&stuff->srcY, n);
+    swaps(&stuff->srcWidth, n);
+    swaps(&stuff->srcHeight, n);
+    swaps(&stuff->dstX, n);
+    swaps(&stuff->dstY, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmGetImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->planeMask, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmCreatePixmapReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return SProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return SProcShmAttach(client);
+    case X_ShmDetach:
+	return SProcShmDetach(client);
+    case X_ShmPutImage:
+	return SProcShmPutImage(client);
+    case X_ShmGetImage:
+	return SProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+	return SProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
new file mode 100644
index 000000000..16328f9ab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
@@ -0,0 +1,4179 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXwindow.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+			All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "selection.h"
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include "Xagsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+
+#include "Screen.h"
+#include "Options.h"
+#include "Atoms.h"
+#include "Clipboard.h"
+#include "Splash.h"
+#include "Rootless.h"
+#include "Composite.h"
+#include "Drawable.h"
+#include "Colormap.h"
+
+#if defined(NEED_SCREEN_REGIONS)
+#define REGION_PTR(pScreen,pWin) \
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+#else
+#define REGION_PTR(pScreen,pWin) /* nothing */
+#endif
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
+/******
+ * Window stuff for server 
+ *
+ *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(
+#if NeedFunctionPrototypes
+    int /*i*/,
+    int /*kind*/
+#endif
+);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+			      CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+      (!( ((b1)->x2 <= (b2)->x1)  || \
+	( ((b1)->x1 >= (b2)->x2)) || \
+	( ((b1)->y2 <= (b2)->y1)) || \
+	( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+WindowPtr nxagentRootTileWindow;
+
+/*
+ * This block used the DEBUG symbol.
+ */
+
+#ifdef WINDOW_TREE_DEBUG
+/******
+ * PrintWindowTree
+ *    For debugging only
+ ******/
+
+int
+PrintChildren(p1, indent)
+    WindowPtr p1;
+    int indent;
+{
+    WindowPtr p2;
+    int i;
+
+    while (p1)
+    {
+	p2 = p1->firstChild;
+	for (i=0; i<indent; i++) ErrorF( " ");
+	ErrorF( "%x\n", p1->drawable.id);
+	miPrintRegion(&p1->clipList);
+	PrintChildren(p2, indent+4);
+	p1 = p1->nextSib;
+    }
+}
+
+PrintWindowTree()
+{
+    int i;
+    WindowPtr pWin, p1;
+
+    for (i=0; i<screenInfo.numScreens; i++)
+    {
+	ErrorF( "WINDOW %d\n", i);
+	pWin = WindowTable[i];
+	miPrintRegion(&pWin->clipList);
+	p1 = pWin->firstChild;
+	PrintChildren(p1, 4);
+    }
+}
+#endif
+
+int
+TraverseTree(pWin, func, data)
+    register WindowPtr pWin;
+    VisitWindowProcPtr func;
+    pointer data;
+{
+    register int result;
+    register WindowPtr pChild;
+
+    if (!(pChild = pWin))
+       return(WT_NOMATCH);
+    while (1)
+    {
+	result = (* func)(pChild, data);
+	if (result == WT_STOPWALKING)
+	    return(WT_STOPWALKING);
+	if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+    return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
+ *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
+ *   exit WalkTree.  Does depth-first traverse.
+ *****/
+
+int
+WalkTree(pScreen, func, data)
+    ScreenPtr pScreen;
+    VisitWindowProcPtr func;
+    pointer data;
+{
+    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int	defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool	disableBackingStore = FALSE;
+Bool	enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool	disableSaveUnders = FALSE;
+
+static void
+#if NeedFunctionPrototypes
+SetWindowToDefaults(register WindowPtr pWin)
+#else
+SetWindowToDefaults(pWin)
+    register WindowPtr pWin;
+#endif
+{
+    pWin->prevSib = NullWindow;
+    pWin->firstChild = NullWindow;
+    pWin->lastChild = NullWindow;
+
+    pWin->valdata = (ValidatePtr)NULL;
+    pWin->optional = (WindowOptPtr)NULL;
+    pWin->cursorIsNone = TRUE;
+
+    pWin->backingStore = NotUseful;
+    pWin->DIXsaveUnder = FALSE;
+    pWin->backStorage = (pointer) NULL;
+
+    pWin->mapped = FALSE;	    /* off */
+    pWin->realized = FALSE;	/* off */
+    pWin->viewable = FALSE;
+    pWin->visibility = VisibilityNotViewable;
+    pWin->overrideRedirect = FALSE;
+    pWin->saveUnder = FALSE;
+
+    pWin->bitGravity = ForgetGravity;
+    pWin->winGravity = NorthWestGravity;
+
+    pWin->eventMask = 0;
+    pWin->deliverableEvents = 0;
+    pWin->dontPropagate = 0;
+    pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+    pWin->srcBuffer = DBE_FRONT_BUFFER;
+    pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+}
+
+void nxagentClearSplash(WindowPtr pW)
+{
+    int w, h;
+    ScreenPtr pScreen;
+
+    w = pW->drawable.width;
+    h = pW->drawable.height;
+
+    pScreen = pW->drawable.pScreen;
+
+    if (pW->backgroundState == BackgroundPixmap)
+    {
+      (*pScreen->DestroyPixmap)(pW->background.pixmap);
+    }
+
+    pW->backgroundState = BackgroundPixel;
+    pW->background.pixel = nxagentLogoBlack;
+
+    (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
+
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+    WindowPtr pWin;
+#endif
+{
+    nxagentRootTileWindow = pWin;
+}
+
+WindowPtr
+AllocateWindow(pScreen)
+    ScreenPtr pScreen;
+{
+    WindowPtr pWin;
+    register char *ptr;
+    register DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+    if (pWin)
+    {
+	ppriv = (DevUnion *)(pWin + 1);
+	pWin->devPrivates = ppriv;
+	sizes = pScreen->WindowPrivateSizes;
+	ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+	for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+	{
+	    if ( (size = *sizes) )
+	    {
+		ppriv->ptr = (pointer)ptr;
+		ptr += size;
+	    }
+	    else
+		ppriv->ptr = (pointer)NULL;
+	}
+    }
+    return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ *    Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(pScreen)
+    ScreenPtr	pScreen;
+{
+    WindowPtr	pWin;
+    BoxRec	box;
+    PixmapFormatRec *format;
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+	return FALSE;
+
+    savedScreenInfo[pScreen->myNum].pWindow = NULL;
+    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+    screenIsSaved = SCREEN_SAVER_OFF;
+
+    WindowTable[pScreen->myNum] = pWin;
+
+    pWin->drawable.pScreen = pScreen;
+    pWin->drawable.type = DRAWABLE_WINDOW;
+
+    pWin->drawable.depth = pScreen->rootDepth;
+    for (format = screenInfo.formats;
+	 format->depth != pScreen->rootDepth;
+	 format++)
+	;
+    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->parent = NullWindow;
+    SetWindowToDefaults(pWin);
+
+    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+    if (!pWin->optional)
+        return FALSE;
+
+    pWin->optional->dontPropagateMask = 0;
+    pWin->optional->otherEventMasks = 0;
+    pWin->optional->otherClients = NULL;
+    pWin->optional->passiveGrabs = NULL;
+    pWin->optional->userProps = NULL;
+    pWin->optional->backingBitPlanes = ~0L;
+    pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+    pWin->optional->boundingShape = NULL;
+    pWin->optional->clipShape = NULL;
+#endif
+#ifdef XINPUT
+    pWin->optional->inputMasks = NULL;
+#endif
+    pWin->optional->colormap = pScreen->defColormap;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->nextSib = NullWindow;
+
+    pWin->drawable.id = FakeClientID(0);
+
+    pWin->origin.x = pWin->origin.y = 0;
+    pWin->drawable.height = pScreen->height;
+    pWin->drawable.width = pScreen->width;
+    pWin->drawable.x = pWin->drawable.y = 0;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+    pWin->drawable.class = InputOutput;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->backgroundState = BackgroundPixel;
+    pWin->background.pixel = pScreen->whitePixel;
+
+    pWin->borderIsPixel = TRUE;
+    pWin->border.pixel = pScreen->blackPixel;
+    pWin->borderWidth = 0;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+	return FALSE;
+
+    if (disableBackingStore)
+    {
+      pScreen -> backingStoreSupport = NotUseful;
+    }
+
+    if (enableBackingStore)
+    {
+      pScreen -> backingStoreSupport = Always;
+    }
+
+    pScreen->saveUnderSupport = False;
+
+#ifdef DO_SAVE_UNDERS
+    if ((pScreen->backingStoreSupport != NotUseful) &&
+	(pScreen->saveUnderSupport == NotUseful))
+    {
+	/*
+	 * If the screen has backing-store but no save-unders, let the
+	 * clients know we can support save-unders using backing-store.
+	 */
+	pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+    }
+#endif /* DO_SAVE_UNDERS */
+		
+    if (disableSaveUnders)
+	pScreen->saveUnderSupport = NotUseful;
+
+    return TRUE;
+}
+
+void
+InitRootWindow(pWin)
+    WindowPtr pWin;
+{
+    ScreenPtr pScreen;
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (nxagentOption(Rootless))
+    {
+      #ifdef TEST
+      fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
+                  (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+      #endif
+
+      nxagentRootlessWindow = pWin;
+    }
+
+    pScreen = pWin->drawable.pScreen;
+
+    /*
+     * A root window is created for each screen by main
+     * and the pointer is saved in WindowTable as in the
+     * following snippet:
+     *
+     * for (i = 0; i < screenInfo.numScreens; i++)
+     *          InitRootWindow(WindowTable[i]);
+     *
+     * Our root window on the real display was already
+     * created at the time the screen was opened, so it
+     * is unclear how this window (or the other window,
+     * if you prefer) fits in the big picture.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+
+    #ifdef NXAGENT_SPLASH
+    /* We SHOULD check for an error value here XXX */
+    pWin -> background.pixel = pScreen -> blackPixel;
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
+    #else
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+    #endif
+
+    MakeRootTile(pWin);
+
+    /*
+     * Map both the root and the default agent window.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
+    #endif
+
+    nxagentInitAtoms(pWin);
+
+    nxagentInitClipboard(pWin);
+
+    nxagentMapDefaultWindows();
+
+    nxagentRedirectDefaultWindows();
+
+    #ifdef NXAGENT_ARTSD
+    {
+      char artsd_port[10];
+      int nPort;
+      extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+      nPort = atoi(display) + 7000;
+      sprintf(artsd_port,"%d", nPort);
+      nxagentPropagateArtsdProperties(pScreen, artsd_port);
+    }
+    #endif
+}
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize.  The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(pWin, Rgn, x, y, w, h)
+    register WindowPtr pWin;
+    RegionPtr Rgn;
+    register int x, y;
+    int w, h;
+{
+    REGION_PTR(pScreen, pWin)
+    BoxRec box;
+
+    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+    /* we do these calculations to avoid overflows */
+    if (x > box.x1)
+	box.x1 = x;
+    if (y > box.y1)
+	box.y1 = y;
+    x += w;
+    if (x < box.x2)
+	box.x2 = x;
+    y += h;
+    if (y < box.y2)
+	box.y2 = y;
+    if (box.x1 > box.x2)
+	box.x2 = box.x1;
+    if (box.y1 > box.y2)
+	box.y2 = box.y1;
+    REGION_RESET(pScreen, Rgn, &box);
+    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(pWin)
+    register WindowPtr pWin;
+{
+    if (!pWin->parent &&
+	(screenIsSaved == SCREEN_SAVER_ON) &&
+	(HasSaverWindow (pWin->drawable.pScreen->myNum)))
+	return (pWin->firstChild);
+    else
+	return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ *    Makes a window in response to client request 
+ *****/
+
+WindowPtr
+CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist,
+	     depth, client, visual, error)
+    Window wid;
+    register WindowPtr pParent;
+    int x,y;
+    unsigned int w, h, bw;
+    unsigned int class;
+    register Mask vmask;
+    XID *vlist;
+    int depth;
+    ClientPtr client;
+    VisualID visual;
+    int *error;
+{
+    register WindowPtr pWin;
+    WindowPtr pHead;
+    register ScreenPtr pScreen;
+    xEvent event;
+    int idepth, ivisual;
+    Bool fOK;
+    DepthPtr pDepth;
+    PixmapFormatRec *format;
+    register WindowOptPtr ancwopt;
+
+    if (class == CopyFromParent)
+	class = pParent->drawable.class;
+
+    if ((class != InputOutput) && (class != InputOnly))
+    {
+	*error = BadValue;
+	client->errorValue = class;
+	return NullWindow;
+    }
+
+    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pScreen = pParent->drawable.pScreen;
+    if ((class == InputOutput) && (depth == 0))
+	 depth = pParent->drawable.depth;
+    ancwopt = pParent->optional;
+    if (!ancwopt)
+	ancwopt = FindWindowWithOptional(pParent)->optional;
+    if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+	VisualID ag_visual;
+
+	if (client->appgroup && !pParent->parent &&
+	    (ag_visual = XagRootVisual (client)))
+	    visual = ag_visual;
+	else
+#endif
+	visual = ancwopt->visual;
+    }
+
+    /* Find out if the depth and visual are acceptable for this Screen */
+    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+    {
+	fOK = FALSE;
+	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+	{
+	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+	    if ((depth == pDepth->depth) || (depth == 0))
+	    {
+		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+		{
+		    if (visual == pDepth->vids[ivisual])
+		    {
+			fOK = TRUE;
+			break;
+		    }
+		}
+	    }
+	}
+	if (fOK == FALSE)
+	{
+	    *error = BadMatch;
+	    return NullWindow;
+	}
+    }
+
+    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+	(class != InputOnly) &&
+	(depth != pParent->drawable.depth))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if (((vmask & CWColormap) == 0) &&
+	(class != InputOnly) &&
+	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+    {
+	*error = BadAlloc;
+	return NullWindow;
+    }
+    pWin->drawable = pParent->drawable;
+    pWin->drawable.depth = depth;
+    if (depth == pParent->drawable.depth)
+	pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+    else
+    {
+	for (format = screenInfo.formats; format->depth != depth; format++)
+	    ;
+	pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+    }
+    if (class == InputOnly)
+	pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->drawable.id = wid;
+    pWin->drawable.class = class;
+
+    pWin->parent = pParent;
+    SetWindowToDefaults(pWin);
+
+    if (visual != ancwopt->visual)
+    {
+	if (!MakeWindowOptional (pWin))
+	{
+	    xfree (pWin);
+	    *error = BadAlloc;
+	    return NullWindow;
+	}
+	pWin->optional->visual = visual;
+	pWin->optional->colormap = None;
+    }
+
+    pWin->borderWidth = bw;
+#ifdef XCSECURITY
+    /*  can't let untrusted clients have background None windows;
+     *  they make it too easy to steal window contents
+     */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	pWin->backgroundState = BackgroundPixel;
+	pWin->background.pixel = 0;
+    }
+    else
+#endif
+    pWin->backgroundState = None;
+
+    pWin->borderIsPixel = pParent->borderIsPixel;
+    pWin->border = pParent->border;
+    if (pWin->borderIsPixel == FALSE)
+	pWin->border.pixmap->refcnt++;
+		
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    pWin->drawable.width = w;
+    pWin->drawable.height = h;
+    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+	/* set up clip list correctly for unobscured WindowPtr */
+    REGION_INIT(pScreen, &pWin->clipList, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->winSize, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, NullBox, 1);
+
+    pHead = RealChildHead(pParent);
+    if (pHead)
+    {
+	pWin->nextSib = pHead->nextSib;
+	if (pHead->nextSib)
+	    pHead->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pHead->nextSib = pWin;
+	pWin->prevSib = pHead;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    /* We SHOULD check for an error value here XXX */
+    if (!(*pScreen->CreateWindow)(pWin))
+    {
+	*error = BadAlloc;
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    if (!(vmask & CWEventMask))
+	RecalculateDeliverableEvents(pWin);
+
+    if (vmask)
+	*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+    else
+	*error = Success;
+
+    if (*error != Success)
+    {
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+    {
+	XID value = defaultBackingStore;
+	(void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+	pWin->forcedBS = TRUE;
+    }
+
+    if (SubSend(pParent))
+    {
+	event.u.u.type = CreateNotify;
+	event.u.createNotify.window = wid;
+	event.u.createNotify.parent = pParent->drawable.id;
+	event.u.createNotify.x = x;
+	event.u.createNotify.y = y;
+	event.u.createNotify.width = w;
+	event.u.createNotify.height = h;
+	event.u.createNotify.borderWidth = bw;
+	event.u.createNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pParent, &event, 1, NullWindow);		
+    }
+    return pWin;
+}
+
+static void
+#if NeedFunctionPrototypes
+FreeWindowResources(register WindowPtr pWin)
+#else
+FreeWindowResources(pWin)
+    register WindowPtr pWin;
+#endif
+{
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DeleteWindowFromAnySaveSet(pWin);
+    DeleteWindowFromAnySelections(pWin);
+    DeleteWindowFromAnyEvents(pWin, TRUE);
+    REGION_UNINIT(pScreen, &pWin->clipList);
+    REGION_UNINIT(pScreen, &pWin->winSize);
+    REGION_UNINIT(pScreen, &pWin->borderClip);
+    REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+    if (wBoundingShape (pWin))
+	REGION_DESTROY(pScreen, wBoundingShape (pWin));
+    if (wClipShape (pWin))
+	REGION_DESTROY(pScreen, wClipShape (pWin));
+#endif
+    if (pWin->borderIsPixel == FALSE)
+	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+    if (pWin->backgroundState == BackgroundPixmap)
+	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+    DeleteAllWindowProperties(pWin);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->DestroyWindow)(pWin);
+    DisposeWindowOptional (pWin);
+}
+
+static void
+#if NeedFunctionPrototypes
+CrushTree(WindowPtr pWin)
+#else
+CrushTree(pWin)
+    WindowPtr pWin;
+#endif
+{
+    register WindowPtr pChild, pSib, pParent;
+    UnrealizeWindowProcPtr UnrealizeWindow;
+    xEvent event;
+
+    if (!(pChild = pWin->firstChild))
+	return;
+    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+    while (1)
+    {
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (1)
+	{
+	    pParent = pChild->parent;
+	    if (SubStrSend(pChild, pParent))
+	    {
+		event.u.u.type = DestroyNotify;
+		event.u.destroyNotify.window = pChild->drawable.id;
+		DeliverEvents(pChild, &event, 1, NullWindow);		
+	    }
+	    FreeResource(pChild->drawable.id, RT_WINDOW);
+	    pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder && pChild->viewable)
+		deltaSaveUndersViewable--;
+#endif
+	    pChild->viewable = FALSE;
+	    if (pChild->realized)
+	    {
+		pChild->realized = FALSE;
+		(*UnrealizeWindow)(pChild);
+	    }
+	    FreeWindowResources(pChild);
+	    xfree(pChild);
+	    if ( (pChild = pSib) )
+		break;
+	    pChild = pParent;
+	    pChild->firstChild = NullWindow;
+	    pChild->lastChild = NullWindow;
+	    if (pChild == pWin)
+		return;
+	}
+    }
+}
+	
+/*****
+ *  DeleteWindow
+ *	 Deletes child of window then window itself
+ *	 If wid is None, don't send any events
+ *****/
+
+/*ARGSUSED*/
+int
+DeleteWindow(value, wid)
+    pointer value;
+    XID wid;
+ {
+    register WindowPtr pParent;
+    register WindowPtr pWin = (WindowPtr)value;
+    xEvent event;
+
+    UnmapWindow(pWin, FALSE);
+
+    CrushTree(pWin);
+
+    pParent = pWin->parent;
+    if (wid && pParent && SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = DestroyNotify;
+	event.u.destroyNotify.window = pWin->drawable.id;
+	DeliverEvents(pWin, &event, 1, NullWindow);		
+    }
+
+    FreeWindowResources(pWin);
+    if (pParent)
+    {
+	if (pParent->firstChild == pWin)
+	    pParent->firstChild = pWin->nextSib;
+	if (pParent->lastChild == pWin)
+	    pParent->lastChild = pWin->prevSib;
+	if (pWin->nextSib)
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	if (pWin->prevSib)
+	    pWin->prevSib->nextSib = pWin->nextSib;
+    }
+    xfree(pWin);
+
+    if (pWin -> optional &&
+            pWin -> optional -> colormap &&
+                pWin -> parent)
+    {
+      nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+    }
+
+    return Success;
+}
+
+/*ARGSUSED*/
+void
+DestroySubwindows(pWin, client)
+    register WindowPtr pWin;
+    ClientPtr client;
+{
+    /* XXX
+     * The protocol is quite clear that each window should be
+     * destroyed in turn, however, unmapping all of the first
+     * eliminates most of the calls to ValidateTree.  So,
+     * this implementation is incorrect in that all of the
+     * UnmapNotifies occur before all of the DestroyNotifies.
+     * If you care, simply delete the call to UnmapSubwindows.
+     */
+    UnmapSubwindows(pWin);
+    while (pWin->lastChild)
+	FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+    ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ *  ChangeWindowAttributes
+ *   
+ *  The value-mask specifies which attributes are to be changed; the
+ *  value-list contains one value for each one bit in the mask, from least
+ *  to most significant bit in the mask.  
+ *****/
+ 
+int
+ChangeWindowAttributes(pWin, vmask, vlist, client)
+    register WindowPtr pWin;
+    Mask vmask;
+    XID *vlist;
+    ClientPtr client;
+{
+    register Mask index2;
+    register XID *pVlist;
+    PixmapPtr pPixmap;
+    Pixmap pixID;
+    CursorPtr pCursor, pOldCursor;
+    Cursor cursorID;
+    WindowPtr pChild;
+    Colormap cmap;
+    ColormapPtr	pCmap;
+    xEvent xE;
+    int result;
+    register ScreenPtr pScreen;
+    Mask vmaskCopy = 0;
+    register Mask tmask;
+    unsigned int val;
+    int error;
+    Bool checkOptional = FALSE;
+    Bool borderRelative = FALSE;
+    WindowPtr pLayerWin;
+
+    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+	return BadMatch;
+
+    error = Success;
+    pScreen = pWin->drawable.pScreen;
+    pVlist = vlist;
+    tmask = vmask;
+    while (tmask)
+    {
+	index2 = (Mask) lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBackPixmap:
+	    pixID = (Pixmap )*pVlist;
+	    pVlist++;
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pixID == None)
+	    {
+#ifdef XCSECURITY
+		/*  can't let untrusted clients have background None windows */
+		if (client->trustLevel == XSecurityClientTrusted)
+		{
+#endif
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = None;
+#ifdef XCSECURITY
+		}
+		else
+		{ /* didn't change the background to None, so don't tell ddx */
+		    index2 = 0; 
+		}
+#endif
+	    }
+	    else if (pixID == ParentRelative)
+	    {
+		if (pWin->parent &&
+		    pWin->drawable.depth != pWin->parent->drawable.depth)
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = ParentRelative;
+		borderRelative = TRUE;
+		/* Note that the parent's backgroundTile's refcnt is NOT
+		 * incremented. */
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+						RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap != (PixmapPtr) NULL)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->backgroundState == BackgroundPixmap)
+			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    pWin->backgroundState = BackgroundPixmap;
+		    pWin->background.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBackPixel:
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pWin->backgroundState == BackgroundPixmap)
+		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+	    pWin->backgroundState = BackgroundPixel;
+	    pWin->background.pixel = (CARD32 ) *pVlist;
+		   /* background pixel overrides background pixmap,
+		      so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBackPixmap;
+	    pVlist++;
+	    break;
+	  case CWBorderPixmap:
+	    pixID = (Pixmap ) *pVlist;
+	    pVlist++;
+	    if (pixID == CopyFromParent)
+	    {
+		if (!pWin->parent ||
+		    (pWin->drawable.depth != pWin->parent->drawable.depth))
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->borderIsPixel == FALSE)
+		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		pWin->border = pWin->parent->border;
+		if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+		{
+		    index2 = CWBorderPixel;
+		}
+		else
+		{
+		    pWin->parent->border.pixmap->refcnt++;
+		}
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+					RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->borderIsPixel == FALSE)
+			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		    pWin->borderIsPixel = FALSE;
+		    pWin->border.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBorderPixel:
+	    if (pWin->borderIsPixel == FALSE)
+		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+	    pWin->borderIsPixel = TRUE;
+	    pWin->border.pixel = (CARD32) *pVlist;
+		    /* border pixel overrides border pixmap,
+		       so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBorderPixmap;
+	    pVlist++;
+	    break;
+	  case CWBitGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->bitGravity = val;
+	    break;
+	  case CWWinGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->winGravity = val;
+	    break;
+	  case CWBackingStore:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->backingStore = val;
+
+            #ifdef TEST
+            fprintf(stderr, "ChangeWindowAttributes: Changed backing store value to %d for window at %p.\n",
+                        val, (void*)pWin);
+            #endif
+
+	    pWin->forcedBS = FALSE;
+	    break;
+	  case CWBackingPlanes:
+	    if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+		if ((CARD32)*pVlist == (CARD32)~0L)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWBackingPixel:
+	    if (pWin->optional || (CARD32) *pVlist) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingPixel = (CARD32) *pVlist;
+		if (!*pVlist)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWSaveUnder:
+	    val = (BOOL) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+		DO_SAVE_UNDERS(pWin))
+	    {
+		/*
+		 * Re-check all siblings and inferiors for obscurity or
+		 * exposition (hee hee).
+		 */
+		if (pWin->saveUnder)
+		    deltaSaveUndersViewable--;
+		else
+		    deltaSaveUndersViewable++;
+		pWin->saveUnder = val;
+
+		if (pWin->firstChild)
+		{
+                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+                                                       pWin->nextSib);
+               }
+               else
+               {
+                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pWin,
+                                                       pWin->nextSib);
+               }                                   
+	    }
+	    else
+	    {
+		/*  If we're changing the saveUnder attribute of the root 
+		 *  window, all we do is set pWin->saveUnder so that
+		 *  GetWindowAttributes returns the right value.  We don't
+		 *  do the "normal" save-under processing (as above).
+		 *  Hope that doesn't cause any problems.
+		 */
+		pWin->saveUnder = val;
+	    }
+#else
+	    pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+	    break;
+	  case CWEventMask:
+            /*
+             * TODO: Some applications like java bean shell
+             * don' t work if they cannot monitor the root
+             * window for Structure Redirect events. However
+             * this doesn't seem to be the best solution, since
+             * also an X server with a window manager running,
+             * doesn't allow to monitor for those events, but
+             * the java bean shell works flawlessy on this
+             * server.
+             *
+             * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
+             * {
+             *   return BadAccess;
+             * }
+             */
+
+	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWDontPropagate:
+	    result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+					    &checkOptional);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWOverrideRedirect:
+	    val = (BOOL ) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->overrideRedirect = val;
+	    break;
+	  case CWColormap:
+	    cmap = (Colormap) *pVlist;
+	    pVlist++;
+	    if (cmap == CopyFromParent)
+	    {
+#ifdef XAPPGROUP
+		Colormap ag_colormap;
+		ClientPtr win_owner;
+
+		/*
+		 * win_owner == client for CreateWindow, other clients
+		 * can ChangeWindowAttributes
+		 */
+		win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+		if ( win_owner && win_owner->appgroup &&
+		    !pWin->parent->parent &&
+		    (ag_colormap = XagDefaultColormap (win_owner)))
+		    cmap = ag_colormap;
+		else
+#endif
+		if (pWin->parent &&
+		    (!pWin->optional ||
+		     pWin->optional->visual == wVisual (pWin->parent)))
+		{
+		    cmap = wColormap (pWin->parent);
+		}
+		else
+		    cmap = None;
+	    }
+	    if (cmap == None)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+					      RT_COLORMAP, SecurityReadAccess);
+	    if (!pCmap)
+	    {
+		error = BadColor;
+		client->errorValue = cmap;
+		goto PatchUp;
+	    }
+	    if (pCmap->pVisual->vid != wVisual (pWin) ||
+		pCmap->pScreen != pScreen)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    if (cmap != wColormap (pWin))
+	    {
+		if (!pWin->optional)
+		{
+		    if (!MakeWindowOptional (pWin))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+		else if (pWin->parent && cmap == wColormap (pWin->parent))
+		    checkOptional = TRUE;
+
+		/*
+		 * propagate the original colormap to any children
+		 * inheriting it
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pWin->optional->colormap = cmap;
+
+		/*
+		 * check on any children now matching the new colormap
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (pChild->optional->colormap == cmap)
+			CheckWindowOptionalNeed (pChild);
+		}
+	
+		xE.u.u.type = ColormapNotify;
+		xE.u.colormap.window = pWin->drawable.id;
+		xE.u.colormap.colormap = cmap;
+		xE.u.colormap.new = xTrue;
+		xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+		DeliverEvents(pWin, &xE, 1, NullWindow);
+	    }
+	    break;
+	  case CWCursor:
+	    cursorID = (Cursor ) *pVlist;
+	    pVlist++;
+	    /*
+	     * install the new
+	     */
+	    if ( cursorID == None)
+	    {
+		if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+		    pCursor = rootCursor;
+		else
+		    pCursor = (CursorPtr) None;
+	    }
+	    else
+	    {
+		pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+						RT_CURSOR, SecurityReadAccess);
+		if (!pCursor)
+		{
+		    error = BadCursor;
+		    client->errorValue = cursorID;
+		    goto PatchUp;
+		}
+	    }
+
+	    if (pCursor != wCursor (pWin))
+	    {
+		/*
+		 * patch up child windows so they don't lose cursors.
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !pChild->cursorIsNone &&
+			!MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pOldCursor = 0;
+		if (pCursor == (CursorPtr) None)
+		{
+		    pWin->cursorIsNone = TRUE;
+		    if (pWin->optional)
+		    {
+			pOldCursor = pWin->optional->cursor;
+			pWin->optional->cursor = (CursorPtr) None;
+			checkOptional = TRUE;
+		    }
+		} else {
+		    if (!pWin->optional)
+		    {
+			if (!MakeWindowOptional (pWin))
+			{
+			    error = BadAlloc;
+			    goto PatchUp;
+			}
+		    }
+		    else if (pWin->parent && pCursor == wCursor (pWin->parent))
+			checkOptional = TRUE;
+		    pOldCursor = pWin->optional->cursor;
+		    pWin->optional->cursor = pCursor;
+		    pCursor->refcnt++;
+		    pWin->cursorIsNone = FALSE;
+		    /*
+		     * check on any children now matching the new cursor
+		     */
+
+		    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+		    {
+			if (pChild->optional &&
+			    (pChild->optional->cursor == pCursor))
+			    CheckWindowOptionalNeed (pChild);
+		    }
+		}
+
+		if (pWin->realized)
+		    WindowHasNewCursor( pWin);
+
+		/* Can't free cursor until here - old cursor
+		 * is needed in WindowHasNewCursor
+		 */
+		if (pOldCursor)
+		    FreeCursor (pOldCursor, (Cursor)0);
+	    }
+	    break;
+	 default:
+	    error = BadValue;
+	    client->errorValue = vmask;
+	    goto PatchUp;
+      }
+      vmaskCopy |= index2;
+    }
+PatchUp:
+    if (checkOptional)
+	CheckWindowOptionalNeed (pWin);
+
+	/* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+    /* 
+	If the border contents have changed, redraw the border. 
+	Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+	for the tile to be rotated, and the correct function selected.
+    */
+    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+	&& pWin->viewable && HasBorder (pWin))
+    {
+	RegionRec exposed;
+
+	REGION_INIT(pScreen, &exposed, NullBox, 0);
+	REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+	(*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+	REGION_UNINIT(pScreen, &exposed);
+    }
+    return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ *    Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(pWin, client, wa)
+    register WindowPtr pWin;
+    ClientPtr client;
+    xGetWindowAttributesReply *wa;
+{
+    wa->type = X_Reply;
+    wa->bitGravity = pWin->bitGravity;
+    wa->winGravity = pWin->winGravity;
+    if (pWin->forcedBS && pWin->backingStore != Always)
+	wa->backingStore = NotUseful;
+    else
+	wa->backingStore = pWin->backingStore;
+    wa->length = (sizeof(xGetWindowAttributesReply) -
+		 sizeof(xGenericReply)) >> 2;
+    wa->sequenceNumber = client->sequence;
+    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
+    wa->backingPixel =  wBackingPixel (pWin);
+    wa->saveUnder = (BOOL)pWin->saveUnder;
+    wa->override = pWin->overrideRedirect;
+    if (!pWin->mapped)
+	wa->mapState = IsUnmapped;
+    else if (pWin->realized)
+	wa->mapState = IsViewable;
+    else
+	wa->mapState = IsUnviewable;
+
+    wa->colormap =  wColormap (pWin);
+    wa->mapInstalled = (wa->colormap == None) ? xFalse
+				: IsMapInstalled(wa->colormap, pWin);
+
+    wa->yourEventMask = EventMaskForClient(pWin, client);
+    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+    wa->doNotPropagateMask = wDontPropagateMask (pWin);
+    wa->class = pWin->drawable.class;
+    wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(pWin, pNextSib)
+    register WindowPtr pWin, pNextSib;
+{
+    register WindowPtr pParent = pWin->parent;
+    WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+    if (pWin->nextSib != pNextSib)
+    {
+	WindowPtr pOldNextSib = pWin->nextSib;
+
+	if (!pNextSib)	      /* move to bottom */
+	{
+	    if (pParent->firstChild == pWin)
+		pParent->firstChild = pWin->nextSib;
+	    /* if (pWin->nextSib) */	 /* is always True: pNextSib == NULL
+					  * and pWin->nextSib != pNextSib
+					  * therefore pWin->nextSib != NULL */
+	    pFirstChange = pWin->nextSib;
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pParent->lastChild->nextSib = pWin;
+	    pWin->prevSib = pParent->lastChild;
+	    pWin->nextSib = NullWindow;
+	    pParent->lastChild = pWin;
+	}
+	else if (pParent->firstChild == pNextSib) /* move to top */
+	{
+	    pFirstChange = pWin;
+	    if (pParent->lastChild == pWin)
+	       pParent->lastChild = pWin->prevSib;
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pParent->firstChild;
+	    pWin->prevSib = (WindowPtr ) NULL;
+	    pNextSib->prevSib = pWin;
+	    pParent->firstChild = pWin;
+	}
+	else			/* move in middle of list */
+	{
+	    WindowPtr pOldNext = pWin->nextSib;
+
+	    pFirstChange = NullWindow;
+	    if (pParent->firstChild == pWin)
+		pFirstChange = pParent->firstChild = pWin->nextSib;
+	    if (pParent->lastChild == pWin) {
+	       pFirstChange = pWin;
+	       pParent->lastChild = pWin->prevSib;
+	    }
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pNextSib;
+	    pWin->prevSib = pNextSib->prevSib;
+	    if (pNextSib->prevSib)
+		pNextSib->prevSib->nextSib = pWin;
+	    pNextSib->prevSib = pWin;
+	    if (!pFirstChange) {		     /* do we know it yet? */
+		pFirstChange = pParent->firstChild;  /* no, search from top */
+		while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+		     pFirstChange = pFirstChange->nextSib;
+	    }
+	}
+	if(pWin->drawable.pScreen->RestackWindow)
+	    (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+    }
+
+    return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (pWin)
+    register WindowPtr	 pWin;
+{
+    RegionPtr	pRgn;
+    BoxRec	box;
+
+    box.x1 = pWin->drawable.x;
+    box.y1 = pWin->drawable.y;
+    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	REGION_PTR(pScreen, pWin)
+
+	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+    }
+#endif
+    return pRgn;
+}
+
+void
+SetWinSize (pWin)
+    register WindowPtr pWin;
+{
+    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+			 pWin->drawable.x, pWin->drawable.y,
+			 (int)pWin->drawable.width,
+			 (int)pWin->drawable.height);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	REGION_PTR(pScreen, pWin)
+
+	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+			 pWin->drawable.y);
+    }
+#endif
+}
+
+void
+SetBorderSize (pWin)
+    register WindowPtr pWin;
+{
+    int	bw;
+
+    if (HasBorder (pWin)) {
+	bw = wBorderWidth (pWin);
+	ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+		pWin->drawable.x - bw, pWin->drawable.y - bw,
+		(int)(pWin->drawable.width + (bw<<1)),
+		(int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+	if (wBoundingShape (pWin)) {
+	    REGION_PTR(pScreen, pWin)
+
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+			     - pWin->drawable.y);
+	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+			     wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+			     pWin->drawable.y);
+	    REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+			 &pWin->winSize);
+	}
+#endif
+    } else {
+	REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+					       &pWin->winSize);
+    }
+}
+
+void
+GravityTranslate (x, y, oldx, oldy, dw, dh, gravity, destx, desty)
+    register int x, y;		/* new window position */
+    int		oldx, oldy;	/* old window position */
+    int		dw, dh;
+    unsigned	gravity;
+    register int *destx, *desty;	/* position relative to gravity */
+{
+    switch (gravity) {
+    case NorthGravity:
+	*destx = x + dw / 2;
+	*desty = y;
+	break;
+    case NorthEastGravity:
+	*destx = x + dw;
+	*desty = y;
+	break;
+    case WestGravity:
+	*destx = x;
+	*desty = y + dh / 2;
+	break;
+    case CenterGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh / 2;
+	break;
+    case EastGravity:
+	*destx = x + dw;
+	*desty = y + dh / 2;
+	break;
+    case SouthWestGravity:
+	*destx = x;
+	*desty = y + dh;
+	break;
+    case SouthGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh;
+	break;
+    case SouthEastGravity:
+	*destx = x + dw;
+	*desty = y + dh;
+	break;
+    case StaticGravity:
+	*destx = oldx;
+	*desty = oldy;
+	break;
+    default:
+	*destx = x;
+	*desty = y;
+	break;
+    }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(pWin, dx, dy, dw, dh)
+    register WindowPtr pWin;
+    int dx, dy, dw, dh;
+{
+    register ScreenPtr pScreen;
+    register WindowPtr pSib, pChild;
+    Bool resized = (dw || dh);
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+    {
+	if (resized && (pSib->winGravity > NorthWestGravity))
+	{
+	    int cwsx, cwsy;
+
+	    cwsx = pSib->origin.x;
+	    cwsy = pSib->origin.y;
+	    GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+			pSib->winGravity, &cwsx, &cwsy);
+	    if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+	    {
+		xEvent event;
+
+		event.u.u.type = GravityNotify;
+		event.u.gravity.window = pSib->drawable.id;
+		event.u.gravity.x = cwsx - wBorderWidth (pSib);
+		event.u.gravity.y = cwsy - wBorderWidth (pSib);
+		DeliverEvents (pSib, &event, 1, NullWindow);
+		pSib->origin.x = cwsx;
+		pSib->origin.y = cwsy;
+	    }
+	}
+	pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+	SetWinSize (pSib);
+	SetBorderSize (pSib);
+
+        /*
+         * Don't force X to move children. It will position them
+         * according with gravity.
+         *
+         * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+         */
+
+        /*
+         * Update pSib privates, as this window is moved by X.
+         */
+
+        nxagentAddConfiguredWindow(pSib, CW_Update);
+
+	if ( (pChild = pSib->firstChild) )
+	{
+	    while (1)
+	    {
+		pChild->drawable.x = pChild->parent->drawable.x +
+				     pChild->origin.x;
+		pChild->drawable.y = pChild->parent->drawable.y +
+				     pChild->origin.y;
+		SetWinSize (pChild);
+		SetBorderSize (pChild);
+
+                (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
+                                               pChild->drawable.y);
+
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+		while (!pChild->nextSib && (pChild != pSib))
+		    pChild = pChild->parent;
+		if (pChild == pSib)
+		    break;
+		pChild = pChild->nextSib;
+	    }
+	}
+    }
+}
+
+#define GET_INT16(m, f) \
+	if (m & mask) \
+	  { \
+	     f = (INT16) *pVlist;\
+	    pVlist++; \
+	 }
+#define GET_CARD16(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD16) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define GET_CARD8(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD8) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ *     returns Above if pSib above pMe in stack or Below otherwise 
+ */
+
+static int
+#if NeedFunctionPrototypes
+IsSiblingAboveMe(
+    register WindowPtr pMe,
+    register WindowPtr pSib)
+#else
+IsSiblingAboveMe(pMe, pSib)
+    register WindowPtr pMe, pSib;
+#endif
+{
+    register WindowPtr pWin;
+
+    pWin = pMe->parent->firstChild;
+    while (pWin)
+    {
+	if (pWin == pSib)
+	    return(Above);
+	else if (pWin == pMe)
+	    return(Below);
+	pWin = pWin->nextSib;
+    }
+    return(Below);
+}
+
+static BoxPtr
+#if NeedFunctionPrototypes
+WindowExtents(
+    register WindowPtr pWin,
+    register BoxPtr pBox)
+#else
+WindowExtents(pWin, pBox)
+    register WindowPtr pWin;
+    register BoxPtr pBox;
+#endif
+{
+    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+	       + wBorderWidth (pWin);
+    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+	       + wBorderWidth (pWin);
+    return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin)	(wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+#if NeedFunctionPrototypes
+MakeBoundingRegion (
+    register WindowPtr	pWin,
+    BoxPtr	pBox)
+#else
+MakeBoundingRegion (pWin, pBox)
+    register WindowPtr	pWin;
+    BoxPtr	pBox;
+#endif
+{
+    RegionPtr	pRgn;
+    REGION_PTR(pScreen, pWin)
+
+    pRgn = REGION_CREATE(pScreen, pBox, 1);
+    if (wBoundingShape (pWin)) {
+	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+						  -pWin->origin.y);
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+						  pWin->origin.y);
+    }
+    return pRgn;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+ShapeOverlap (
+    WindowPtr	pWin,
+    BoxPtr	pWinBox,
+    WindowPtr	pSib,
+    BoxPtr	pSibBox)
+#else
+ShapeOverlap (pWin, pWinBox, pSib, pSibBox)
+    WindowPtr	pWin, pSib;
+    BoxPtr	pWinBox, pSibBox;
+#endif
+{
+    RegionPtr	pWinRgn, pSibRgn;
+    register ScreenPtr	pScreen;
+    Bool	ret;
+
+    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+	return TRUE;
+    pScreen = pWin->drawable.pScreen;
+    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pSibRgn);
+    return ret;
+}
+#endif
+
+static Bool
+#if NeedFunctionPrototypes
+AnyWindowOverlapsMe(
+    WindowPtr pWin,
+    WindowPtr pHead,
+    register BoxPtr box)
+#else
+AnyWindowOverlapsMe(pWin, pHead, box)
+    WindowPtr pWin, pHead;
+    register BoxPtr box;
+#endif
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+static Bool
+#if NeedFunctionPrototypes
+IOverlapAnyWindow(
+    WindowPtr pWin,
+    register BoxPtr box)
+#else
+IOverlapAnyWindow(pWin, box)
+    WindowPtr pWin;
+    register BoxPtr box;
+#endif
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+/*
+ *   WhereDoIGoInTheStack() 
+ *	  Given pWin and pSib and the relationshipe smode, return
+ *	  the window that pWin should go ABOVE.
+ *	  If a pSib is specified:
+ *	      Above:  pWin is placed just above pSib
+ *	      Below:  pWin is placed just below pSib
+ *	      TopIf:  if pSib occludes pWin, then pWin is placed
+ *		      at the top of the stack
+ *	      BottomIf:	 if pWin occludes pSib, then pWin is 
+ *			 placed at the bottom of the stack
+ *	      Opposite: if pSib occludes pWin, then pWin is placed at the
+ *			top of the stack, else if pWin occludes pSib, then
+ *			pWin is placed at the bottom of the stack
+ *
+ *	  If pSib is NULL:
+ *	      Above:  pWin is placed at the top of the stack
+ *	      Below:  pWin is placed at the bottom of the stack
+ *	      TopIf:  if any sibling occludes pWin, then pWin is placed at
+ *		      the top of the stack
+ *	      BottomIf: if pWin occludes any sibline, then pWin is placed at
+ *			the bottom of the stack
+ *	      Opposite: if any sibling occludes pWin, then pWin is placed at
+ *			the top of the stack, else if pWin occludes any
+ *			sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+#if NeedFunctionPrototypes
+WhereDoIGoInTheStack(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    short x,
+    short y,
+    unsigned short w,
+    unsigned short h,
+    int smode)
+#else
+WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode)
+    register WindowPtr pWin, pSib;
+    short x, y;
+    unsigned short w, h;
+    int smode;
+#endif
+{
+    BoxRec box;
+    register ScreenPtr pScreen;
+    WindowPtr pHead, pFirst;
+
+    if ((pWin == pWin->parent->firstChild) &&
+	(pWin == pWin->parent->lastChild))
+	return((WindowPtr ) NULL);
+    pHead = RealChildHead(pWin->parent);
+    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+    pScreen = pWin->drawable.pScreen;
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + (int)w;
+    box.y2 = y + (int)h;
+    switch (smode)
+    {
+      case Above:
+	if (pSib)
+	   return(pSib);
+	else if (pWin == pFirst)
+	    return(pWin->nextSib);
+	else
+	    return(pFirst);
+      case Below:
+	if (pSib)
+	    if (pSib->nextSib != pWin)
+		return(pSib->nextSib);
+	    else
+		return(pWin->nextSib);
+	else
+	    return NullWindow;
+      case TopIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return(pFirst);
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	    return(pFirst);
+	else
+	    return(pWin->nextSib);
+      case BottomIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return NullWindow;
+	    else
+		return(pWin->nextSib);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return(pWin->nextSib);
+      case Opposite:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+	    {
+		if (IsSiblingAboveMe(pWin, pSib) == Above)
+		    return(pFirst);
+		else
+		    return NullWindow;
+	    }
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	{
+	    /* If I'm occluded, I can't possibly be the first child
+	     * if (pWin == pWin->parent->firstChild)
+	     *	  return pWin->nextSib;
+	     */
+	    return(pFirst);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return pWin->nextSib;
+      default:
+      {
+	ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+	return pWin->nextSib;
+      }
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+ReflectStackChange(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    VTKind  kind)
+#else
+ReflectStackChange(pWin, pSib, kind)
+    register WindowPtr pWin, pSib;
+    VTKind  kind;
+#endif
+{
+/* Note that pSib might be NULL */
+
+    Bool WasViewable = (Bool)pWin->viewable;
+    WindowPtr pParent;
+    Bool anyMarked;
+    WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    /* if this is a root window, can't be restacked */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						      &pLayerWin);
+	if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(pWin, mask, vlist, client)
+    register WindowPtr pWin;
+    register Mask mask;
+    XID *vlist;
+    ClientPtr client;
+{
+#define RESTACK_WIN    0
+#define MOVE_WIN       1
+#define RESIZE_WIN     2
+#define REBORDER_WIN   3
+    register WindowPtr pSib = NullWindow;
+    register WindowPtr pParent = pWin->parent;
+    Window sibwid = 0;
+    Mask index2, tmask;
+    register XID *pVlist;
+    short x,   y, beforeX, beforeY;
+    unsigned short w = pWin->drawable.width,
+		   h = pWin->drawable.height,
+		   bw = pWin->borderWidth;
+    int action, smode = Above;
+#ifdef XAPPGROUP
+    ClientPtr win_owner;
+    ClientPtr ag_leader = NULL;
+#endif
+    xEvent event;
+
+    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+	return(BadMatch);
+
+    if ((mask & CWSibling) && !(mask & CWStackMode))
+	return(BadMatch);
+
+    pVlist = vlist;
+
+    if (pParent)
+    {
+	x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+	y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+    }
+    else
+    {
+	x = pWin->drawable.x;
+	y = pWin->drawable.y;
+    }
+    beforeX = x;
+    beforeY = y;
+    action = RESTACK_WIN;	
+    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	action = MOVE_WIN;
+    }
+	/* or should be resized */
+    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	GET_CARD16(CWWidth, w);
+	GET_CARD16 (CWHeight, h);
+	if (!w || !h)
+	{
+	    client->errorValue = 0;
+	    return BadValue;
+	}
+	action = RESIZE_WIN;
+    }
+    tmask = mask & ~ChangeMask;
+    while (tmask)
+    {
+	index2 = (Mask)lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBorderWidth:
+	    GET_CARD16(CWBorderWidth, bw);
+	    break;
+	  case CWSibling:
+	    sibwid = (Window ) *pVlist;
+	    pVlist++;
+	    pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+						RT_WINDOW, SecurityReadAccess);
+	    if (!pSib)
+	    {
+		client->errorValue = sibwid;
+		return(BadWindow);
+	    }
+	    if (pSib->parent != pParent)
+		return(BadMatch);
+	    if (pSib == pWin)
+		return(BadMatch);
+	    break;
+	  case CWStackMode:
+	    GET_CARD8(CWStackMode, smode);
+	    if ((smode != TopIf) && (smode != BottomIf) &&
+		(smode != Opposite) && (smode != Above) && (smode != Below))
+	    {
+		client->errorValue = smode;
+		return(BadValue);
+	    }
+	    break;
+	  default:
+	    client->errorValue = mask;
+	    return(BadValue);
+	}
+    }
+	/* root really can't be reconfigured, so just return */
+    if (!pParent)
+	return Success;
+
+	/* Figure out if the window should be moved.  Doesnt
+	   make the changes to the window if event sent */
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+
+      fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
+                  pWin, mask, client);
+
+      fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
+                  "smode [%d] pSib [%p]\n",
+                      x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
+    }
+    #endif
+
+    if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
+            pWin -> overrideRedirect == 0 &&
+                nxagentScreenTrap == 0)
+    {
+      nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
+
+      return Success;
+    }
+
+    if (mask & CWStackMode)
+	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+				    pParent->drawable.y + y,
+				    w + (bw << 1), h + (bw << 1), smode);
+    else
+	pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+    ag_leader = XagLeader (win_owner);
+#endif
+
+    if ((!pWin->overrideRedirect) && 
+	(RedirectSend(pParent)
+#ifdef XAPPGROUP
+	|| (win_owner->appgroup && ag_leader && 
+	    XagIsControlledRoot (client, pParent))
+#endif
+	))
+    {
+	event.u.u.type = ConfigureRequest;
+	event.u.configureRequest.window = pWin->drawable.id;
+	if (mask & CWSibling)
+	   event.u.configureRequest.sibling = sibwid;
+	else
+	    event.u.configureRequest.sibling = None;
+	if (mask & CWStackMode)
+	   event.u.u.detail = smode;
+	else
+	    event.u.u.detail = Above;
+	event.u.configureRequest.x = x;
+	event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+            event.u.configureRequest.x += panoramiXdataPtr[0].x;
+            event.u.configureRequest.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureRequest.width = w;
+	event.u.configureRequest.height = h;
+	event.u.configureRequest.borderWidth = bw;
+	event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+	/* make sure if the ag_leader maps the window it goes to the wm */
+	if (ag_leader && ag_leader != client && 
+	    XagIsControlledRoot (client, pParent)) {
+	    event.u.configureRequest.parent = XagId (win_owner);
+	    (void) TryClientEvents (ag_leader, &event, 1,
+				    NoEventMask, NoEventMask, NullGrab);
+	    return Success;
+	}
+#endif
+	event.u.configureRequest.parent = pParent->drawable.id;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+    if (action == RESIZE_WIN)
+    {
+	Bool size_change = (w != pWin->drawable.width)
+			|| (h != pWin->drawable.height);
+	if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+	{
+	    xEvent eventT;
+	    eventT.u.u.type = ResizeRequest;
+	    eventT.u.resizeRequest.window = pWin->drawable.id;
+	    eventT.u.resizeRequest.width = w;
+	    eventT.u.resizeRequest.height = h;
+	    if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+				       ResizeRedirectMask, client) == 1)
+	    {
+		/* if event is delivered, leave the actual size alone. */
+		w = pWin->drawable.width;
+		h = pWin->drawable.height;
+		size_change = FALSE;
+	    }
+	}
+	if (!size_change)
+	{
+	    if (mask & (CWX | CWY))
+		action = MOVE_WIN;
+	    else if (mask & (CWStackMode | CWBorderWidth))
+		action = RESTACK_WIN;
+	    else   /* really nothing to do */
+		return(Success) ;
+	}
+    }
+
+    if (action == RESIZE_WIN)
+	    /* we've already checked whether there's really a size change */
+	    goto ActuallyDoSomething;
+    if ((mask & CWX) && (x != beforeX))
+	    goto ActuallyDoSomething;
+    if ((mask & CWY) && (y != beforeY))
+	    goto ActuallyDoSomething;
+    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+	    goto ActuallyDoSomething;
+    if (mask & CWStackMode)
+    {
+	if (pWin->nextSib != pSib)
+	    goto ActuallyDoSomething;
+    }
+    return(Success);
+
+ActuallyDoSomething:
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = ConfigureNotify;
+	event.u.configureNotify.window = pWin->drawable.id;
+	if (pSib)
+	    event.u.configureNotify.aboveSibling = pSib->drawable.id;
+	else
+	    event.u.configureNotify.aboveSibling = None;
+	event.u.configureNotify.x = x;
+	event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+	    event.u.configureNotify.x += panoramiXdataPtr[0].x;
+            event.u.configureNotify.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureNotify.width = w;
+	event.u.configureNotify.height = h;
+	event.u.configureNotify.borderWidth = bw;
+	event.u.configureNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (mask & CWBorderWidth)
+    {
+	if (action == RESTACK_WIN)
+	{
+	    action = MOVE_WIN;
+	    pWin->borderWidth = bw;
+	}
+	else if ((action == MOVE_WIN) &&
+		 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+		 (beforeY + wBorderWidth (pWin) == y + (int)bw))
+	{
+	    action = REBORDER_WIN;
+	    (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+	}
+	else
+	    pWin->borderWidth = bw;
+    }
+    if (action == MOVE_WIN)
+	(*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+		   (mask & CWBorderWidth) ? VTOther : VTMove);
+    else if (action == RESIZE_WIN)
+	(*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+    else if (mask & CWStackMode)
+	ReflectStackChange(pWin, pSib, VTOther);
+
+    if (action != RESTACK_WIN)
+	CheckCursorConfinement(pWin);
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ *    For RaiseLowest, raises the lowest mapped child (if any) that is
+ *    obscured by another child to the top of the stack.  For LowerHighest,
+ *    lowers the highest mapped child (if any) that is obscuring another
+ *    child to the bottom of the stack.	 Exposure processing is performed 
+ *
+ ******/
+
+int
+CirculateWindow(pParent, direction, client)
+    WindowPtr pParent;
+    int direction;
+    ClientPtr client;
+{
+    register WindowPtr pWin, pHead, pFirst;
+    xEvent event;
+    BoxRec box;
+
+    #ifdef TEST
+    fprintf(stderr, "CirculateWindow: pParent [%p] direction [%d] client [%p]\n",
+                pParent, direction, client);
+    #endif
+
+    /*
+     * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+     *         nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
+     * {
+     *   nxagentCirculateRootlessWindows(direction);
+     *   return Success;
+     * }
+     */
+
+    pHead = RealChildHead(pParent);
+    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+    if (direction == RaiseLowest)
+    {
+	for (pWin = pParent->lastChild;
+	     (pWin != pHead) &&
+	     !(pWin->mapped &&
+	       AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+	     pWin = pWin->prevSib) ;
+	if (pWin == pHead)
+	    return Success;
+    }
+    else
+    {
+	for (pWin = pFirst;
+	     pWin &&
+	     !(pWin->mapped &&
+	       IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+	     pWin = pWin->nextSib) ;
+	if (!pWin)
+	    return Success;
+    }
+
+    event.u.circulate.window = pWin->drawable.id;
+    event.u.circulate.parent = pParent->drawable.id;
+    event.u.circulate.event = pParent->drawable.id;
+    if (direction == RaiseLowest)
+	event.u.circulate.place = PlaceOnTop;
+    else
+	event.u.circulate.place = PlaceOnBottom;
+
+    if (RedirectSend(pParent))
+    {
+	event.u.u.type = CirculateRequest;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+
+    event.u.u.type = CirculateNotify;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+    ReflectStackChange(pWin,
+		       (direction == RaiseLowest) ? pFirst : NullWindow,
+		       VTStack);
+
+    return(Success);
+}
+
+static int
+#if NeedFunctionPrototypes
+CompareWIDs(
+    WindowPtr pWin,
+    pointer   value) /* must conform to VisitWindowProcPtr */
+#else
+CompareWIDs(pWin, value)
+    WindowPtr pWin;
+    pointer   value; /* must conform to VisitWindowProcPtr */
+#endif
+{
+    Window *wid = (Window *)value;
+
+    if (pWin->drawable.id == *wid)
+       return(WT_STOPWALKING);
+    else
+       return(WT_WALKCHILDREN);
+}
+
+/*****
+ *  ReparentWindow
+ *****/
+
+int
+ReparentWindow(pWin, pParent, x, y, client)
+    register WindowPtr pWin, pParent;
+    int x,y;
+    ClientPtr client;
+{
+    WindowPtr pPrev, pPriorParent;
+    Bool WasMapped = (Bool)(pWin->mapped);
+    xEvent event;
+    int bw = wBorderWidth (pWin);
+    register ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+	return(BadMatch);		
+    if (!MakeWindowOptional(pWin))
+	return(BadAlloc);
+
+    if (WasMapped)
+       UnmapWindow(pWin, FALSE);
+
+    event.u.u.type = ReparentNotify;
+    event.u.reparent.window = pWin->drawable.id;
+    event.u.reparent.parent = pParent->drawable.id;
+    event.u.reparent.x = x;
+    event.u.reparent.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && !pParent->parent) {
+	event.u.reparent.x += panoramiXdataPtr[0].x;
+	event.u.reparent.y += panoramiXdataPtr[0].y;
+    }
+#endif
+    event.u.reparent.override = pWin->overrideRedirect;
+    DeliverEvents(pWin, &event, 1, pParent);
+
+    /* take out of sibling chain */
+
+    pPriorParent = pPrev = pWin->parent;
+    if (pPrev->firstChild == pWin)
+	pPrev->firstChild = pWin->nextSib;
+    if (pPrev->lastChild == pWin)
+	pPrev->lastChild = pWin->prevSib;
+
+    if (pWin->nextSib)
+	pWin->nextSib->prevSib = pWin->prevSib;
+    if (pWin->prevSib)
+	pWin->prevSib->nextSib = pWin->nextSib;
+
+    /* insert at begining of pParent */
+    pWin->parent = pParent;
+    pPrev = RealChildHead(pParent);
+
+    if (pWin->parent == WindowTable[0])
+    {
+      nxagentSetTopLevelEventMask(pWin);
+    }
+ 
+    if (pPrev)
+    {
+	pWin->nextSib = pPrev->nextSib;
+	if (pPrev->nextSib)
+	    pPrev->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pPrev->nextSib = pWin;
+	pWin->prevSib = pPrev;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	pWin->prevSib = NullWindow;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.x = x + bw + pParent->drawable.x;
+    pWin->drawable.y = y + bw + pParent->drawable.y;
+
+    /* clip to parent */
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    if (pScreen->ReparentWindow)
+	(*pScreen->ReparentWindow)(pWin, pPriorParent);
+
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    CheckWindowOptionalNeed(pWin);
+
+    if (WasMapped)
+	MapWindow(pWin, client);
+    RecalculateDeliverableEvents(pWin);
+    return(Success);
+}
+
+static void
+#if NeedFunctionPrototypes
+RealizeTree(WindowPtr pWin)
+#else
+RealizeTree(pWin)
+    WindowPtr pWin;
+#endif
+{
+    register WindowPtr pChild;
+    RealizeWindowProcPtr Realize;
+
+    Realize = pWin->drawable.pScreen->RealizeWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->mapped)
+	{
+	    pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder)
+		deltaSaveUndersViewable++;
+#endif
+	    pChild->viewable = (pChild->drawable.class == InputOutput);
+	    (* Realize)(pChild);
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * MapWindow
+ *    If some other client has selected SubStructureReDirect on the parent
+ *    and override-redirect is xFalse, then a MapRequest event is generated,
+ *    but the window remains unmapped.	Otherwise, the window is mapped and a
+ *    MapNotify event is generated.
+ *****/
+
+int
+MapWindow(pWin, client)
+    register WindowPtr pWin;
+    ClientPtr client;
+{
+    register ScreenPtr pScreen;
+
+    register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+    }
+    #endif
+
+    if (pWin->mapped)
+	return(Success);
+
+#ifdef XCSECURITY
+    /*  don't let an untrusted client map a child-of-trusted-window, InputOnly
+     *  window; too easy to steal device input
+     */
+    if ( (client->trustLevel != XSecurityClientTrusted) &&
+	 (pWin->drawable.class == InputOnly) &&
+	 (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+	 return Success;
+#endif	
+
+    pScreen = pWin->drawable.pScreen;
+    if ( (pParent = pWin->parent) )
+    {
+	xEvent event;
+	Bool anyMarked;
+#ifdef XAPPGROUP
+	ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+	ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+	if ((!pWin->overrideRedirect) && 
+	    (RedirectSend(pParent)
+#ifdef XAPPGROUP
+	    || (win_owner->appgroup && ag_leader &&
+		XagIsControlledRoot (client, pParent))
+#endif
+	))
+	{
+	    event.u.u.type = MapRequest;
+	    event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+	    /* make sure if the ag_leader maps the window it goes to the wm */
+	    if (ag_leader && ag_leader != client &&
+		XagIsControlledRoot (client, pParent)) {
+		event.u.mapRequest.parent = XagId (win_owner);
+		(void) TryClientEvents (ag_leader, &event, 1,
+					NoEventMask, NoEventMask, NullGrab);
+		return Success;
+	    }
+#endif
+	    event.u.mapRequest.parent = pParent->drawable.id;
+
+	    if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+		return(Success);
+	}
+
+	pWin->mapped = TRUE;
+	if (SubStrSend(pWin, pParent))
+	{
+	    event.u.u.type = MapNotify;
+	    event.u.mapNotify.window = pWin->drawable.id;
+	    event.u.mapNotify.override = pWin->overrideRedirect;
+	    DeliverEvents(pWin, &event, 1, NullWindow);
+	}
+
+	if (!pParent->realized)
+	    return(Success);
+	RealizeTree(pWin);
+	if (pWin->viewable)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+	    if (DO_SAVE_UNDERS(pWin))
+	    {
+		dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+#endif /* DO_SAVE_UNDERS */
+	    if (anyMarked)
+	    {
+		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+		(*pScreen->HandleExposures)(pLayerWin->parent);
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (dosave)
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+	}
+	WindowsRestructured ();
+    }
+    else
+    {
+	RegionRec   temp;
+
+	pWin->mapped = TRUE;
+	pWin->realized = TRUE;	   /* for roots */
+	pWin->viewable = pWin->drawable.class == InputOutput;
+	/* We SHOULD check for an error value here XXX */
+	(*pScreen->RealizeWindow)(pWin);
+	if (pScreen->ClipNotify)
+	    (*pScreen->ClipNotify) (pWin, 0, 0);
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+	REGION_INIT(pScreen, &temp, NullBox, 0);
+	REGION_COPY(pScreen, &temp, &pWin->clipList);
+	(*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+	REGION_UNINIT(pScreen, &temp);
+    }
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ *    Performs a MapWindow all unmapped children of the window, in top
+ *    to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(pParent, client)
+    register WindowPtr pParent;
+    ClientPtr client;
+{
+    register WindowPtr	pWin;
+    WindowPtr		pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+    WindowPtr		pFirstSaveUndered = NullWindow;
+#endif
+    register ScreenPtr	pScreen;
+    register Mask	parentRedirect;
+    register Mask	parentNotify;
+    xEvent		event;
+    Bool		anyMarked;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr		pLayerWin;
+
+    pScreen = pParent->drawable.pScreen;
+    parentRedirect = RedirectSend(pParent);
+    parentNotify = SubSend(pParent);
+    anyMarked = FALSE;
+    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+    {
+	if (!pWin->mapped)
+	{
+	    if (parentRedirect && !pWin->overrideRedirect)
+	    {
+		event.u.u.type = MapRequest;
+		event.u.mapRequest.window = pWin->drawable.id;
+		event.u.mapRequest.parent = pParent->drawable.id;
+    
+		if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		    SubstructureRedirectMask, client) == 1)
+		    continue;
+	    }
+    
+	    pWin->mapped = TRUE;
+	    if (parentNotify || StrSend(pWin))
+	    {
+		event.u.u.type = MapNotify;
+		event.u.mapNotify.window = pWin->drawable.id;
+		event.u.mapNotify.override = pWin->overrideRedirect;
+		DeliverEvents(pWin, &event, 1, NullWindow);
+	    }
+    
+	    if (!pFirstMapped)
+		pFirstMapped = pWin;
+	    if (pParent->realized)
+	    {
+		RealizeTree(pWin);
+		if (pWin->viewable)
+		{
+		    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							(WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave = TRUE;
+		    }
+#endif /* DO_SAVE_UNDERS */
+		}
+	    }
+	}
+    }
+
+    if (pFirstMapped)
+    {
+	pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+	if (pLayerWin->parent != pParent) {
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+							   pLayerWin,
+							   (WindowPtr *)NULL);
+	    pFirstMapped = pLayerWin;
+	}
+        if (anyMarked)
+        {
+#ifdef DO_SAVE_UNDERS
+	    if (pLayerWin->parent != pParent)
+	    {
+		if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+		{
+		    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+							 pLayerWin);
+		}
+	    }
+	    else if (dosave)
+	    {
+		dosave = FALSE;
+		for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+		{
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+							      pWin->nextSib);
+			if (dosave && !pFirstSaveUndered)
+			    pFirstSaveUndered = pWin;
+		    }
+		}
+            }
+#endif /* DO_SAVE_UNDERS */
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+        if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin,
+					    pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+        if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+					 VTMap);
+        WindowsRestructured ();
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+UnrealizeTree(
+    WindowPtr pWin,
+    Bool fromConfigure)
+#else
+UnrealizeTree(pWin, fromConfigure)
+    WindowPtr pWin;
+    Bool fromConfigure;
+#endif
+{
+    register WindowPtr pChild;
+    UnrealizeWindowProcPtr Unrealize;
+    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->realized)
+	{
+	    pChild->realized = FALSE;
+	    pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+		PanoramiXRes *win;
+		win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+							XRT_WINDOW);
+		if(win)
+		   win->u.win.visibility = VisibilityNotViewable;
+	    } 
+#endif
+	    (* Unrealize)(pChild);
+	    DeleteWindowFromAnyEvents(pChild, FALSE);
+	    if (pChild->viewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		if (pChild->saveUnder)
+		    deltaSaveUndersViewable--;
+#endif
+		pChild->viewable = FALSE;
+		if (pChild->backStorage)
+		    (*pChild->drawable.pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+		(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+		pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    }
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * UnmapWindow
+ *    If the window is already unmapped, this request has no effect.
+ *    Otherwise, the window is unmapped and an UnMapNotify event is
+ *    generated.  Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(pWin, fromConfigure)
+    register WindowPtr pWin;
+    Bool fromConfigure;
+{
+    register WindowPtr pParent;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
+                  fromConfigure);
+    }
+    #endif
+
+    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+	return(Success);
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = UnmapNotify;
+	event.u.unmapNotify.window = pWin->drawable.id;
+	event.u.unmapNotify.fromConfigure = fromConfigure;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (wasViewable && !fromConfigure)
+    {
+	pWin->valdata = UnmapValData;
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+	(*pScreen->MarkWindow)(pLayerWin->parent);
+    }
+    pWin->mapped = FALSE;
+    if (wasRealized)
+	UnrealizeTree(pWin, fromConfigure);
+    if (wasViewable)
+    {
+	if (!fromConfigure)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+	    {
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+	}
+	pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+	if (!fromConfigure && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+    }
+    if (wasRealized && !fromConfigure)
+	WindowsRestructured ();
+    return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ *    Performs an UnmapWindow request with the specified mode on all mapped
+ *    children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(pWin)
+    register WindowPtr pWin;
+{
+    register WindowPtr pChild, pHead;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    Bool anyMarked = FALSE;
+    Mask parentNotify;
+    WindowPtr pLayerWin = NULL;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!pWin->firstChild)
+	return;
+    parentNotify = SubSend(pWin);
+    pHead = RealChildHead(pWin);
+
+    if (wasViewable)
+	pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+	if (pChild->mapped)
+	{
+	    if (parentNotify || StrSend(pChild))
+	    {
+		event.u.u.type = UnmapNotify;
+		event.u.unmapNotify.window = pChild->drawable.id;
+		event.u.unmapNotify.fromConfigure = xFalse;
+		DeliverEvents(pChild, &event, 1, NullWindow);
+	    }
+	    if (pChild->viewable)
+	    {
+		pChild->valdata = UnmapValData;
+		anyMarked = TRUE;
+	    }
+	    pChild->mapped = FALSE;
+	    if (pChild->realized)
+		UnrealizeTree(pChild, FALSE);
+	    if (wasViewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+		if (pChild->backStorage)
+		    (*pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+	    }
+	}
+    }
+    if (wasViewable)
+    {
+	if (anyMarked)
+	{
+	    if (pLayerWin->parent == pWin)
+		(*pScreen->MarkWindow)(pWin);
+	    else
+	    {
+		WindowPtr ptmp;
+                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						  (WindowPtr *)NULL);
+		(*pScreen->MarkWindow)(pLayerWin->parent);
+		
+		/* Windows between pWin and pLayerWin may not have been marked */
+		ptmp = pWin;
+ 
+		while (ptmp != pLayerWin->parent)
+		{
+		    (*pScreen->MarkWindow)(ptmp);
+		    ptmp = ptmp->parent;
+		}
+                pHead = pWin->firstChild;
+	    }
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+    }
+    if (wasRealized)
+	WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(client)
+    register ClientPtr client;
+{
+    register WindowPtr pParent, pWin;
+    register int j;
+
+    for (j=0; j<client->numSaved; j++)
+    {
+	pWin = (WindowPtr)client->saveSet[j];
+	pParent = pWin->parent;
+	while (pParent && (wClient (pParent) == client))
+	    pParent = pParent->parent;
+	if (pParent)
+	{
+	    if (pParent != pWin->parent)
+	    {
+		ReparentWindow(pWin, pParent,
+			       pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+			       pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+			       client);
+		if(!pWin->realized && pWin->mapped)
+		    pWin->mapped = FALSE;
+	    }
+	    MapWindow(pWin, client);
+	}
+    }
+    xfree(client->saveSet);
+    client->numSaved = 0;
+    client->saveSet = (pointer *)NULL;
+}
+
+Bool
+VisibleBoundingBoxFromPoint(pWin, x, y, box)
+    register WindowPtr pWin;
+    int x, y;	/* in root */
+    BoxPtr box;	  /* "return" value */
+{
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+	return(TRUE);
+    return(FALSE);
+}
+
+Bool
+PointInWindowIsVisible(pWin, x, y)
+    register WindowPtr pWin;
+    int x, y;	/* in root */
+{
+    BoxRec box;
+
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+						  x, y, &box))
+	return(TRUE);
+    return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(pWin)
+    register WindowPtr pWin;
+{
+    register ScreenPtr pScreen;
+    RegionPtr pReg;
+
+    pScreen = pWin->drawable.pScreen;
+    pReg = REGION_CREATE(pScreen, NullBox, 1);
+    if (pWin->parent ||
+	screenIsSaved != SCREEN_SAVER_ON ||
+	!HasSaverWindow (pWin->drawable.pScreen->myNum))
+    {
+	REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+    }
+    return(pReg);
+}
+
+void
+SendVisibilityNotify(pWin)
+    WindowPtr pWin;
+{
+    xEvent event;
+    unsigned int visibility = pWin->visibility;
+
+#ifdef PANORAMIX
+    /* This is not quite correct yet, but it's close */
+    if(!noPanoramiXExtension) {
+	PanoramiXRes *win;
+	WindowPtr pWin2;
+	int i, Scrnum;
+
+	Scrnum = pWin->drawable.pScreen->myNum;
+	
+	win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+	if(!win || (win->u.win.visibility == visibility))
+	    return;
+
+	switch(visibility) {
+	case VisibilityUnobscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+		if (pWin2) {
+		    if(pWin2->visibility == VisibilityPartiallyObscured)
+		   	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	case VisibilityPartiallyObscured:
+	    if(Scrnum) {
+	        pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+		if (pWin2) pWin = pWin2;
+	    }
+	    break;
+	case VisibilityFullyObscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+		
+		if (pWin2) {
+		    if(pWin2->visibility != VisibilityFullyObscured)
+		    	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	}
+	
+	win->u.win.visibility = visibility;
+    }
+#endif
+
+    event.u.u.type = VisibilityNotify;
+    event.u.visibility.window = pWin->drawable.id;
+    event.u.visibility.state = visibility;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+#if NeedFunctionPrototypes
+    WindowPtr /*pWin*/
+#endif
+);
+#endif
+
+void
+SaveScreens(on, mode)
+    int on;
+    int mode;
+{
+    int i;
+    int what;
+    int type;
+
+    if (on == SCREEN_SAVER_FORCER)
+    {
+	UpdateCurrentTimeIf();
+	lastDeviceEventTime = currentTime;
+	if (mode == ScreenSaverReset)
+	    what = SCREEN_SAVER_OFF;
+	else
+	    what = SCREEN_SAVER_ON;
+	type = what;
+    }
+    else
+    {
+	what = on;
+	type = what;
+	if (what == screenIsSaved)
+	    type = SCREEN_SAVER_CYCLE;
+    }
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+	if (on == SCREEN_SAVER_FORCER)
+	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+	if (savedScreenInfo[i].ExternalScreenSaver)
+	{
+          if (nxagentOption(Timeout) != 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
+                        "Ignoring it to let the auto-disconnect feature work.\n");
+            #endif
+          }
+          else
+          {
+	      if ((*savedScreenInfo[i].ExternalScreenSaver)
+		  (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+		  continue;
+          }
+	}
+	if (type == screenIsSaved)
+	    continue;
+	switch (type) {
+	case SCREEN_SAVER_OFF:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+	       (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						      what);
+	    }
+	    else if (HasSaverWindow (i))
+	    {
+		savedScreenInfo[i].pWindow = NullWindow;
+		FreeResource(savedScreenInfo[i].wid, RT_NONE);
+	    }
+	    break;
+	case SCREEN_SAVER_CYCLE:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+	    {
+		WindowPtr pWin = savedScreenInfo[i].pWindow;
+		/* make it look like screen saver is off, so that
+		 * NotClippedByChildren will compute a clip list
+		 * for the root window, so miPaintWindow works
+		 */
+		screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+		(*pWin->drawable.pScreen->MoveWindow)(pWin,
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    DrawLogo(pWin);
+#endif
+		screenIsSaved = SCREEN_SAVER_ON;
+	    }
+	    /*
+	     * Call the DDX saver in case it wants to do something
+	     * at cycle time
+	     */
+	    else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+		(* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						       type);
+	    }
+	    break;
+	case SCREEN_SAVER_ON:
+	    if (ScreenSaverBlanking != DontPreferBlanking)
+	    {
+		if ((* screenInfo.screens[i]->SaveScreen)
+		   (screenInfo.screens[i], what))
+		{
+		   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+		   continue;
+		}
+		if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		    TileScreenSaver(i, SCREEN_IS_BLACK))
+		{
+		    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+		    continue;
+		}
+	    }
+	    if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		TileScreenSaver(i, SCREEN_IS_TILED))
+	    {
+		savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+	    }
+	    else
+		savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+	    break;
+	}
+    }
+    screenIsSaved = what;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+TileScreenSaver(int i, int kind)
+#else
+TileScreenSaver(i, kind)
+    int i;
+    int	kind;
+#endif
+{
+    int j;
+    int result;
+    XID attributes[3];
+    Mask mask;
+    WindowPtr pWin;		
+    CursorMetricRec cm;
+    unsigned char *srcbits, *mskbits;
+    CursorPtr cursor;
+    XID	cursorID = 0;
+    int	attri;
+
+    mask = 0;
+    attri = 0;
+    switch (kind) {
+    case SCREEN_IS_TILED:
+	switch (WindowTable[i]->backgroundState) {
+	case BackgroundPixel:
+	    attributes[attri++] = WindowTable[i]->background.pixel;
+	    mask |= CWBackPixel;
+	    break;
+	case BackgroundPixmap:
+	    attributes[attri++] = None;
+	    mask |= CWBackPixmap;
+	    break;
+	default:
+	    break;
+	}
+	break;
+    case SCREEN_IS_BLACK:
+	attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+	mask |= CWBackPixel;
+	break;
+    }
+    mask |= CWOverrideRedirect;
+    attributes[attri++] = xTrue;
+
+    /*
+     * create a blank cursor
+     */
+
+    cm.width=16;
+    cm.height=16;
+    cm.xhot=8;
+    cm.yhot=8;
+    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    if (!srcbits || !mskbits)
+    {
+	xfree(srcbits);
+	xfree(mskbits);
+	cursor = 0;
+    }
+    else
+    {
+	for (j=0; j<BitmapBytePad(32)*16; j++)
+	    srcbits[j] = mskbits[j] = 0x0;
+	cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+	if (cursor)
+	{
+	    cursorID = FakeClientID(0);
+	    if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+	    {
+		attributes[attri] = cursorID;
+		mask |= CWCursor;
+	    }
+	    else
+		cursor = 0;
+	}
+	else
+	{
+	    xfree (srcbits);
+	    xfree (mskbits);
+	}
+    }
+
+    pWin = savedScreenInfo[i].pWindow =
+	 CreateWindow(savedScreenInfo[i].wid,
+	      WindowTable[i],
+	      -RANDOM_WIDTH, -RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+	      0, InputOutput, mask, attributes, 0, serverClient,
+	      wVisual (WindowTable[i]), &result);
+
+    if (cursor)
+	FreeResource (cursorID, RT_NONE);
+
+    if (!pWin)
+	return FALSE;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW,
+		     (pointer)savedScreenInfo[i].pWindow))
+	return FALSE;
+
+    if (mask & CWBackPixmap)
+    {
+	MakeRootTile (pWin);
+	(*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+    }
+    MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+    if (kind == SCREEN_IS_TILED && logoScreenSaver)
+	DrawLogo(pWin);
+#endif
+    return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure.  Assumptions:	 some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (w)
+    register WindowPtr w;
+{
+    do
+	w = w->parent;
+    while (!w->optional);
+    return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules.	 If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (w)
+    register WindowPtr w;
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (!w->parent)
+	return;
+    optional = w->optional;
+    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+	return;
+    if (optional->otherEventMasks != 0)
+	return;
+    if (optional->otherClients != NULL)
+	return;
+    if (optional->passiveGrabs != NULL)
+	return;
+    if (optional->userProps != NULL)
+	return;
+    if (optional->backingBitPlanes != ~0L)
+	return;
+    if (optional->backingPixel != 0)
+	return;
+#ifdef SHAPE
+    if (optional->boundingShape != NULL)
+	return;
+    if (optional->clipShape != NULL)
+	return;
+#endif
+#ifdef XINPUT
+    if (optional->inputMasks != NULL)
+	return;
+#endif
+    parentOptional = FindWindowWithOptional(w)->optional;
+    if (optional->visual != parentOptional->visual)
+	return;
+    if (optional->cursor != None &&
+	(optional->cursor != parentOptional->cursor ||
+	 w->parent->cursorIsNone))
+	return;
+    if (optional->colormap != parentOptional->colormap)
+	return;
+    DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (pWin)
+    register WindowPtr pWin;
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (pWin->optional)
+	return TRUE;
+    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+    if (!optional)
+	return FALSE;
+    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+    optional->otherEventMasks = 0;
+    optional->otherClients = NULL;
+    optional->passiveGrabs = NULL;
+    optional->userProps = NULL;
+    optional->backingBitPlanes = ~0L;
+    optional->backingPixel = 0;
+#ifdef SHAPE
+    optional->boundingShape = NULL;
+    optional->clipShape = NULL;
+#endif
+#ifdef XINPUT
+    optional->inputMasks = NULL;
+#endif
+    parentOptional = FindWindowWithOptional(pWin)->optional;
+    optional->visual = parentOptional->visual;
+    if (!pWin->cursorIsNone)
+    {
+	optional->cursor = parentOptional->cursor;
+	optional->cursor->refcnt++;
+    }
+    else
+    {
+	optional->cursor = None;
+    }
+    optional->colormap = parentOptional->colormap;
+    pWin->optional = optional;
+    return TRUE;
+}
+
+void
+DisposeWindowOptional (pWin)
+    register WindowPtr pWin;
+{
+    if (!pWin->optional)
+	return;
+    /*
+     * everything is peachy.  Delete the optional record
+     * and clean up
+     */
+    /*
+     * TOG changed this code to:
+     *
+     *	    if (pWin->cursorIsNone == FALSE)
+     *		FreeCursor (pWin->optional->cursor, (Cursor)0);
+     *	    pWin->cursorIsNone = TRUE;
+     *
+     * This is blatently wrong; windows without optionals can have
+     * two different cursor values, either None or sharing their
+     * parents cursor.  This difference is controlled by the
+     * cursorIsNone value; when TRUE, the window has no cursor,
+     * when false, it shares its cursor with its parent; TOG
+     * made it impossible for a window to have a cursor without
+     * an optional record.
+     */
+    if (pWin->optional->cursor)
+    {
+	FreeCursor (pWin->optional->cursor, (Cursor)0);
+	pWin->cursorIsNone = FALSE;
+    }
+    else
+	pWin->cursorIsNone = TRUE;
+/* FIXME
+   There is an error when disposing ClientResources on Agent exit
+   this xfree is not valid in some window at exit
+*/
+
+    xfree (pWin->optional);
+    pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+#if NeedFunctionPrototypes
+DrawLogo(WindowPtr pWin)
+#else
+DrawLogo(pWin)
+    WindowPtr pWin;
+#endif
+{
+    DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    int x, y;
+    unsigned int width, height, size;
+    GC *pGC;
+    int thin, gap, d31;
+    DDXPointRec poly[4];
+    ChangeGCVal fore[2], back[2];
+    xrgb rgb[2];
+    BITS32 fmask, bmask;
+    ColormapPtr cmap;
+
+    pDraw = (DrawablePtr)pWin;
+    pScreen = pDraw->pScreen;
+    x = -pWin->origin.x;
+    y = -pWin->origin.y;
+    width = pScreen->width;
+    height = pScreen->height;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pGC)
+	return;
+
+    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+	fore[0].val = pScreen->whitePixel;
+    else
+	fore[0].val = pScreen->blackPixel;
+    if ((pWin->backgroundState == BackgroundPixel) &&
+	(cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+	Pixel querypixels[2];
+
+	querypixels[0] = fore[0].val;
+	querypixels[1] = pWin->background.pixel;
+	QueryColors(cmap, 2, querypixels, rgb);
+	if ((rgb[0].red == rgb[1].red) &&
+	    (rgb[0].green == rgb[1].green) &&
+	    (rgb[0].blue == rgb[1].blue)) {
+	    if (fore[0].val == pScreen->blackPixel)
+		fore[0].val = pScreen->whitePixel;
+	    else
+		fore[0].val = pScreen->blackPixel;
+	}
+    }
+    fore[1].val = FillSolid;
+    fmask = GCForeground|GCFillStyle;
+    if (pWin->backgroundState == BackgroundPixel) {
+	back[0].val = pWin->background.pixel;
+	back[1].val = FillSolid;
+	bmask = GCForeground|GCFillStyle;
+    } else {
+	back[0].val = 0;
+	back[1].val = 0;
+	dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+		    NULL, back);
+	back[0].val = FillTiled;
+	back[1].ptr = pWin->background.pixmap;
+	bmask = GCFillStyle|GCTile;
+    }
+
+    /* should be the same as the reference function XmuDrawLogo() */
+
+    size = width;
+    if (height < width)
+	 size = height;
+    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+    size &= ~1;
+    x += rand() % (width - size);
+    y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ *           -----
+ *          /    /
+ *         /    /
+ *        /    /
+ *       /    /
+ *      /____/
+ *           d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+    thin = (size / 11);
+    if (thin < 1) thin = 1;
+    gap = (thin+3) / 4;
+    d31 = thin + thin + gap;
+    poly[0].x = x + size;	       poly[0].y = y;
+    poly[1].x = x + size-d31;	       poly[1].y = y;
+    poly[2].x = x + 0;		       poly[2].y = y + size;
+    poly[3].x = x + d31;	       poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ *           ------
+ *          /	  /
+ *         /  __ /
+ *        /  /	/
+ *       /  /  /
+ *      /__/__/
+ */
+
+    poly[0].x = x + d31/2;			 poly[0].y = y + size;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)+(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + d31;			 poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ *	     ------
+ *	    /  /  /
+ *	   /--/	 /
+ *	  /	/
+ *	 /     /
+ *	/_____/
+ */
+
+    poly[0].x = x + size - d31/2;		 poly[0].y = y;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)-(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + size - d31;			 poly[3].y = y;
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ *      b
+ * -----
+ * \	\
+ *  \	 \
+ *   \	  \
+ *    \	   \
+ *     \____\
+ */
+
+    poly[0].x = x;		       poly[0].y = y;
+    poly[1].x = x + size/4;	       poly[1].y = y;
+    poly[2].x = x + size;	       poly[2].y = y + size;
+    poly[3].x = x + size - size/4;     poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ *	    /
+ *	   /
+ *	  /
+ *	 /
+ *	/
+ */
+
+    poly[0].x = x + size- thin;	      poly[0].y = y;
+    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
+    poly[2].x = x + thin;	      poly[2].y = y + size;
+    poly[3].x = x + thin + gap;	      poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+    FreeScratchGC(pGC);
+}
+
+#endif
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
new file mode 100644
index 000000000..16328f9ab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
@@ -0,0 +1,4179 @@
+#ifdef NXAGENT_UPGRADE
+
+#include "X/NXwindow.c"
+
+#else
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+			All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "selection.h"
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include "Xagsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+
+#include "Screen.h"
+#include "Options.h"
+#include "Atoms.h"
+#include "Clipboard.h"
+#include "Splash.h"
+#include "Rootless.h"
+#include "Composite.h"
+#include "Drawable.h"
+#include "Colormap.h"
+
+#if defined(NEED_SCREEN_REGIONS)
+#define REGION_PTR(pScreen,pWin) \
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+#else
+#define REGION_PTR(pScreen,pWin) /* nothing */
+#endif
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
+/******
+ * Window stuff for server 
+ *
+ *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(
+#if NeedFunctionPrototypes
+    int /*i*/,
+    int /*kind*/
+#endif
+);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+			      CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+      (!( ((b1)->x2 <= (b2)->x1)  || \
+	( ((b1)->x1 >= (b2)->x2)) || \
+	( ((b1)->y2 <= (b2)->y1)) || \
+	( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+WindowPtr nxagentRootTileWindow;
+
+/*
+ * This block used the DEBUG symbol.
+ */
+
+#ifdef WINDOW_TREE_DEBUG
+/******
+ * PrintWindowTree
+ *    For debugging only
+ ******/
+
+int
+PrintChildren(p1, indent)
+    WindowPtr p1;
+    int indent;
+{
+    WindowPtr p2;
+    int i;
+
+    while (p1)
+    {
+	p2 = p1->firstChild;
+	for (i=0; i<indent; i++) ErrorF( " ");
+	ErrorF( "%x\n", p1->drawable.id);
+	miPrintRegion(&p1->clipList);
+	PrintChildren(p2, indent+4);
+	p1 = p1->nextSib;
+    }
+}
+
+PrintWindowTree()
+{
+    int i;
+    WindowPtr pWin, p1;
+
+    for (i=0; i<screenInfo.numScreens; i++)
+    {
+	ErrorF( "WINDOW %d\n", i);
+	pWin = WindowTable[i];
+	miPrintRegion(&pWin->clipList);
+	p1 = pWin->firstChild;
+	PrintChildren(p1, 4);
+    }
+}
+#endif
+
+int
+TraverseTree(pWin, func, data)
+    register WindowPtr pWin;
+    VisitWindowProcPtr func;
+    pointer data;
+{
+    register int result;
+    register WindowPtr pChild;
+
+    if (!(pChild = pWin))
+       return(WT_NOMATCH);
+    while (1)
+    {
+	result = (* func)(pChild, data);
+	if (result == WT_STOPWALKING)
+	    return(WT_STOPWALKING);
+	if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+    return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
+ *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
+ *   exit WalkTree.  Does depth-first traverse.
+ *****/
+
+int
+WalkTree(pScreen, func, data)
+    ScreenPtr pScreen;
+    VisitWindowProcPtr func;
+    pointer data;
+{
+    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int	defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool	disableBackingStore = FALSE;
+Bool	enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool	disableSaveUnders = FALSE;
+
+static void
+#if NeedFunctionPrototypes
+SetWindowToDefaults(register WindowPtr pWin)
+#else
+SetWindowToDefaults(pWin)
+    register WindowPtr pWin;
+#endif
+{
+    pWin->prevSib = NullWindow;
+    pWin->firstChild = NullWindow;
+    pWin->lastChild = NullWindow;
+
+    pWin->valdata = (ValidatePtr)NULL;
+    pWin->optional = (WindowOptPtr)NULL;
+    pWin->cursorIsNone = TRUE;
+
+    pWin->backingStore = NotUseful;
+    pWin->DIXsaveUnder = FALSE;
+    pWin->backStorage = (pointer) NULL;
+
+    pWin->mapped = FALSE;	    /* off */
+    pWin->realized = FALSE;	/* off */
+    pWin->viewable = FALSE;
+    pWin->visibility = VisibilityNotViewable;
+    pWin->overrideRedirect = FALSE;
+    pWin->saveUnder = FALSE;
+
+    pWin->bitGravity = ForgetGravity;
+    pWin->winGravity = NorthWestGravity;
+
+    pWin->eventMask = 0;
+    pWin->deliverableEvents = 0;
+    pWin->dontPropagate = 0;
+    pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+    pWin->srcBuffer = DBE_FRONT_BUFFER;
+    pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+}
+
+void nxagentClearSplash(WindowPtr pW)
+{
+    int w, h;
+    ScreenPtr pScreen;
+
+    w = pW->drawable.width;
+    h = pW->drawable.height;
+
+    pScreen = pW->drawable.pScreen;
+
+    if (pW->backgroundState == BackgroundPixmap)
+    {
+      (*pScreen->DestroyPixmap)(pW->background.pixmap);
+    }
+
+    pW->backgroundState = BackgroundPixel;
+    pW->background.pixel = nxagentLogoBlack;
+
+    (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
+
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+    WindowPtr pWin;
+#endif
+{
+    nxagentRootTileWindow = pWin;
+}
+
+WindowPtr
+AllocateWindow(pScreen)
+    ScreenPtr pScreen;
+{
+    WindowPtr pWin;
+    register char *ptr;
+    register DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+    if (pWin)
+    {
+	ppriv = (DevUnion *)(pWin + 1);
+	pWin->devPrivates = ppriv;
+	sizes = pScreen->WindowPrivateSizes;
+	ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+	for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+	{
+	    if ( (size = *sizes) )
+	    {
+		ppriv->ptr = (pointer)ptr;
+		ptr += size;
+	    }
+	    else
+		ppriv->ptr = (pointer)NULL;
+	}
+    }
+    return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ *    Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(pScreen)
+    ScreenPtr	pScreen;
+{
+    WindowPtr	pWin;
+    BoxRec	box;
+    PixmapFormatRec *format;
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+	return FALSE;
+
+    savedScreenInfo[pScreen->myNum].pWindow = NULL;
+    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+    screenIsSaved = SCREEN_SAVER_OFF;
+
+    WindowTable[pScreen->myNum] = pWin;
+
+    pWin->drawable.pScreen = pScreen;
+    pWin->drawable.type = DRAWABLE_WINDOW;
+
+    pWin->drawable.depth = pScreen->rootDepth;
+    for (format = screenInfo.formats;
+	 format->depth != pScreen->rootDepth;
+	 format++)
+	;
+    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->parent = NullWindow;
+    SetWindowToDefaults(pWin);
+
+    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+    if (!pWin->optional)
+        return FALSE;
+
+    pWin->optional->dontPropagateMask = 0;
+    pWin->optional->otherEventMasks = 0;
+    pWin->optional->otherClients = NULL;
+    pWin->optional->passiveGrabs = NULL;
+    pWin->optional->userProps = NULL;
+    pWin->optional->backingBitPlanes = ~0L;
+    pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+    pWin->optional->boundingShape = NULL;
+    pWin->optional->clipShape = NULL;
+#endif
+#ifdef XINPUT
+    pWin->optional->inputMasks = NULL;
+#endif
+    pWin->optional->colormap = pScreen->defColormap;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->nextSib = NullWindow;
+
+    pWin->drawable.id = FakeClientID(0);
+
+    pWin->origin.x = pWin->origin.y = 0;
+    pWin->drawable.height = pScreen->height;
+    pWin->drawable.width = pScreen->width;
+    pWin->drawable.x = pWin->drawable.y = 0;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+    pWin->drawable.class = InputOutput;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->backgroundState = BackgroundPixel;
+    pWin->background.pixel = pScreen->whitePixel;
+
+    pWin->borderIsPixel = TRUE;
+    pWin->border.pixel = pScreen->blackPixel;
+    pWin->borderWidth = 0;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+	return FALSE;
+
+    if (disableBackingStore)
+    {
+      pScreen -> backingStoreSupport = NotUseful;
+    }
+
+    if (enableBackingStore)
+    {
+      pScreen -> backingStoreSupport = Always;
+    }
+
+    pScreen->saveUnderSupport = False;
+
+#ifdef DO_SAVE_UNDERS
+    if ((pScreen->backingStoreSupport != NotUseful) &&
+	(pScreen->saveUnderSupport == NotUseful))
+    {
+	/*
+	 * If the screen has backing-store but no save-unders, let the
+	 * clients know we can support save-unders using backing-store.
+	 */
+	pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+    }
+#endif /* DO_SAVE_UNDERS */
+		
+    if (disableSaveUnders)
+	pScreen->saveUnderSupport = NotUseful;
+
+    return TRUE;
+}
+
+void
+InitRootWindow(pWin)
+    WindowPtr pWin;
+{
+    ScreenPtr pScreen;
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (nxagentOption(Rootless))
+    {
+      #ifdef TEST
+      fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
+                  (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+      #endif
+
+      nxagentRootlessWindow = pWin;
+    }
+
+    pScreen = pWin->drawable.pScreen;
+
+    /*
+     * A root window is created for each screen by main
+     * and the pointer is saved in WindowTable as in the
+     * following snippet:
+     *
+     * for (i = 0; i < screenInfo.numScreens; i++)
+     *          InitRootWindow(WindowTable[i]);
+     *
+     * Our root window on the real display was already
+     * created at the time the screen was opened, so it
+     * is unclear how this window (or the other window,
+     * if you prefer) fits in the big picture.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+
+    #ifdef NXAGENT_SPLASH
+    /* We SHOULD check for an error value here XXX */
+    pWin -> background.pixel = pScreen -> blackPixel;
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
+    #else
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+    #endif
+
+    MakeRootTile(pWin);
+
+    /*
+     * Map both the root and the default agent window.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
+    #endif
+
+    nxagentInitAtoms(pWin);
+
+    nxagentInitClipboard(pWin);
+
+    nxagentMapDefaultWindows();
+
+    nxagentRedirectDefaultWindows();
+
+    #ifdef NXAGENT_ARTSD
+    {
+      char artsd_port[10];
+      int nPort;
+      extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+      nPort = atoi(display) + 7000;
+      sprintf(artsd_port,"%d", nPort);
+      nxagentPropagateArtsdProperties(pScreen, artsd_port);
+    }
+    #endif
+}
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize.  The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(pWin, Rgn, x, y, w, h)
+    register WindowPtr pWin;
+    RegionPtr Rgn;
+    register int x, y;
+    int w, h;
+{
+    REGION_PTR(pScreen, pWin)
+    BoxRec box;
+
+    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+    /* we do these calculations to avoid overflows */
+    if (x > box.x1)
+	box.x1 = x;
+    if (y > box.y1)
+	box.y1 = y;
+    x += w;
+    if (x < box.x2)
+	box.x2 = x;
+    y += h;
+    if (y < box.y2)
+	box.y2 = y;
+    if (box.x1 > box.x2)
+	box.x2 = box.x1;
+    if (box.y1 > box.y2)
+	box.y2 = box.y1;
+    REGION_RESET(pScreen, Rgn, &box);
+    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(pWin)
+    register WindowPtr pWin;
+{
+    if (!pWin->parent &&
+	(screenIsSaved == SCREEN_SAVER_ON) &&
+	(HasSaverWindow (pWin->drawable.pScreen->myNum)))
+	return (pWin->firstChild);
+    else
+	return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ *    Makes a window in response to client request 
+ *****/
+
+WindowPtr
+CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist,
+	     depth, client, visual, error)
+    Window wid;
+    register WindowPtr pParent;
+    int x,y;
+    unsigned int w, h, bw;
+    unsigned int class;
+    register Mask vmask;
+    XID *vlist;
+    int depth;
+    ClientPtr client;
+    VisualID visual;
+    int *error;
+{
+    register WindowPtr pWin;
+    WindowPtr pHead;
+    register ScreenPtr pScreen;
+    xEvent event;
+    int idepth, ivisual;
+    Bool fOK;
+    DepthPtr pDepth;
+    PixmapFormatRec *format;
+    register WindowOptPtr ancwopt;
+
+    if (class == CopyFromParent)
+	class = pParent->drawable.class;
+
+    if ((class != InputOutput) && (class != InputOnly))
+    {
+	*error = BadValue;
+	client->errorValue = class;
+	return NullWindow;
+    }
+
+    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pScreen = pParent->drawable.pScreen;
+    if ((class == InputOutput) && (depth == 0))
+	 depth = pParent->drawable.depth;
+    ancwopt = pParent->optional;
+    if (!ancwopt)
+	ancwopt = FindWindowWithOptional(pParent)->optional;
+    if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+	VisualID ag_visual;
+
+	if (client->appgroup && !pParent->parent &&
+	    (ag_visual = XagRootVisual (client)))
+	    visual = ag_visual;
+	else
+#endif
+	visual = ancwopt->visual;
+    }
+
+    /* Find out if the depth and visual are acceptable for this Screen */
+    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+    {
+	fOK = FALSE;
+	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+	{
+	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+	    if ((depth == pDepth->depth) || (depth == 0))
+	    {
+		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+		{
+		    if (visual == pDepth->vids[ivisual])
+		    {
+			fOK = TRUE;
+			break;
+		    }
+		}
+	    }
+	}
+	if (fOK == FALSE)
+	{
+	    *error = BadMatch;
+	    return NullWindow;
+	}
+    }
+
+    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+	(class != InputOnly) &&
+	(depth != pParent->drawable.depth))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if (((vmask & CWColormap) == 0) &&
+	(class != InputOnly) &&
+	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+    {
+	*error = BadAlloc;
+	return NullWindow;
+    }
+    pWin->drawable = pParent->drawable;
+    pWin->drawable.depth = depth;
+    if (depth == pParent->drawable.depth)
+	pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+    else
+    {
+	for (format = screenInfo.formats; format->depth != depth; format++)
+	    ;
+	pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+    }
+    if (class == InputOnly)
+	pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->drawable.id = wid;
+    pWin->drawable.class = class;
+
+    pWin->parent = pParent;
+    SetWindowToDefaults(pWin);
+
+    if (visual != ancwopt->visual)
+    {
+	if (!MakeWindowOptional (pWin))
+	{
+	    xfree (pWin);
+	    *error = BadAlloc;
+	    return NullWindow;
+	}
+	pWin->optional->visual = visual;
+	pWin->optional->colormap = None;
+    }
+
+    pWin->borderWidth = bw;
+#ifdef XCSECURITY
+    /*  can't let untrusted clients have background None windows;
+     *  they make it too easy to steal window contents
+     */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	pWin->backgroundState = BackgroundPixel;
+	pWin->background.pixel = 0;
+    }
+    else
+#endif
+    pWin->backgroundState = None;
+
+    pWin->borderIsPixel = pParent->borderIsPixel;
+    pWin->border = pParent->border;
+    if (pWin->borderIsPixel == FALSE)
+	pWin->border.pixmap->refcnt++;
+		
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    pWin->drawable.width = w;
+    pWin->drawable.height = h;
+    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+	/* set up clip list correctly for unobscured WindowPtr */
+    REGION_INIT(pScreen, &pWin->clipList, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->winSize, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, NullBox, 1);
+
+    pHead = RealChildHead(pParent);
+    if (pHead)
+    {
+	pWin->nextSib = pHead->nextSib;
+	if (pHead->nextSib)
+	    pHead->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pHead->nextSib = pWin;
+	pWin->prevSib = pHead;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    /* We SHOULD check for an error value here XXX */
+    if (!(*pScreen->CreateWindow)(pWin))
+    {
+	*error = BadAlloc;
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    if (!(vmask & CWEventMask))
+	RecalculateDeliverableEvents(pWin);
+
+    if (vmask)
+	*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+    else
+	*error = Success;
+
+    if (*error != Success)
+    {
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+    {
+	XID value = defaultBackingStore;
+	(void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+	pWin->forcedBS = TRUE;
+    }
+
+    if (SubSend(pParent))
+    {
+	event.u.u.type = CreateNotify;
+	event.u.createNotify.window = wid;
+	event.u.createNotify.parent = pParent->drawable.id;
+	event.u.createNotify.x = x;
+	event.u.createNotify.y = y;
+	event.u.createNotify.width = w;
+	event.u.createNotify.height = h;
+	event.u.createNotify.borderWidth = bw;
+	event.u.createNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pParent, &event, 1, NullWindow);		
+    }
+    return pWin;
+}
+
+static void
+#if NeedFunctionPrototypes
+FreeWindowResources(register WindowPtr pWin)
+#else
+FreeWindowResources(pWin)
+    register WindowPtr pWin;
+#endif
+{
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DeleteWindowFromAnySaveSet(pWin);
+    DeleteWindowFromAnySelections(pWin);
+    DeleteWindowFromAnyEvents(pWin, TRUE);
+    REGION_UNINIT(pScreen, &pWin->clipList);
+    REGION_UNINIT(pScreen, &pWin->winSize);
+    REGION_UNINIT(pScreen, &pWin->borderClip);
+    REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+    if (wBoundingShape (pWin))
+	REGION_DESTROY(pScreen, wBoundingShape (pWin));
+    if (wClipShape (pWin))
+	REGION_DESTROY(pScreen, wClipShape (pWin));
+#endif
+    if (pWin->borderIsPixel == FALSE)
+	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+    if (pWin->backgroundState == BackgroundPixmap)
+	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+    DeleteAllWindowProperties(pWin);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->DestroyWindow)(pWin);
+    DisposeWindowOptional (pWin);
+}
+
+static void
+#if NeedFunctionPrototypes
+CrushTree(WindowPtr pWin)
+#else
+CrushTree(pWin)
+    WindowPtr pWin;
+#endif
+{
+    register WindowPtr pChild, pSib, pParent;
+    UnrealizeWindowProcPtr UnrealizeWindow;
+    xEvent event;
+
+    if (!(pChild = pWin->firstChild))
+	return;
+    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+    while (1)
+    {
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (1)
+	{
+	    pParent = pChild->parent;
+	    if (SubStrSend(pChild, pParent))
+	    {
+		event.u.u.type = DestroyNotify;
+		event.u.destroyNotify.window = pChild->drawable.id;
+		DeliverEvents(pChild, &event, 1, NullWindow);		
+	    }
+	    FreeResource(pChild->drawable.id, RT_WINDOW);
+	    pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder && pChild->viewable)
+		deltaSaveUndersViewable--;
+#endif
+	    pChild->viewable = FALSE;
+	    if (pChild->realized)
+	    {
+		pChild->realized = FALSE;
+		(*UnrealizeWindow)(pChild);
+	    }
+	    FreeWindowResources(pChild);
+	    xfree(pChild);
+	    if ( (pChild = pSib) )
+		break;
+	    pChild = pParent;
+	    pChild->firstChild = NullWindow;
+	    pChild->lastChild = NullWindow;
+	    if (pChild == pWin)
+		return;
+	}
+    }
+}
+	
+/*****
+ *  DeleteWindow
+ *	 Deletes child of window then window itself
+ *	 If wid is None, don't send any events
+ *****/
+
+/*ARGSUSED*/
+int
+DeleteWindow(value, wid)
+    pointer value;
+    XID wid;
+ {
+    register WindowPtr pParent;
+    register WindowPtr pWin = (WindowPtr)value;
+    xEvent event;
+
+    UnmapWindow(pWin, FALSE);
+
+    CrushTree(pWin);
+
+    pParent = pWin->parent;
+    if (wid && pParent && SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = DestroyNotify;
+	event.u.destroyNotify.window = pWin->drawable.id;
+	DeliverEvents(pWin, &event, 1, NullWindow);		
+    }
+
+    FreeWindowResources(pWin);
+    if (pParent)
+    {
+	if (pParent->firstChild == pWin)
+	    pParent->firstChild = pWin->nextSib;
+	if (pParent->lastChild == pWin)
+	    pParent->lastChild = pWin->prevSib;
+	if (pWin->nextSib)
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	if (pWin->prevSib)
+	    pWin->prevSib->nextSib = pWin->nextSib;
+    }
+    xfree(pWin);
+
+    if (pWin -> optional &&
+            pWin -> optional -> colormap &&
+                pWin -> parent)
+    {
+      nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+    }
+
+    return Success;
+}
+
+/*ARGSUSED*/
+void
+DestroySubwindows(pWin, client)
+    register WindowPtr pWin;
+    ClientPtr client;
+{
+    /* XXX
+     * The protocol is quite clear that each window should be
+     * destroyed in turn, however, unmapping all of the first
+     * eliminates most of the calls to ValidateTree.  So,
+     * this implementation is incorrect in that all of the
+     * UnmapNotifies occur before all of the DestroyNotifies.
+     * If you care, simply delete the call to UnmapSubwindows.
+     */
+    UnmapSubwindows(pWin);
+    while (pWin->lastChild)
+	FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+    ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ *  ChangeWindowAttributes
+ *   
+ *  The value-mask specifies which attributes are to be changed; the
+ *  value-list contains one value for each one bit in the mask, from least
+ *  to most significant bit in the mask.  
+ *****/
+ 
+int
+ChangeWindowAttributes(pWin, vmask, vlist, client)
+    register WindowPtr pWin;
+    Mask vmask;
+    XID *vlist;
+    ClientPtr client;
+{
+    register Mask index2;
+    register XID *pVlist;
+    PixmapPtr pPixmap;
+    Pixmap pixID;
+    CursorPtr pCursor, pOldCursor;
+    Cursor cursorID;
+    WindowPtr pChild;
+    Colormap cmap;
+    ColormapPtr	pCmap;
+    xEvent xE;
+    int result;
+    register ScreenPtr pScreen;
+    Mask vmaskCopy = 0;
+    register Mask tmask;
+    unsigned int val;
+    int error;
+    Bool checkOptional = FALSE;
+    Bool borderRelative = FALSE;
+    WindowPtr pLayerWin;
+
+    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+	return BadMatch;
+
+    error = Success;
+    pScreen = pWin->drawable.pScreen;
+    pVlist = vlist;
+    tmask = vmask;
+    while (tmask)
+    {
+	index2 = (Mask) lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBackPixmap:
+	    pixID = (Pixmap )*pVlist;
+	    pVlist++;
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pixID == None)
+	    {
+#ifdef XCSECURITY
+		/*  can't let untrusted clients have background None windows */
+		if (client->trustLevel == XSecurityClientTrusted)
+		{
+#endif
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = None;
+#ifdef XCSECURITY
+		}
+		else
+		{ /* didn't change the background to None, so don't tell ddx */
+		    index2 = 0; 
+		}
+#endif
+	    }
+	    else if (pixID == ParentRelative)
+	    {
+		if (pWin->parent &&
+		    pWin->drawable.depth != pWin->parent->drawable.depth)
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = ParentRelative;
+		borderRelative = TRUE;
+		/* Note that the parent's backgroundTile's refcnt is NOT
+		 * incremented. */
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+						RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap != (PixmapPtr) NULL)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->backgroundState == BackgroundPixmap)
+			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    pWin->backgroundState = BackgroundPixmap;
+		    pWin->background.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBackPixel:
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pWin->backgroundState == BackgroundPixmap)
+		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+	    pWin->backgroundState = BackgroundPixel;
+	    pWin->background.pixel = (CARD32 ) *pVlist;
+		   /* background pixel overrides background pixmap,
+		      so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBackPixmap;
+	    pVlist++;
+	    break;
+	  case CWBorderPixmap:
+	    pixID = (Pixmap ) *pVlist;
+	    pVlist++;
+	    if (pixID == CopyFromParent)
+	    {
+		if (!pWin->parent ||
+		    (pWin->drawable.depth != pWin->parent->drawable.depth))
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->borderIsPixel == FALSE)
+		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		pWin->border = pWin->parent->border;
+		if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+		{
+		    index2 = CWBorderPixel;
+		}
+		else
+		{
+		    pWin->parent->border.pixmap->refcnt++;
+		}
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+					RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->borderIsPixel == FALSE)
+			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		    pWin->borderIsPixel = FALSE;
+		    pWin->border.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBorderPixel:
+	    if (pWin->borderIsPixel == FALSE)
+		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+	    pWin->borderIsPixel = TRUE;
+	    pWin->border.pixel = (CARD32) *pVlist;
+		    /* border pixel overrides border pixmap,
+		       so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBorderPixmap;
+	    pVlist++;
+	    break;
+	  case CWBitGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->bitGravity = val;
+	    break;
+	  case CWWinGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->winGravity = val;
+	    break;
+	  case CWBackingStore:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->backingStore = val;
+
+            #ifdef TEST
+            fprintf(stderr, "ChangeWindowAttributes: Changed backing store value to %d for window at %p.\n",
+                        val, (void*)pWin);
+            #endif
+
+	    pWin->forcedBS = FALSE;
+	    break;
+	  case CWBackingPlanes:
+	    if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+		if ((CARD32)*pVlist == (CARD32)~0L)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWBackingPixel:
+	    if (pWin->optional || (CARD32) *pVlist) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingPixel = (CARD32) *pVlist;
+		if (!*pVlist)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWSaveUnder:
+	    val = (BOOL) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+		DO_SAVE_UNDERS(pWin))
+	    {
+		/*
+		 * Re-check all siblings and inferiors for obscurity or
+		 * exposition (hee hee).
+		 */
+		if (pWin->saveUnder)
+		    deltaSaveUndersViewable--;
+		else
+		    deltaSaveUndersViewable++;
+		pWin->saveUnder = val;
+
+		if (pWin->firstChild)
+		{
+                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+                                                       pWin->nextSib);
+               }
+               else
+               {
+                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pWin,
+                                                       pWin->nextSib);
+               }                                   
+	    }
+	    else
+	    {
+		/*  If we're changing the saveUnder attribute of the root 
+		 *  window, all we do is set pWin->saveUnder so that
+		 *  GetWindowAttributes returns the right value.  We don't
+		 *  do the "normal" save-under processing (as above).
+		 *  Hope that doesn't cause any problems.
+		 */
+		pWin->saveUnder = val;
+	    }
+#else
+	    pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+	    break;
+	  case CWEventMask:
+            /*
+             * TODO: Some applications like java bean shell
+             * don' t work if they cannot monitor the root
+             * window for Structure Redirect events. However
+             * this doesn't seem to be the best solution, since
+             * also an X server with a window manager running,
+             * doesn't allow to monitor for those events, but
+             * the java bean shell works flawlessy on this
+             * server.
+             *
+             * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
+             * {
+             *   return BadAccess;
+             * }
+             */
+
+	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWDontPropagate:
+	    result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+					    &checkOptional);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWOverrideRedirect:
+	    val = (BOOL ) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->overrideRedirect = val;
+	    break;
+	  case CWColormap:
+	    cmap = (Colormap) *pVlist;
+	    pVlist++;
+	    if (cmap == CopyFromParent)
+	    {
+#ifdef XAPPGROUP
+		Colormap ag_colormap;
+		ClientPtr win_owner;
+
+		/*
+		 * win_owner == client for CreateWindow, other clients
+		 * can ChangeWindowAttributes
+		 */
+		win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+		if ( win_owner && win_owner->appgroup &&
+		    !pWin->parent->parent &&
+		    (ag_colormap = XagDefaultColormap (win_owner)))
+		    cmap = ag_colormap;
+		else
+#endif
+		if (pWin->parent &&
+		    (!pWin->optional ||
+		     pWin->optional->visual == wVisual (pWin->parent)))
+		{
+		    cmap = wColormap (pWin->parent);
+		}
+		else
+		    cmap = None;
+	    }
+	    if (cmap == None)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+					      RT_COLORMAP, SecurityReadAccess);
+	    if (!pCmap)
+	    {
+		error = BadColor;
+		client->errorValue = cmap;
+		goto PatchUp;
+	    }
+	    if (pCmap->pVisual->vid != wVisual (pWin) ||
+		pCmap->pScreen != pScreen)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    if (cmap != wColormap (pWin))
+	    {
+		if (!pWin->optional)
+		{
+		    if (!MakeWindowOptional (pWin))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+		else if (pWin->parent && cmap == wColormap (pWin->parent))
+		    checkOptional = TRUE;
+
+		/*
+		 * propagate the original colormap to any children
+		 * inheriting it
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pWin->optional->colormap = cmap;
+
+		/*
+		 * check on any children now matching the new colormap
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (pChild->optional->colormap == cmap)
+			CheckWindowOptionalNeed (pChild);
+		}
+	
+		xE.u.u.type = ColormapNotify;
+		xE.u.colormap.window = pWin->drawable.id;
+		xE.u.colormap.colormap = cmap;
+		xE.u.colormap.new = xTrue;
+		xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+		DeliverEvents(pWin, &xE, 1, NullWindow);
+	    }
+	    break;
+	  case CWCursor:
+	    cursorID = (Cursor ) *pVlist;
+	    pVlist++;
+	    /*
+	     * install the new
+	     */
+	    if ( cursorID == None)
+	    {
+		if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+		    pCursor = rootCursor;
+		else
+		    pCursor = (CursorPtr) None;
+	    }
+	    else
+	    {
+		pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+						RT_CURSOR, SecurityReadAccess);
+		if (!pCursor)
+		{
+		    error = BadCursor;
+		    client->errorValue = cursorID;
+		    goto PatchUp;
+		}
+	    }
+
+	    if (pCursor != wCursor (pWin))
+	    {
+		/*
+		 * patch up child windows so they don't lose cursors.
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !pChild->cursorIsNone &&
+			!MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pOldCursor = 0;
+		if (pCursor == (CursorPtr) None)
+		{
+		    pWin->cursorIsNone = TRUE;
+		    if (pWin->optional)
+		    {
+			pOldCursor = pWin->optional->cursor;
+			pWin->optional->cursor = (CursorPtr) None;
+			checkOptional = TRUE;
+		    }
+		} else {
+		    if (!pWin->optional)
+		    {
+			if (!MakeWindowOptional (pWin))
+			{
+			    error = BadAlloc;
+			    goto PatchUp;
+			}
+		    }
+		    else if (pWin->parent && pCursor == wCursor (pWin->parent))
+			checkOptional = TRUE;
+		    pOldCursor = pWin->optional->cursor;
+		    pWin->optional->cursor = pCursor;
+		    pCursor->refcnt++;
+		    pWin->cursorIsNone = FALSE;
+		    /*
+		     * check on any children now matching the new cursor
+		     */
+
+		    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+		    {
+			if (pChild->optional &&
+			    (pChild->optional->cursor == pCursor))
+			    CheckWindowOptionalNeed (pChild);
+		    }
+		}
+
+		if (pWin->realized)
+		    WindowHasNewCursor( pWin);
+
+		/* Can't free cursor until here - old cursor
+		 * is needed in WindowHasNewCursor
+		 */
+		if (pOldCursor)
+		    FreeCursor (pOldCursor, (Cursor)0);
+	    }
+	    break;
+	 default:
+	    error = BadValue;
+	    client->errorValue = vmask;
+	    goto PatchUp;
+      }
+      vmaskCopy |= index2;
+    }
+PatchUp:
+    if (checkOptional)
+	CheckWindowOptionalNeed (pWin);
+
+	/* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+    /* 
+	If the border contents have changed, redraw the border. 
+	Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+	for the tile to be rotated, and the correct function selected.
+    */
+    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+	&& pWin->viewable && HasBorder (pWin))
+    {
+	RegionRec exposed;
+
+	REGION_INIT(pScreen, &exposed, NullBox, 0);
+	REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+	(*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+	REGION_UNINIT(pScreen, &exposed);
+    }
+    return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ *    Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(pWin, client, wa)
+    register WindowPtr pWin;
+    ClientPtr client;
+    xGetWindowAttributesReply *wa;
+{
+    wa->type = X_Reply;
+    wa->bitGravity = pWin->bitGravity;
+    wa->winGravity = pWin->winGravity;
+    if (pWin->forcedBS && pWin->backingStore != Always)
+	wa->backingStore = NotUseful;
+    else
+	wa->backingStore = pWin->backingStore;
+    wa->length = (sizeof(xGetWindowAttributesReply) -
+		 sizeof(xGenericReply)) >> 2;
+    wa->sequenceNumber = client->sequence;
+    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
+    wa->backingPixel =  wBackingPixel (pWin);
+    wa->saveUnder = (BOOL)pWin->saveUnder;
+    wa->override = pWin->overrideRedirect;
+    if (!pWin->mapped)
+	wa->mapState = IsUnmapped;
+    else if (pWin->realized)
+	wa->mapState = IsViewable;
+    else
+	wa->mapState = IsUnviewable;
+
+    wa->colormap =  wColormap (pWin);
+    wa->mapInstalled = (wa->colormap == None) ? xFalse
+				: IsMapInstalled(wa->colormap, pWin);
+
+    wa->yourEventMask = EventMaskForClient(pWin, client);
+    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+    wa->doNotPropagateMask = wDontPropagateMask (pWin);
+    wa->class = pWin->drawable.class;
+    wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(pWin, pNextSib)
+    register WindowPtr pWin, pNextSib;
+{
+    register WindowPtr pParent = pWin->parent;
+    WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+    if (pWin->nextSib != pNextSib)
+    {
+	WindowPtr pOldNextSib = pWin->nextSib;
+
+	if (!pNextSib)	      /* move to bottom */
+	{
+	    if (pParent->firstChild == pWin)
+		pParent->firstChild = pWin->nextSib;
+	    /* if (pWin->nextSib) */	 /* is always True: pNextSib == NULL
+					  * and pWin->nextSib != pNextSib
+					  * therefore pWin->nextSib != NULL */
+	    pFirstChange = pWin->nextSib;
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pParent->lastChild->nextSib = pWin;
+	    pWin->prevSib = pParent->lastChild;
+	    pWin->nextSib = NullWindow;
+	    pParent->lastChild = pWin;
+	}
+	else if (pParent->firstChild == pNextSib) /* move to top */
+	{
+	    pFirstChange = pWin;
+	    if (pParent->lastChild == pWin)
+	       pParent->lastChild = pWin->prevSib;
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pParent->firstChild;
+	    pWin->prevSib = (WindowPtr ) NULL;
+	    pNextSib->prevSib = pWin;
+	    pParent->firstChild = pWin;
+	}
+	else			/* move in middle of list */
+	{
+	    WindowPtr pOldNext = pWin->nextSib;
+
+	    pFirstChange = NullWindow;
+	    if (pParent->firstChild == pWin)
+		pFirstChange = pParent->firstChild = pWin->nextSib;
+	    if (pParent->lastChild == pWin) {
+	       pFirstChange = pWin;
+	       pParent->lastChild = pWin->prevSib;
+	    }
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pNextSib;
+	    pWin->prevSib = pNextSib->prevSib;
+	    if (pNextSib->prevSib)
+		pNextSib->prevSib->nextSib = pWin;
+	    pNextSib->prevSib = pWin;
+	    if (!pFirstChange) {		     /* do we know it yet? */
+		pFirstChange = pParent->firstChild;  /* no, search from top */
+		while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+		     pFirstChange = pFirstChange->nextSib;
+	    }
+	}
+	if(pWin->drawable.pScreen->RestackWindow)
+	    (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+    }
+
+    return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (pWin)
+    register WindowPtr	 pWin;
+{
+    RegionPtr	pRgn;
+    BoxRec	box;
+
+    box.x1 = pWin->drawable.x;
+    box.y1 = pWin->drawable.y;
+    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	REGION_PTR(pScreen, pWin)
+
+	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+    }
+#endif
+    return pRgn;
+}
+
+void
+SetWinSize (pWin)
+    register WindowPtr pWin;
+{
+    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+			 pWin->drawable.x, pWin->drawable.y,
+			 (int)pWin->drawable.width,
+			 (int)pWin->drawable.height);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	REGION_PTR(pScreen, pWin)
+
+	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+			 pWin->drawable.y);
+    }
+#endif
+}
+
+void
+SetBorderSize (pWin)
+    register WindowPtr pWin;
+{
+    int	bw;
+
+    if (HasBorder (pWin)) {
+	bw = wBorderWidth (pWin);
+	ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+		pWin->drawable.x - bw, pWin->drawable.y - bw,
+		(int)(pWin->drawable.width + (bw<<1)),
+		(int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+	if (wBoundingShape (pWin)) {
+	    REGION_PTR(pScreen, pWin)
+
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+			     - pWin->drawable.y);
+	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+			     wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+			     pWin->drawable.y);
+	    REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+			 &pWin->winSize);
+	}
+#endif
+    } else {
+	REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+					       &pWin->winSize);
+    }
+}
+
+void
+GravityTranslate (x, y, oldx, oldy, dw, dh, gravity, destx, desty)
+    register int x, y;		/* new window position */
+    int		oldx, oldy;	/* old window position */
+    int		dw, dh;
+    unsigned	gravity;
+    register int *destx, *desty;	/* position relative to gravity */
+{
+    switch (gravity) {
+    case NorthGravity:
+	*destx = x + dw / 2;
+	*desty = y;
+	break;
+    case NorthEastGravity:
+	*destx = x + dw;
+	*desty = y;
+	break;
+    case WestGravity:
+	*destx = x;
+	*desty = y + dh / 2;
+	break;
+    case CenterGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh / 2;
+	break;
+    case EastGravity:
+	*destx = x + dw;
+	*desty = y + dh / 2;
+	break;
+    case SouthWestGravity:
+	*destx = x;
+	*desty = y + dh;
+	break;
+    case SouthGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh;
+	break;
+    case SouthEastGravity:
+	*destx = x + dw;
+	*desty = y + dh;
+	break;
+    case StaticGravity:
+	*destx = oldx;
+	*desty = oldy;
+	break;
+    default:
+	*destx = x;
+	*desty = y;
+	break;
+    }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(pWin, dx, dy, dw, dh)
+    register WindowPtr pWin;
+    int dx, dy, dw, dh;
+{
+    register ScreenPtr pScreen;
+    register WindowPtr pSib, pChild;
+    Bool resized = (dw || dh);
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+    {
+	if (resized && (pSib->winGravity > NorthWestGravity))
+	{
+	    int cwsx, cwsy;
+
+	    cwsx = pSib->origin.x;
+	    cwsy = pSib->origin.y;
+	    GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+			pSib->winGravity, &cwsx, &cwsy);
+	    if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+	    {
+		xEvent event;
+
+		event.u.u.type = GravityNotify;
+		event.u.gravity.window = pSib->drawable.id;
+		event.u.gravity.x = cwsx - wBorderWidth (pSib);
+		event.u.gravity.y = cwsy - wBorderWidth (pSib);
+		DeliverEvents (pSib, &event, 1, NullWindow);
+		pSib->origin.x = cwsx;
+		pSib->origin.y = cwsy;
+	    }
+	}
+	pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+	SetWinSize (pSib);
+	SetBorderSize (pSib);
+
+        /*
+         * Don't force X to move children. It will position them
+         * according with gravity.
+         *
+         * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+         */
+
+        /*
+         * Update pSib privates, as this window is moved by X.
+         */
+
+        nxagentAddConfiguredWindow(pSib, CW_Update);
+
+	if ( (pChild = pSib->firstChild) )
+	{
+	    while (1)
+	    {
+		pChild->drawable.x = pChild->parent->drawable.x +
+				     pChild->origin.x;
+		pChild->drawable.y = pChild->parent->drawable.y +
+				     pChild->origin.y;
+		SetWinSize (pChild);
+		SetBorderSize (pChild);
+
+                (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
+                                               pChild->drawable.y);
+
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+		while (!pChild->nextSib && (pChild != pSib))
+		    pChild = pChild->parent;
+		if (pChild == pSib)
+		    break;
+		pChild = pChild->nextSib;
+	    }
+	}
+    }
+}
+
+#define GET_INT16(m, f) \
+	if (m & mask) \
+	  { \
+	     f = (INT16) *pVlist;\
+	    pVlist++; \
+	 }
+#define GET_CARD16(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD16) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define GET_CARD8(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD8) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ *     returns Above if pSib above pMe in stack or Below otherwise 
+ */
+
+static int
+#if NeedFunctionPrototypes
+IsSiblingAboveMe(
+    register WindowPtr pMe,
+    register WindowPtr pSib)
+#else
+IsSiblingAboveMe(pMe, pSib)
+    register WindowPtr pMe, pSib;
+#endif
+{
+    register WindowPtr pWin;
+
+    pWin = pMe->parent->firstChild;
+    while (pWin)
+    {
+	if (pWin == pSib)
+	    return(Above);
+	else if (pWin == pMe)
+	    return(Below);
+	pWin = pWin->nextSib;
+    }
+    return(Below);
+}
+
+static BoxPtr
+#if NeedFunctionPrototypes
+WindowExtents(
+    register WindowPtr pWin,
+    register BoxPtr pBox)
+#else
+WindowExtents(pWin, pBox)
+    register WindowPtr pWin;
+    register BoxPtr pBox;
+#endif
+{
+    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+	       + wBorderWidth (pWin);
+    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+	       + wBorderWidth (pWin);
+    return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin)	(wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+#if NeedFunctionPrototypes
+MakeBoundingRegion (
+    register WindowPtr	pWin,
+    BoxPtr	pBox)
+#else
+MakeBoundingRegion (pWin, pBox)
+    register WindowPtr	pWin;
+    BoxPtr	pBox;
+#endif
+{
+    RegionPtr	pRgn;
+    REGION_PTR(pScreen, pWin)
+
+    pRgn = REGION_CREATE(pScreen, pBox, 1);
+    if (wBoundingShape (pWin)) {
+	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+						  -pWin->origin.y);
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+						  pWin->origin.y);
+    }
+    return pRgn;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+ShapeOverlap (
+    WindowPtr	pWin,
+    BoxPtr	pWinBox,
+    WindowPtr	pSib,
+    BoxPtr	pSibBox)
+#else
+ShapeOverlap (pWin, pWinBox, pSib, pSibBox)
+    WindowPtr	pWin, pSib;
+    BoxPtr	pWinBox, pSibBox;
+#endif
+{
+    RegionPtr	pWinRgn, pSibRgn;
+    register ScreenPtr	pScreen;
+    Bool	ret;
+
+    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+	return TRUE;
+    pScreen = pWin->drawable.pScreen;
+    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pSibRgn);
+    return ret;
+}
+#endif
+
+static Bool
+#if NeedFunctionPrototypes
+AnyWindowOverlapsMe(
+    WindowPtr pWin,
+    WindowPtr pHead,
+    register BoxPtr box)
+#else
+AnyWindowOverlapsMe(pWin, pHead, box)
+    WindowPtr pWin, pHead;
+    register BoxPtr box;
+#endif
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+static Bool
+#if NeedFunctionPrototypes
+IOverlapAnyWindow(
+    WindowPtr pWin,
+    register BoxPtr box)
+#else
+IOverlapAnyWindow(pWin, box)
+    WindowPtr pWin;
+    register BoxPtr box;
+#endif
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+/*
+ *   WhereDoIGoInTheStack() 
+ *	  Given pWin and pSib and the relationshipe smode, return
+ *	  the window that pWin should go ABOVE.
+ *	  If a pSib is specified:
+ *	      Above:  pWin is placed just above pSib
+ *	      Below:  pWin is placed just below pSib
+ *	      TopIf:  if pSib occludes pWin, then pWin is placed
+ *		      at the top of the stack
+ *	      BottomIf:	 if pWin occludes pSib, then pWin is 
+ *			 placed at the bottom of the stack
+ *	      Opposite: if pSib occludes pWin, then pWin is placed at the
+ *			top of the stack, else if pWin occludes pSib, then
+ *			pWin is placed at the bottom of the stack
+ *
+ *	  If pSib is NULL:
+ *	      Above:  pWin is placed at the top of the stack
+ *	      Below:  pWin is placed at the bottom of the stack
+ *	      TopIf:  if any sibling occludes pWin, then pWin is placed at
+ *		      the top of the stack
+ *	      BottomIf: if pWin occludes any sibline, then pWin is placed at
+ *			the bottom of the stack
+ *	      Opposite: if any sibling occludes pWin, then pWin is placed at
+ *			the top of the stack, else if pWin occludes any
+ *			sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+#if NeedFunctionPrototypes
+WhereDoIGoInTheStack(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    short x,
+    short y,
+    unsigned short w,
+    unsigned short h,
+    int smode)
+#else
+WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode)
+    register WindowPtr pWin, pSib;
+    short x, y;
+    unsigned short w, h;
+    int smode;
+#endif
+{
+    BoxRec box;
+    register ScreenPtr pScreen;
+    WindowPtr pHead, pFirst;
+
+    if ((pWin == pWin->parent->firstChild) &&
+	(pWin == pWin->parent->lastChild))
+	return((WindowPtr ) NULL);
+    pHead = RealChildHead(pWin->parent);
+    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+    pScreen = pWin->drawable.pScreen;
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + (int)w;
+    box.y2 = y + (int)h;
+    switch (smode)
+    {
+      case Above:
+	if (pSib)
+	   return(pSib);
+	else if (pWin == pFirst)
+	    return(pWin->nextSib);
+	else
+	    return(pFirst);
+      case Below:
+	if (pSib)
+	    if (pSib->nextSib != pWin)
+		return(pSib->nextSib);
+	    else
+		return(pWin->nextSib);
+	else
+	    return NullWindow;
+      case TopIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return(pFirst);
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	    return(pFirst);
+	else
+	    return(pWin->nextSib);
+      case BottomIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return NullWindow;
+	    else
+		return(pWin->nextSib);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return(pWin->nextSib);
+      case Opposite:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+	    {
+		if (IsSiblingAboveMe(pWin, pSib) == Above)
+		    return(pFirst);
+		else
+		    return NullWindow;
+	    }
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	{
+	    /* If I'm occluded, I can't possibly be the first child
+	     * if (pWin == pWin->parent->firstChild)
+	     *	  return pWin->nextSib;
+	     */
+	    return(pFirst);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return pWin->nextSib;
+      default:
+      {
+	ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+	return pWin->nextSib;
+      }
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+ReflectStackChange(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    VTKind  kind)
+#else
+ReflectStackChange(pWin, pSib, kind)
+    register WindowPtr pWin, pSib;
+    VTKind  kind;
+#endif
+{
+/* Note that pSib might be NULL */
+
+    Bool WasViewable = (Bool)pWin->viewable;
+    WindowPtr pParent;
+    Bool anyMarked;
+    WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    /* if this is a root window, can't be restacked */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						      &pLayerWin);
+	if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(pWin, mask, vlist, client)
+    register WindowPtr pWin;
+    register Mask mask;
+    XID *vlist;
+    ClientPtr client;
+{
+#define RESTACK_WIN    0
+#define MOVE_WIN       1
+#define RESIZE_WIN     2
+#define REBORDER_WIN   3
+    register WindowPtr pSib = NullWindow;
+    register WindowPtr pParent = pWin->parent;
+    Window sibwid = 0;
+    Mask index2, tmask;
+    register XID *pVlist;
+    short x,   y, beforeX, beforeY;
+    unsigned short w = pWin->drawable.width,
+		   h = pWin->drawable.height,
+		   bw = pWin->borderWidth;
+    int action, smode = Above;
+#ifdef XAPPGROUP
+    ClientPtr win_owner;
+    ClientPtr ag_leader = NULL;
+#endif
+    xEvent event;
+
+    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+	return(BadMatch);
+
+    if ((mask & CWSibling) && !(mask & CWStackMode))
+	return(BadMatch);
+
+    pVlist = vlist;
+
+    if (pParent)
+    {
+	x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+	y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+    }
+    else
+    {
+	x = pWin->drawable.x;
+	y = pWin->drawable.y;
+    }
+    beforeX = x;
+    beforeY = y;
+    action = RESTACK_WIN;	
+    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	action = MOVE_WIN;
+    }
+	/* or should be resized */
+    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	GET_CARD16(CWWidth, w);
+	GET_CARD16 (CWHeight, h);
+	if (!w || !h)
+	{
+	    client->errorValue = 0;
+	    return BadValue;
+	}
+	action = RESIZE_WIN;
+    }
+    tmask = mask & ~ChangeMask;
+    while (tmask)
+    {
+	index2 = (Mask)lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBorderWidth:
+	    GET_CARD16(CWBorderWidth, bw);
+	    break;
+	  case CWSibling:
+	    sibwid = (Window ) *pVlist;
+	    pVlist++;
+	    pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+						RT_WINDOW, SecurityReadAccess);
+	    if (!pSib)
+	    {
+		client->errorValue = sibwid;
+		return(BadWindow);
+	    }
+	    if (pSib->parent != pParent)
+		return(BadMatch);
+	    if (pSib == pWin)
+		return(BadMatch);
+	    break;
+	  case CWStackMode:
+	    GET_CARD8(CWStackMode, smode);
+	    if ((smode != TopIf) && (smode != BottomIf) &&
+		(smode != Opposite) && (smode != Above) && (smode != Below))
+	    {
+		client->errorValue = smode;
+		return(BadValue);
+	    }
+	    break;
+	  default:
+	    client->errorValue = mask;
+	    return(BadValue);
+	}
+    }
+	/* root really can't be reconfigured, so just return */
+    if (!pParent)
+	return Success;
+
+	/* Figure out if the window should be moved.  Doesnt
+	   make the changes to the window if event sent */
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+
+      fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
+                  pWin, mask, client);
+
+      fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
+                  "smode [%d] pSib [%p]\n",
+                      x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
+    }
+    #endif
+
+    if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
+            pWin -> overrideRedirect == 0 &&
+                nxagentScreenTrap == 0)
+    {
+      nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
+
+      return Success;
+    }
+
+    if (mask & CWStackMode)
+	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+				    pParent->drawable.y + y,
+				    w + (bw << 1), h + (bw << 1), smode);
+    else
+	pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+    ag_leader = XagLeader (win_owner);
+#endif
+
+    if ((!pWin->overrideRedirect) && 
+	(RedirectSend(pParent)
+#ifdef XAPPGROUP
+	|| (win_owner->appgroup && ag_leader && 
+	    XagIsControlledRoot (client, pParent))
+#endif
+	))
+    {
+	event.u.u.type = ConfigureRequest;
+	event.u.configureRequest.window = pWin->drawable.id;
+	if (mask & CWSibling)
+	   event.u.configureRequest.sibling = sibwid;
+	else
+	    event.u.configureRequest.sibling = None;
+	if (mask & CWStackMode)
+	   event.u.u.detail = smode;
+	else
+	    event.u.u.detail = Above;
+	event.u.configureRequest.x = x;
+	event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+            event.u.configureRequest.x += panoramiXdataPtr[0].x;
+            event.u.configureRequest.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureRequest.width = w;
+	event.u.configureRequest.height = h;
+	event.u.configureRequest.borderWidth = bw;
+	event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+	/* make sure if the ag_leader maps the window it goes to the wm */
+	if (ag_leader && ag_leader != client && 
+	    XagIsControlledRoot (client, pParent)) {
+	    event.u.configureRequest.parent = XagId (win_owner);
+	    (void) TryClientEvents (ag_leader, &event, 1,
+				    NoEventMask, NoEventMask, NullGrab);
+	    return Success;
+	}
+#endif
+	event.u.configureRequest.parent = pParent->drawable.id;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+    if (action == RESIZE_WIN)
+    {
+	Bool size_change = (w != pWin->drawable.width)
+			|| (h != pWin->drawable.height);
+	if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+	{
+	    xEvent eventT;
+	    eventT.u.u.type = ResizeRequest;
+	    eventT.u.resizeRequest.window = pWin->drawable.id;
+	    eventT.u.resizeRequest.width = w;
+	    eventT.u.resizeRequest.height = h;
+	    if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+				       ResizeRedirectMask, client) == 1)
+	    {
+		/* if event is delivered, leave the actual size alone. */
+		w = pWin->drawable.width;
+		h = pWin->drawable.height;
+		size_change = FALSE;
+	    }
+	}
+	if (!size_change)
+	{
+	    if (mask & (CWX | CWY))
+		action = MOVE_WIN;
+	    else if (mask & (CWStackMode | CWBorderWidth))
+		action = RESTACK_WIN;
+	    else   /* really nothing to do */
+		return(Success) ;
+	}
+    }
+
+    if (action == RESIZE_WIN)
+	    /* we've already checked whether there's really a size change */
+	    goto ActuallyDoSomething;
+    if ((mask & CWX) && (x != beforeX))
+	    goto ActuallyDoSomething;
+    if ((mask & CWY) && (y != beforeY))
+	    goto ActuallyDoSomething;
+    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+	    goto ActuallyDoSomething;
+    if (mask & CWStackMode)
+    {
+	if (pWin->nextSib != pSib)
+	    goto ActuallyDoSomething;
+    }
+    return(Success);
+
+ActuallyDoSomething:
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = ConfigureNotify;
+	event.u.configureNotify.window = pWin->drawable.id;
+	if (pSib)
+	    event.u.configureNotify.aboveSibling = pSib->drawable.id;
+	else
+	    event.u.configureNotify.aboveSibling = None;
+	event.u.configureNotify.x = x;
+	event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+	    event.u.configureNotify.x += panoramiXdataPtr[0].x;
+            event.u.configureNotify.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureNotify.width = w;
+	event.u.configureNotify.height = h;
+	event.u.configureNotify.borderWidth = bw;
+	event.u.configureNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (mask & CWBorderWidth)
+    {
+	if (action == RESTACK_WIN)
+	{
+	    action = MOVE_WIN;
+	    pWin->borderWidth = bw;
+	}
+	else if ((action == MOVE_WIN) &&
+		 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+		 (beforeY + wBorderWidth (pWin) == y + (int)bw))
+	{
+	    action = REBORDER_WIN;
+	    (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+	}
+	else
+	    pWin->borderWidth = bw;
+    }
+    if (action == MOVE_WIN)
+	(*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+		   (mask & CWBorderWidth) ? VTOther : VTMove);
+    else if (action == RESIZE_WIN)
+	(*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+    else if (mask & CWStackMode)
+	ReflectStackChange(pWin, pSib, VTOther);
+
+    if (action != RESTACK_WIN)
+	CheckCursorConfinement(pWin);
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ *    For RaiseLowest, raises the lowest mapped child (if any) that is
+ *    obscured by another child to the top of the stack.  For LowerHighest,
+ *    lowers the highest mapped child (if any) that is obscuring another
+ *    child to the bottom of the stack.	 Exposure processing is performed 
+ *
+ ******/
+
+int
+CirculateWindow(pParent, direction, client)
+    WindowPtr pParent;
+    int direction;
+    ClientPtr client;
+{
+    register WindowPtr pWin, pHead, pFirst;
+    xEvent event;
+    BoxRec box;
+
+    #ifdef TEST
+    fprintf(stderr, "CirculateWindow: pParent [%p] direction [%d] client [%p]\n",
+                pParent, direction, client);
+    #endif
+
+    /*
+     * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+     *         nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
+     * {
+     *   nxagentCirculateRootlessWindows(direction);
+     *   return Success;
+     * }
+     */
+
+    pHead = RealChildHead(pParent);
+    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+    if (direction == RaiseLowest)
+    {
+	for (pWin = pParent->lastChild;
+	     (pWin != pHead) &&
+	     !(pWin->mapped &&
+	       AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+	     pWin = pWin->prevSib) ;
+	if (pWin == pHead)
+	    return Success;
+    }
+    else
+    {
+	for (pWin = pFirst;
+	     pWin &&
+	     !(pWin->mapped &&
+	       IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+	     pWin = pWin->nextSib) ;
+	if (!pWin)
+	    return Success;
+    }
+
+    event.u.circulate.window = pWin->drawable.id;
+    event.u.circulate.parent = pParent->drawable.id;
+    event.u.circulate.event = pParent->drawable.id;
+    if (direction == RaiseLowest)
+	event.u.circulate.place = PlaceOnTop;
+    else
+	event.u.circulate.place = PlaceOnBottom;
+
+    if (RedirectSend(pParent))
+    {
+	event.u.u.type = CirculateRequest;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+
+    event.u.u.type = CirculateNotify;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+    ReflectStackChange(pWin,
+		       (direction == RaiseLowest) ? pFirst : NullWindow,
+		       VTStack);
+
+    return(Success);
+}
+
+static int
+#if NeedFunctionPrototypes
+CompareWIDs(
+    WindowPtr pWin,
+    pointer   value) /* must conform to VisitWindowProcPtr */
+#else
+CompareWIDs(pWin, value)
+    WindowPtr pWin;
+    pointer   value; /* must conform to VisitWindowProcPtr */
+#endif
+{
+    Window *wid = (Window *)value;
+
+    if (pWin->drawable.id == *wid)
+       return(WT_STOPWALKING);
+    else
+       return(WT_WALKCHILDREN);
+}
+
+/*****
+ *  ReparentWindow
+ *****/
+
+int
+ReparentWindow(pWin, pParent, x, y, client)
+    register WindowPtr pWin, pParent;
+    int x,y;
+    ClientPtr client;
+{
+    WindowPtr pPrev, pPriorParent;
+    Bool WasMapped = (Bool)(pWin->mapped);
+    xEvent event;
+    int bw = wBorderWidth (pWin);
+    register ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+	return(BadMatch);		
+    if (!MakeWindowOptional(pWin))
+	return(BadAlloc);
+
+    if (WasMapped)
+       UnmapWindow(pWin, FALSE);
+
+    event.u.u.type = ReparentNotify;
+    event.u.reparent.window = pWin->drawable.id;
+    event.u.reparent.parent = pParent->drawable.id;
+    event.u.reparent.x = x;
+    event.u.reparent.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && !pParent->parent) {
+	event.u.reparent.x += panoramiXdataPtr[0].x;
+	event.u.reparent.y += panoramiXdataPtr[0].y;
+    }
+#endif
+    event.u.reparent.override = pWin->overrideRedirect;
+    DeliverEvents(pWin, &event, 1, pParent);
+
+    /* take out of sibling chain */
+
+    pPriorParent = pPrev = pWin->parent;
+    if (pPrev->firstChild == pWin)
+	pPrev->firstChild = pWin->nextSib;
+    if (pPrev->lastChild == pWin)
+	pPrev->lastChild = pWin->prevSib;
+
+    if (pWin->nextSib)
+	pWin->nextSib->prevSib = pWin->prevSib;
+    if (pWin->prevSib)
+	pWin->prevSib->nextSib = pWin->nextSib;
+
+    /* insert at begining of pParent */
+    pWin->parent = pParent;
+    pPrev = RealChildHead(pParent);
+
+    if (pWin->parent == WindowTable[0])
+    {
+      nxagentSetTopLevelEventMask(pWin);
+    }
+ 
+    if (pPrev)
+    {
+	pWin->nextSib = pPrev->nextSib;
+	if (pPrev->nextSib)
+	    pPrev->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pPrev->nextSib = pWin;
+	pWin->prevSib = pPrev;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	pWin->prevSib = NullWindow;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.x = x + bw + pParent->drawable.x;
+    pWin->drawable.y = y + bw + pParent->drawable.y;
+
+    /* clip to parent */
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    if (pScreen->ReparentWindow)
+	(*pScreen->ReparentWindow)(pWin, pPriorParent);
+
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    CheckWindowOptionalNeed(pWin);
+
+    if (WasMapped)
+	MapWindow(pWin, client);
+    RecalculateDeliverableEvents(pWin);
+    return(Success);
+}
+
+static void
+#if NeedFunctionPrototypes
+RealizeTree(WindowPtr pWin)
+#else
+RealizeTree(pWin)
+    WindowPtr pWin;
+#endif
+{
+    register WindowPtr pChild;
+    RealizeWindowProcPtr Realize;
+
+    Realize = pWin->drawable.pScreen->RealizeWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->mapped)
+	{
+	    pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder)
+		deltaSaveUndersViewable++;
+#endif
+	    pChild->viewable = (pChild->drawable.class == InputOutput);
+	    (* Realize)(pChild);
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * MapWindow
+ *    If some other client has selected SubStructureReDirect on the parent
+ *    and override-redirect is xFalse, then a MapRequest event is generated,
+ *    but the window remains unmapped.	Otherwise, the window is mapped and a
+ *    MapNotify event is generated.
+ *****/
+
+int
+MapWindow(pWin, client)
+    register WindowPtr pWin;
+    ClientPtr client;
+{
+    register ScreenPtr pScreen;
+
+    register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+    }
+    #endif
+
+    if (pWin->mapped)
+	return(Success);
+
+#ifdef XCSECURITY
+    /*  don't let an untrusted client map a child-of-trusted-window, InputOnly
+     *  window; too easy to steal device input
+     */
+    if ( (client->trustLevel != XSecurityClientTrusted) &&
+	 (pWin->drawable.class == InputOnly) &&
+	 (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+	 return Success;
+#endif	
+
+    pScreen = pWin->drawable.pScreen;
+    if ( (pParent = pWin->parent) )
+    {
+	xEvent event;
+	Bool anyMarked;
+#ifdef XAPPGROUP
+	ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+	ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+	if ((!pWin->overrideRedirect) && 
+	    (RedirectSend(pParent)
+#ifdef XAPPGROUP
+	    || (win_owner->appgroup && ag_leader &&
+		XagIsControlledRoot (client, pParent))
+#endif
+	))
+	{
+	    event.u.u.type = MapRequest;
+	    event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+	    /* make sure if the ag_leader maps the window it goes to the wm */
+	    if (ag_leader && ag_leader != client &&
+		XagIsControlledRoot (client, pParent)) {
+		event.u.mapRequest.parent = XagId (win_owner);
+		(void) TryClientEvents (ag_leader, &event, 1,
+					NoEventMask, NoEventMask, NullGrab);
+		return Success;
+	    }
+#endif
+	    event.u.mapRequest.parent = pParent->drawable.id;
+
+	    if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+		return(Success);
+	}
+
+	pWin->mapped = TRUE;
+	if (SubStrSend(pWin, pParent))
+	{
+	    event.u.u.type = MapNotify;
+	    event.u.mapNotify.window = pWin->drawable.id;
+	    event.u.mapNotify.override = pWin->overrideRedirect;
+	    DeliverEvents(pWin, &event, 1, NullWindow);
+	}
+
+	if (!pParent->realized)
+	    return(Success);
+	RealizeTree(pWin);
+	if (pWin->viewable)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+	    if (DO_SAVE_UNDERS(pWin))
+	    {
+		dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+#endif /* DO_SAVE_UNDERS */
+	    if (anyMarked)
+	    {
+		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+		(*pScreen->HandleExposures)(pLayerWin->parent);
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (dosave)
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+	}
+	WindowsRestructured ();
+    }
+    else
+    {
+	RegionRec   temp;
+
+	pWin->mapped = TRUE;
+	pWin->realized = TRUE;	   /* for roots */
+	pWin->viewable = pWin->drawable.class == InputOutput;
+	/* We SHOULD check for an error value here XXX */
+	(*pScreen->RealizeWindow)(pWin);
+	if (pScreen->ClipNotify)
+	    (*pScreen->ClipNotify) (pWin, 0, 0);
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+	REGION_INIT(pScreen, &temp, NullBox, 0);
+	REGION_COPY(pScreen, &temp, &pWin->clipList);
+	(*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+	REGION_UNINIT(pScreen, &temp);
+    }
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ *    Performs a MapWindow all unmapped children of the window, in top
+ *    to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(pParent, client)
+    register WindowPtr pParent;
+    ClientPtr client;
+{
+    register WindowPtr	pWin;
+    WindowPtr		pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+    WindowPtr		pFirstSaveUndered = NullWindow;
+#endif
+    register ScreenPtr	pScreen;
+    register Mask	parentRedirect;
+    register Mask	parentNotify;
+    xEvent		event;
+    Bool		anyMarked;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr		pLayerWin;
+
+    pScreen = pParent->drawable.pScreen;
+    parentRedirect = RedirectSend(pParent);
+    parentNotify = SubSend(pParent);
+    anyMarked = FALSE;
+    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+    {
+	if (!pWin->mapped)
+	{
+	    if (parentRedirect && !pWin->overrideRedirect)
+	    {
+		event.u.u.type = MapRequest;
+		event.u.mapRequest.window = pWin->drawable.id;
+		event.u.mapRequest.parent = pParent->drawable.id;
+    
+		if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		    SubstructureRedirectMask, client) == 1)
+		    continue;
+	    }
+    
+	    pWin->mapped = TRUE;
+	    if (parentNotify || StrSend(pWin))
+	    {
+		event.u.u.type = MapNotify;
+		event.u.mapNotify.window = pWin->drawable.id;
+		event.u.mapNotify.override = pWin->overrideRedirect;
+		DeliverEvents(pWin, &event, 1, NullWindow);
+	    }
+    
+	    if (!pFirstMapped)
+		pFirstMapped = pWin;
+	    if (pParent->realized)
+	    {
+		RealizeTree(pWin);
+		if (pWin->viewable)
+		{
+		    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							(WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave = TRUE;
+		    }
+#endif /* DO_SAVE_UNDERS */
+		}
+	    }
+	}
+    }
+
+    if (pFirstMapped)
+    {
+	pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+	if (pLayerWin->parent != pParent) {
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+							   pLayerWin,
+							   (WindowPtr *)NULL);
+	    pFirstMapped = pLayerWin;
+	}
+        if (anyMarked)
+        {
+#ifdef DO_SAVE_UNDERS
+	    if (pLayerWin->parent != pParent)
+	    {
+		if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+		{
+		    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+							 pLayerWin);
+		}
+	    }
+	    else if (dosave)
+	    {
+		dosave = FALSE;
+		for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+		{
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+							      pWin->nextSib);
+			if (dosave && !pFirstSaveUndered)
+			    pFirstSaveUndered = pWin;
+		    }
+		}
+            }
+#endif /* DO_SAVE_UNDERS */
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+        if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin,
+					    pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+        if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+					 VTMap);
+        WindowsRestructured ();
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+UnrealizeTree(
+    WindowPtr pWin,
+    Bool fromConfigure)
+#else
+UnrealizeTree(pWin, fromConfigure)
+    WindowPtr pWin;
+    Bool fromConfigure;
+#endif
+{
+    register WindowPtr pChild;
+    UnrealizeWindowProcPtr Unrealize;
+    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->realized)
+	{
+	    pChild->realized = FALSE;
+	    pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+		PanoramiXRes *win;
+		win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+							XRT_WINDOW);
+		if(win)
+		   win->u.win.visibility = VisibilityNotViewable;
+	    } 
+#endif
+	    (* Unrealize)(pChild);
+	    DeleteWindowFromAnyEvents(pChild, FALSE);
+	    if (pChild->viewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		if (pChild->saveUnder)
+		    deltaSaveUndersViewable--;
+#endif
+		pChild->viewable = FALSE;
+		if (pChild->backStorage)
+		    (*pChild->drawable.pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+		(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+		pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    }
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * UnmapWindow
+ *    If the window is already unmapped, this request has no effect.
+ *    Otherwise, the window is unmapped and an UnMapNotify event is
+ *    generated.  Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(pWin, fromConfigure)
+    register WindowPtr pWin;
+    Bool fromConfigure;
+{
+    register WindowPtr pParent;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
+                  fromConfigure);
+    }
+    #endif
+
+    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+	return(Success);
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = UnmapNotify;
+	event.u.unmapNotify.window = pWin->drawable.id;
+	event.u.unmapNotify.fromConfigure = fromConfigure;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (wasViewable && !fromConfigure)
+    {
+	pWin->valdata = UnmapValData;
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+	(*pScreen->MarkWindow)(pLayerWin->parent);
+    }
+    pWin->mapped = FALSE;
+    if (wasRealized)
+	UnrealizeTree(pWin, fromConfigure);
+    if (wasViewable)
+    {
+	if (!fromConfigure)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+	    {
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+	}
+	pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+	if (!fromConfigure && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+    }
+    if (wasRealized && !fromConfigure)
+	WindowsRestructured ();
+    return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ *    Performs an UnmapWindow request with the specified mode on all mapped
+ *    children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(pWin)
+    register WindowPtr pWin;
+{
+    register WindowPtr pChild, pHead;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    Bool anyMarked = FALSE;
+    Mask parentNotify;
+    WindowPtr pLayerWin = NULL;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!pWin->firstChild)
+	return;
+    parentNotify = SubSend(pWin);
+    pHead = RealChildHead(pWin);
+
+    if (wasViewable)
+	pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+	if (pChild->mapped)
+	{
+	    if (parentNotify || StrSend(pChild))
+	    {
+		event.u.u.type = UnmapNotify;
+		event.u.unmapNotify.window = pChild->drawable.id;
+		event.u.unmapNotify.fromConfigure = xFalse;
+		DeliverEvents(pChild, &event, 1, NullWindow);
+	    }
+	    if (pChild->viewable)
+	    {
+		pChild->valdata = UnmapValData;
+		anyMarked = TRUE;
+	    }
+	    pChild->mapped = FALSE;
+	    if (pChild->realized)
+		UnrealizeTree(pChild, FALSE);
+	    if (wasViewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+		if (pChild->backStorage)
+		    (*pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+	    }
+	}
+    }
+    if (wasViewable)
+    {
+	if (anyMarked)
+	{
+	    if (pLayerWin->parent == pWin)
+		(*pScreen->MarkWindow)(pWin);
+	    else
+	    {
+		WindowPtr ptmp;
+                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						  (WindowPtr *)NULL);
+		(*pScreen->MarkWindow)(pLayerWin->parent);
+		
+		/* Windows between pWin and pLayerWin may not have been marked */
+		ptmp = pWin;
+ 
+		while (ptmp != pLayerWin->parent)
+		{
+		    (*pScreen->MarkWindow)(ptmp);
+		    ptmp = ptmp->parent;
+		}
+                pHead = pWin->firstChild;
+	    }
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+    }
+    if (wasRealized)
+	WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(client)
+    register ClientPtr client;
+{
+    register WindowPtr pParent, pWin;
+    register int j;
+
+    for (j=0; j<client->numSaved; j++)
+    {
+	pWin = (WindowPtr)client->saveSet[j];
+	pParent = pWin->parent;
+	while (pParent && (wClient (pParent) == client))
+	    pParent = pParent->parent;
+	if (pParent)
+	{
+	    if (pParent != pWin->parent)
+	    {
+		ReparentWindow(pWin, pParent,
+			       pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+			       pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+			       client);
+		if(!pWin->realized && pWin->mapped)
+		    pWin->mapped = FALSE;
+	    }
+	    MapWindow(pWin, client);
+	}
+    }
+    xfree(client->saveSet);
+    client->numSaved = 0;
+    client->saveSet = (pointer *)NULL;
+}
+
+Bool
+VisibleBoundingBoxFromPoint(pWin, x, y, box)
+    register WindowPtr pWin;
+    int x, y;	/* in root */
+    BoxPtr box;	  /* "return" value */
+{
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+	return(TRUE);
+    return(FALSE);
+}
+
+Bool
+PointInWindowIsVisible(pWin, x, y)
+    register WindowPtr pWin;
+    int x, y;	/* in root */
+{
+    BoxRec box;
+
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+						  x, y, &box))
+	return(TRUE);
+    return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(pWin)
+    register WindowPtr pWin;
+{
+    register ScreenPtr pScreen;
+    RegionPtr pReg;
+
+    pScreen = pWin->drawable.pScreen;
+    pReg = REGION_CREATE(pScreen, NullBox, 1);
+    if (pWin->parent ||
+	screenIsSaved != SCREEN_SAVER_ON ||
+	!HasSaverWindow (pWin->drawable.pScreen->myNum))
+    {
+	REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+    }
+    return(pReg);
+}
+
+void
+SendVisibilityNotify(pWin)
+    WindowPtr pWin;
+{
+    xEvent event;
+    unsigned int visibility = pWin->visibility;
+
+#ifdef PANORAMIX
+    /* This is not quite correct yet, but it's close */
+    if(!noPanoramiXExtension) {
+	PanoramiXRes *win;
+	WindowPtr pWin2;
+	int i, Scrnum;
+
+	Scrnum = pWin->drawable.pScreen->myNum;
+	
+	win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+	if(!win || (win->u.win.visibility == visibility))
+	    return;
+
+	switch(visibility) {
+	case VisibilityUnobscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+		if (pWin2) {
+		    if(pWin2->visibility == VisibilityPartiallyObscured)
+		   	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	case VisibilityPartiallyObscured:
+	    if(Scrnum) {
+	        pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+		if (pWin2) pWin = pWin2;
+	    }
+	    break;
+	case VisibilityFullyObscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+		
+		if (pWin2) {
+		    if(pWin2->visibility != VisibilityFullyObscured)
+		    	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	}
+	
+	win->u.win.visibility = visibility;
+    }
+#endif
+
+    event.u.u.type = VisibilityNotify;
+    event.u.visibility.window = pWin->drawable.id;
+    event.u.visibility.state = visibility;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+#if NeedFunctionPrototypes
+    WindowPtr /*pWin*/
+#endif
+);
+#endif
+
+void
+SaveScreens(on, mode)
+    int on;
+    int mode;
+{
+    int i;
+    int what;
+    int type;
+
+    if (on == SCREEN_SAVER_FORCER)
+    {
+	UpdateCurrentTimeIf();
+	lastDeviceEventTime = currentTime;
+	if (mode == ScreenSaverReset)
+	    what = SCREEN_SAVER_OFF;
+	else
+	    what = SCREEN_SAVER_ON;
+	type = what;
+    }
+    else
+    {
+	what = on;
+	type = what;
+	if (what == screenIsSaved)
+	    type = SCREEN_SAVER_CYCLE;
+    }
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+	if (on == SCREEN_SAVER_FORCER)
+	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+	if (savedScreenInfo[i].ExternalScreenSaver)
+	{
+          if (nxagentOption(Timeout) != 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
+                        "Ignoring it to let the auto-disconnect feature work.\n");
+            #endif
+          }
+          else
+          {
+	      if ((*savedScreenInfo[i].ExternalScreenSaver)
+		  (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+		  continue;
+          }
+	}
+	if (type == screenIsSaved)
+	    continue;
+	switch (type) {
+	case SCREEN_SAVER_OFF:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+	       (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						      what);
+	    }
+	    else if (HasSaverWindow (i))
+	    {
+		savedScreenInfo[i].pWindow = NullWindow;
+		FreeResource(savedScreenInfo[i].wid, RT_NONE);
+	    }
+	    break;
+	case SCREEN_SAVER_CYCLE:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+	    {
+		WindowPtr pWin = savedScreenInfo[i].pWindow;
+		/* make it look like screen saver is off, so that
+		 * NotClippedByChildren will compute a clip list
+		 * for the root window, so miPaintWindow works
+		 */
+		screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+		(*pWin->drawable.pScreen->MoveWindow)(pWin,
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    DrawLogo(pWin);
+#endif
+		screenIsSaved = SCREEN_SAVER_ON;
+	    }
+	    /*
+	     * Call the DDX saver in case it wants to do something
+	     * at cycle time
+	     */
+	    else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+		(* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						       type);
+	    }
+	    break;
+	case SCREEN_SAVER_ON:
+	    if (ScreenSaverBlanking != DontPreferBlanking)
+	    {
+		if ((* screenInfo.screens[i]->SaveScreen)
+		   (screenInfo.screens[i], what))
+		{
+		   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+		   continue;
+		}
+		if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		    TileScreenSaver(i, SCREEN_IS_BLACK))
+		{
+		    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+		    continue;
+		}
+	    }
+	    if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		TileScreenSaver(i, SCREEN_IS_TILED))
+	    {
+		savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+	    }
+	    else
+		savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+	    break;
+	}
+    }
+    screenIsSaved = what;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+TileScreenSaver(int i, int kind)
+#else
+TileScreenSaver(i, kind)
+    int i;
+    int	kind;
+#endif
+{
+    int j;
+    int result;
+    XID attributes[3];
+    Mask mask;
+    WindowPtr pWin;		
+    CursorMetricRec cm;
+    unsigned char *srcbits, *mskbits;
+    CursorPtr cursor;
+    XID	cursorID = 0;
+    int	attri;
+
+    mask = 0;
+    attri = 0;
+    switch (kind) {
+    case SCREEN_IS_TILED:
+	switch (WindowTable[i]->backgroundState) {
+	case BackgroundPixel:
+	    attributes[attri++] = WindowTable[i]->background.pixel;
+	    mask |= CWBackPixel;
+	    break;
+	case BackgroundPixmap:
+	    attributes[attri++] = None;
+	    mask |= CWBackPixmap;
+	    break;
+	default:
+	    break;
+	}
+	break;
+    case SCREEN_IS_BLACK:
+	attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+	mask |= CWBackPixel;
+	break;
+    }
+    mask |= CWOverrideRedirect;
+    attributes[attri++] = xTrue;
+
+    /*
+     * create a blank cursor
+     */
+
+    cm.width=16;
+    cm.height=16;
+    cm.xhot=8;
+    cm.yhot=8;
+    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    if (!srcbits || !mskbits)
+    {
+	xfree(srcbits);
+	xfree(mskbits);
+	cursor = 0;
+    }
+    else
+    {
+	for (j=0; j<BitmapBytePad(32)*16; j++)
+	    srcbits[j] = mskbits[j] = 0x0;
+	cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+	if (cursor)
+	{
+	    cursorID = FakeClientID(0);
+	    if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+	    {
+		attributes[attri] = cursorID;
+		mask |= CWCursor;
+	    }
+	    else
+		cursor = 0;
+	}
+	else
+	{
+	    xfree (srcbits);
+	    xfree (mskbits);
+	}
+    }
+
+    pWin = savedScreenInfo[i].pWindow =
+	 CreateWindow(savedScreenInfo[i].wid,
+	      WindowTable[i],
+	      -RANDOM_WIDTH, -RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+	      0, InputOutput, mask, attributes, 0, serverClient,
+	      wVisual (WindowTable[i]), &result);
+
+    if (cursor)
+	FreeResource (cursorID, RT_NONE);
+
+    if (!pWin)
+	return FALSE;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW,
+		     (pointer)savedScreenInfo[i].pWindow))
+	return FALSE;
+
+    if (mask & CWBackPixmap)
+    {
+	MakeRootTile (pWin);
+	(*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+    }
+    MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+    if (kind == SCREEN_IS_TILED && logoScreenSaver)
+	DrawLogo(pWin);
+#endif
+    return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure.  Assumptions:	 some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (w)
+    register WindowPtr w;
+{
+    do
+	w = w->parent;
+    while (!w->optional);
+    return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules.	 If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (w)
+    register WindowPtr w;
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (!w->parent)
+	return;
+    optional = w->optional;
+    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+	return;
+    if (optional->otherEventMasks != 0)
+	return;
+    if (optional->otherClients != NULL)
+	return;
+    if (optional->passiveGrabs != NULL)
+	return;
+    if (optional->userProps != NULL)
+	return;
+    if (optional->backingBitPlanes != ~0L)
+	return;
+    if (optional->backingPixel != 0)
+	return;
+#ifdef SHAPE
+    if (optional->boundingShape != NULL)
+	return;
+    if (optional->clipShape != NULL)
+	return;
+#endif
+#ifdef XINPUT
+    if (optional->inputMasks != NULL)
+	return;
+#endif
+    parentOptional = FindWindowWithOptional(w)->optional;
+    if (optional->visual != parentOptional->visual)
+	return;
+    if (optional->cursor != None &&
+	(optional->cursor != parentOptional->cursor ||
+	 w->parent->cursorIsNone))
+	return;
+    if (optional->colormap != parentOptional->colormap)
+	return;
+    DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (pWin)
+    register WindowPtr pWin;
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (pWin->optional)
+	return TRUE;
+    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+    if (!optional)
+	return FALSE;
+    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+    optional->otherEventMasks = 0;
+    optional->otherClients = NULL;
+    optional->passiveGrabs = NULL;
+    optional->userProps = NULL;
+    optional->backingBitPlanes = ~0L;
+    optional->backingPixel = 0;
+#ifdef SHAPE
+    optional->boundingShape = NULL;
+    optional->clipShape = NULL;
+#endif
+#ifdef XINPUT
+    optional->inputMasks = NULL;
+#endif
+    parentOptional = FindWindowWithOptional(pWin)->optional;
+    optional->visual = parentOptional->visual;
+    if (!pWin->cursorIsNone)
+    {
+	optional->cursor = parentOptional->cursor;
+	optional->cursor->refcnt++;
+    }
+    else
+    {
+	optional->cursor = None;
+    }
+    optional->colormap = parentOptional->colormap;
+    pWin->optional = optional;
+    return TRUE;
+}
+
+void
+DisposeWindowOptional (pWin)
+    register WindowPtr pWin;
+{
+    if (!pWin->optional)
+	return;
+    /*
+     * everything is peachy.  Delete the optional record
+     * and clean up
+     */
+    /*
+     * TOG changed this code to:
+     *
+     *	    if (pWin->cursorIsNone == FALSE)
+     *		FreeCursor (pWin->optional->cursor, (Cursor)0);
+     *	    pWin->cursorIsNone = TRUE;
+     *
+     * This is blatently wrong; windows without optionals can have
+     * two different cursor values, either None or sharing their
+     * parents cursor.  This difference is controlled by the
+     * cursorIsNone value; when TRUE, the window has no cursor,
+     * when false, it shares its cursor with its parent; TOG
+     * made it impossible for a window to have a cursor without
+     * an optional record.
+     */
+    if (pWin->optional->cursor)
+    {
+	FreeCursor (pWin->optional->cursor, (Cursor)0);
+	pWin->cursorIsNone = FALSE;
+    }
+    else
+	pWin->cursorIsNone = TRUE;
+/* FIXME
+   There is an error when disposing ClientResources on Agent exit
+   this xfree is not valid in some window at exit
+*/
+
+    xfree (pWin->optional);
+    pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+#if NeedFunctionPrototypes
+DrawLogo(WindowPtr pWin)
+#else
+DrawLogo(pWin)
+    WindowPtr pWin;
+#endif
+{
+    DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    int x, y;
+    unsigned int width, height, size;
+    GC *pGC;
+    int thin, gap, d31;
+    DDXPointRec poly[4];
+    ChangeGCVal fore[2], back[2];
+    xrgb rgb[2];
+    BITS32 fmask, bmask;
+    ColormapPtr cmap;
+
+    pDraw = (DrawablePtr)pWin;
+    pScreen = pDraw->pScreen;
+    x = -pWin->origin.x;
+    y = -pWin->origin.y;
+    width = pScreen->width;
+    height = pScreen->height;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pGC)
+	return;
+
+    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+	fore[0].val = pScreen->whitePixel;
+    else
+	fore[0].val = pScreen->blackPixel;
+    if ((pWin->backgroundState == BackgroundPixel) &&
+	(cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+	Pixel querypixels[2];
+
+	querypixels[0] = fore[0].val;
+	querypixels[1] = pWin->background.pixel;
+	QueryColors(cmap, 2, querypixels, rgb);
+	if ((rgb[0].red == rgb[1].red) &&
+	    (rgb[0].green == rgb[1].green) &&
+	    (rgb[0].blue == rgb[1].blue)) {
+	    if (fore[0].val == pScreen->blackPixel)
+		fore[0].val = pScreen->whitePixel;
+	    else
+		fore[0].val = pScreen->blackPixel;
+	}
+    }
+    fore[1].val = FillSolid;
+    fmask = GCForeground|GCFillStyle;
+    if (pWin->backgroundState == BackgroundPixel) {
+	back[0].val = pWin->background.pixel;
+	back[1].val = FillSolid;
+	bmask = GCForeground|GCFillStyle;
+    } else {
+	back[0].val = 0;
+	back[1].val = 0;
+	dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+		    NULL, back);
+	back[0].val = FillTiled;
+	back[1].ptr = pWin->background.pixmap;
+	bmask = GCFillStyle|GCTile;
+    }
+
+    /* should be the same as the reference function XmuDrawLogo() */
+
+    size = width;
+    if (height < width)
+	 size = height;
+    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+    size &= ~1;
+    x += rand() % (width - size);
+    y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ *           -----
+ *          /    /
+ *         /    /
+ *        /    /
+ *       /    /
+ *      /____/
+ *           d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+    thin = (size / 11);
+    if (thin < 1) thin = 1;
+    gap = (thin+3) / 4;
+    d31 = thin + thin + gap;
+    poly[0].x = x + size;	       poly[0].y = y;
+    poly[1].x = x + size-d31;	       poly[1].y = y;
+    poly[2].x = x + 0;		       poly[2].y = y + size;
+    poly[3].x = x + d31;	       poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ *           ------
+ *          /	  /
+ *         /  __ /
+ *        /  /	/
+ *       /  /  /
+ *      /__/__/
+ */
+
+    poly[0].x = x + d31/2;			 poly[0].y = y + size;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)+(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + d31;			 poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ *	     ------
+ *	    /  /  /
+ *	   /--/	 /
+ *	  /	/
+ *	 /     /
+ *	/_____/
+ */
+
+    poly[0].x = x + size - d31/2;		 poly[0].y = y;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)-(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + size - d31;			 poly[3].y = y;
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ *      b
+ * -----
+ * \	\
+ *  \	 \
+ *   \	  \
+ *    \	   \
+ *     \____\
+ */
+
+    poly[0].x = x;		       poly[0].y = y;
+    poly[1].x = x + size/4;	       poly[1].y = y;
+    poly[2].x = x + size;	       poly[2].y = y + size;
+    poly[3].x = x + size - size/4;     poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ *	    /
+ *	   /
+ *	  /
+ *	 /
+ *	/
+ */
+
+    poly[0].x = x + size- thin;	      poly[0].y = y;
+    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
+    poly[2].x = x + thin;	      poly[2].y = y + size;
+    poly[3].x = x + thin + gap;	      poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+    FreeScratchGC(pGC);
+}
+
+#endif
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.XF86.original
new file mode 100644
index 000000000..30c0df032
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.XF86.original
@@ -0,0 +1,3947 @@
+/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+/*
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+			All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/****************************************************************
+*                                                               *
+*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
+*                                                               *
+*   All Rights Reserved.  Unpublished rights  reserved  under   *
+*   the copyright laws of the United States.                    *
+*                                                               *
+*   The software contained on this media  is  proprietary  to   *
+*   and  embodies  the  confidential  technology  of  Digital   *
+*   Equipment Corporation.  Possession, use,  duplication  or   *
+*   dissemination of the software and media is authorized only  *
+*   pursuant to a valid written license from Digital Equipment  *
+*   Corporation.                                                *
+*                                                               *
+*   RESTRICTED RIGHTS LEGEND   Use, duplication, or disclosure  *
+*   by the U.S. Government is subject to restrictions  as  set  *
+*   forth in Subparagraph (c)(1)(ii)  of  DFARS  252.227-7013,  *
+*   or  in  FAR 52.227-19, as applicable.                       *
+*                                                               *
+*****************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.32 2003/01/12 02:44:26 dawes Exp $ */
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include "Xagsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "security.h"
+#endif
+
+#if defined(NEED_SCREEN_REGIONS)
+#define REGION_PTR(pScreen,pWin) \
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+#else
+#define REGION_PTR(pScreen,pWin) /* nothing */
+#endif
+
+/******
+ * Window stuff for server 
+ *
+ *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
+static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(
+#if NeedFunctionPrototypes
+    int /*i*/,
+    int /*kind*/
+#endif
+);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+			      CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+      (!( ((b1)->x2 <= (b2)->x1)  || \
+	( ((b1)->x1 >= (b2)->x2)) || \
+	( ((b1)->y2 <= (b2)->y1)) || \
+	( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+#ifdef DEBUG
+/******
+ * PrintWindowTree
+ *    For debugging only
+ ******/
+
+int
+PrintChildren(p1, indent)
+    WindowPtr p1;
+    int indent;
+{
+    WindowPtr p2;
+    int i;
+
+    while (p1)
+    {
+	p2 = p1->firstChild;
+	for (i=0; i<indent; i++) ErrorF( " ");
+	ErrorF( "%x\n", p1->drawable.id);
+	miPrintRegion(&p1->clipList);
+	PrintChildren(p2, indent+4);
+	p1 = p1->nextSib;
+    }
+}
+
+PrintWindowTree()
+{
+    int i;
+    WindowPtr pWin, p1;
+
+    for (i=0; i<screenInfo.numScreens; i++)
+    {
+	ErrorF( "WINDOW %d\n", i);
+	pWin = WindowTable[i];
+	miPrintRegion(&pWin->clipList);
+	p1 = pWin->firstChild;
+	PrintChildren(p1, 4);
+    }
+}
+#endif
+
+int
+TraverseTree(pWin, func, data)
+    register WindowPtr pWin;
+    VisitWindowProcPtr func;
+    pointer data;
+{
+    register int result;
+    register WindowPtr pChild;
+
+    if (!(pChild = pWin))
+       return(WT_NOMATCH);
+    while (1)
+    {
+	result = (* func)(pChild, data);
+	if (result == WT_STOPWALKING)
+	    return(WT_STOPWALKING);
+	if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+    return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
+ *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
+ *   exit WalkTree.  Does depth-first traverse.
+ *****/
+
+int
+WalkTree(pScreen, func, data)
+    ScreenPtr pScreen;
+    VisitWindowProcPtr func;
+    pointer data;
+{
+    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int	defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool	disableBackingStore = FALSE;
+Bool	enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool	disableSaveUnders = FALSE;
+
+static void
+#if NeedFunctionPrototypes
+SetWindowToDefaults(register WindowPtr pWin)
+#else
+SetWindowToDefaults(pWin)
+    register WindowPtr pWin;
+#endif
+{
+    pWin->prevSib = NullWindow;
+    pWin->firstChild = NullWindow;
+    pWin->lastChild = NullWindow;
+
+    pWin->valdata = (ValidatePtr)NULL;
+    pWin->optional = (WindowOptPtr)NULL;
+    pWin->cursorIsNone = TRUE;
+
+    pWin->backingStore = NotUseful;
+    pWin->DIXsaveUnder = FALSE;
+    pWin->backStorage = (pointer) NULL;
+
+    pWin->mapped = FALSE;	    /* off */
+    pWin->realized = FALSE;	/* off */
+    pWin->viewable = FALSE;
+    pWin->visibility = VisibilityNotViewable;
+    pWin->overrideRedirect = FALSE;
+    pWin->saveUnder = FALSE;
+
+    pWin->bitGravity = ForgetGravity;
+    pWin->winGravity = NorthWestGravity;
+
+    pWin->eventMask = 0;
+    pWin->deliverableEvents = 0;
+    pWin->dontPropagate = 0;
+    pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+    pWin->srcBuffer = DBE_FRONT_BUFFER;
+    pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+}
+
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+    WindowPtr pWin;
+#endif
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    GCPtr pGC;
+    unsigned char back[128];
+    int len = BitmapBytePad(sizeof(long));
+    register unsigned char *from, *to;
+    register int i, j;
+
+    pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+						    pScreen->rootDepth);
+
+    pWin->backgroundState = BackgroundPixmap;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pWin->background.pixmap || !pGC)
+	FatalError("could not create root tile");
+
+    {
+	CARD32 attributes[2];
+
+	attributes[0] = pScreen->whitePixel;
+	attributes[1] = pScreen->blackPixel;
+
+	(void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+    }
+
+   ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+   from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+   to = back;
+
+   for (i = 4; i > 0; i--, from++)
+	for (j = len; j > 0; j--)
+	    *to++ = *from;
+
+   if (blackRoot)
+       bzero(back, sizeof(back));
+
+   (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+		    0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+   FreeScratchGC(pGC);
+
+}
+
+WindowPtr
+AllocateWindow(pScreen)
+    ScreenPtr pScreen;
+{
+    WindowPtr pWin;
+    register char *ptr;
+    register DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+    if (pWin)
+    {
+	ppriv = (DevUnion *)(pWin + 1);
+	pWin->devPrivates = ppriv;
+	sizes = pScreen->WindowPrivateSizes;
+	ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+	for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+	{
+	    if ( (size = *sizes) )
+	    {
+		ppriv->ptr = (pointer)ptr;
+		ptr += size;
+	    }
+	    else
+		ppriv->ptr = (pointer)NULL;
+	}
+    }
+    return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ *    Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(pScreen)
+    ScreenPtr	pScreen;
+{
+    WindowPtr	pWin;
+    BoxRec	box;
+    PixmapFormatRec *format;
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+	return FALSE;
+
+    savedScreenInfo[pScreen->myNum].pWindow = NULL;
+    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+    screenIsSaved = SCREEN_SAVER_OFF;
+
+    WindowTable[pScreen->myNum] = pWin;
+
+    pWin->drawable.pScreen = pScreen;
+    pWin->drawable.type = DRAWABLE_WINDOW;
+
+    pWin->drawable.depth = pScreen->rootDepth;
+    for (format = screenInfo.formats;
+	 format->depth != pScreen->rootDepth;
+	 format++)
+	;
+    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->parent = NullWindow;
+    SetWindowToDefaults(pWin);
+
+    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+    if (!pWin->optional)
+        return FALSE;
+
+    pWin->optional->dontPropagateMask = 0;
+    pWin->optional->otherEventMasks = 0;
+    pWin->optional->otherClients = NULL;
+    pWin->optional->passiveGrabs = NULL;
+    pWin->optional->userProps = NULL;
+    pWin->optional->backingBitPlanes = ~0L;
+    pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+    pWin->optional->boundingShape = NULL;
+    pWin->optional->clipShape = NULL;
+#endif
+#ifdef XINPUT
+    pWin->optional->inputMasks = NULL;
+#endif
+    pWin->optional->colormap = pScreen->defColormap;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->nextSib = NullWindow;
+
+    pWin->drawable.id = FakeClientID(0);
+
+    pWin->origin.x = pWin->origin.y = 0;
+    pWin->drawable.height = pScreen->height;
+    pWin->drawable.width = pScreen->width;
+    pWin->drawable.x = pWin->drawable.y = 0;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+    pWin->drawable.class = InputOutput;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->backgroundState = BackgroundPixel;
+    pWin->background.pixel = pScreen->whitePixel;
+
+    pWin->borderIsPixel = TRUE;
+    pWin->border.pixel = pScreen->blackPixel;
+    pWin->borderWidth = 0;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+	return FALSE;
+
+    if (disableBackingStore)
+	pScreen->backingStoreSupport = NotUseful;
+    if (enableBackingStore)
+	pScreen->backingStoreSupport = Always;
+
+#ifdef DO_SAVE_UNDERS
+    if ((pScreen->backingStoreSupport != NotUseful) &&
+	(pScreen->saveUnderSupport == NotUseful))
+    {
+	/*
+	 * If the screen has backing-store but no save-unders, let the
+	 * clients know we can support save-unders using backing-store.
+	 */
+	pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+    }
+#endif /* DO_SAVE_UNDERS */
+		
+    if (disableSaveUnders)
+	pScreen->saveUnderSupport = NotUseful;
+
+    return TRUE;
+}
+
+void
+InitRootWindow(pWin)
+    WindowPtr pWin;
+{
+    ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    MakeRootTile(pWin);
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+    MapWindow(pWin, serverClient);
+}
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize.  The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(pWin, Rgn, x, y, w, h)
+    register WindowPtr pWin;
+    RegionPtr Rgn;
+    register int x, y;
+    int w, h;
+{
+    REGION_PTR(pScreen, pWin)
+    BoxRec box;
+
+    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+    /* we do these calculations to avoid overflows */
+    if (x > box.x1)
+	box.x1 = x;
+    if (y > box.y1)
+	box.y1 = y;
+    x += w;
+    if (x < box.x2)
+	box.x2 = x;
+    y += h;
+    if (y < box.y2)
+	box.y2 = y;
+    if (box.x1 > box.x2)
+	box.x2 = box.x1;
+    if (box.y1 > box.y2)
+	box.y2 = box.y1;
+    REGION_RESET(pScreen, Rgn, &box);
+    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(pWin)
+    register WindowPtr pWin;
+{
+    if (!pWin->parent &&
+	(screenIsSaved == SCREEN_SAVER_ON) &&
+	(HasSaverWindow (pWin->drawable.pScreen->myNum)))
+	return (pWin->firstChild);
+    else
+	return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ *    Makes a window in response to client request 
+ *****/
+
+WindowPtr
+CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist,
+	     depth, client, visual, error)
+    Window wid;
+    register WindowPtr pParent;
+    int x,y;
+    unsigned int w, h, bw;
+    unsigned int class;
+    register Mask vmask;
+    XID *vlist;
+    int depth;
+    ClientPtr client;
+    VisualID visual;
+    int *error;
+{
+    register WindowPtr pWin;
+    WindowPtr pHead;
+    register ScreenPtr pScreen;
+    xEvent event;
+    int idepth, ivisual;
+    Bool fOK;
+    DepthPtr pDepth;
+    PixmapFormatRec *format;
+    register WindowOptPtr ancwopt;
+
+    if (class == CopyFromParent)
+	class = pParent->drawable.class;
+
+    if ((class != InputOutput) && (class != InputOnly))
+    {
+	*error = BadValue;
+	client->errorValue = class;
+	return NullWindow;
+    }
+
+    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pScreen = pParent->drawable.pScreen;
+    if ((class == InputOutput) && (depth == 0))
+	 depth = pParent->drawable.depth;
+    ancwopt = pParent->optional;
+    if (!ancwopt)
+	ancwopt = FindWindowWithOptional(pParent)->optional;
+    if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+	VisualID ag_visual;
+
+	if (client->appgroup && !pParent->parent &&
+	    (ag_visual = XagRootVisual (client)))
+	    visual = ag_visual;
+	else
+#endif
+	visual = ancwopt->visual;
+    }
+
+    /* Find out if the depth and visual are acceptable for this Screen */
+    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+    {
+	fOK = FALSE;
+	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+	{
+	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+	    if ((depth == pDepth->depth) || (depth == 0))
+	    {
+		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+		{
+		    if (visual == pDepth->vids[ivisual])
+		    {
+			fOK = TRUE;
+			break;
+		    }
+		}
+	    }
+	}
+	if (fOK == FALSE)
+	{
+	    *error = BadMatch;
+	    return NullWindow;
+	}
+    }
+
+    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+	(class != InputOnly) &&
+	(depth != pParent->drawable.depth))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if (((vmask & CWColormap) == 0) &&
+	(class != InputOnly) &&
+	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+    {
+	*error = BadAlloc;
+	return NullWindow;
+    }
+    pWin->drawable = pParent->drawable;
+    pWin->drawable.depth = depth;
+    if (depth == pParent->drawable.depth)
+	pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+    else
+    {
+	for (format = screenInfo.formats; format->depth != depth; format++)
+	    ;
+	pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+    }
+    if (class == InputOnly)
+	pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->drawable.id = wid;
+    pWin->drawable.class = class;
+
+    pWin->parent = pParent;
+    SetWindowToDefaults(pWin);
+
+    if (visual != ancwopt->visual)
+    {
+	if (!MakeWindowOptional (pWin))
+	{
+	    xfree (pWin);
+	    *error = BadAlloc;
+	    return NullWindow;
+	}
+	pWin->optional->visual = visual;
+	pWin->optional->colormap = None;
+    }
+
+    pWin->borderWidth = bw;
+#ifdef XCSECURITY
+    /*  can't let untrusted clients have background None windows;
+     *  they make it too easy to steal window contents
+     */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	pWin->backgroundState = BackgroundPixel;
+	pWin->background.pixel = 0;
+    }
+    else
+#endif
+    pWin->backgroundState = None;
+
+    pWin->borderIsPixel = pParent->borderIsPixel;
+    pWin->border = pParent->border;
+    if (pWin->borderIsPixel == FALSE)
+	pWin->border.pixmap->refcnt++;
+		
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    pWin->drawable.width = w;
+    pWin->drawable.height = h;
+    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+	/* set up clip list correctly for unobscured WindowPtr */
+    REGION_INIT(pScreen, &pWin->clipList, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->winSize, NullBox, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, NullBox, 1);
+
+    pHead = RealChildHead(pParent);
+    if (pHead)
+    {
+	pWin->nextSib = pHead->nextSib;
+	if (pHead->nextSib)
+	    pHead->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pHead->nextSib = pWin;
+	pWin->prevSib = pHead;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    /* We SHOULD check for an error value here XXX */
+    if (!(*pScreen->CreateWindow)(pWin))
+    {
+	*error = BadAlloc;
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    if (!(vmask & CWEventMask))
+	RecalculateDeliverableEvents(pWin);
+
+    if (vmask)
+	*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+    else
+	*error = Success;
+
+    if (*error != Success)
+    {
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+    {
+	XID value = defaultBackingStore;
+	(void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+	pWin->forcedBS = TRUE;
+    }
+
+    if (SubSend(pParent))
+    {
+	event.u.u.type = CreateNotify;
+	event.u.createNotify.window = wid;
+	event.u.createNotify.parent = pParent->drawable.id;
+	event.u.createNotify.x = x;
+	event.u.createNotify.y = y;
+	event.u.createNotify.width = w;
+	event.u.createNotify.height = h;
+	event.u.createNotify.borderWidth = bw;
+	event.u.createNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pParent, &event, 1, NullWindow);		
+    }
+    return pWin;
+}
+
+static void
+#if NeedFunctionPrototypes
+FreeWindowResources(register WindowPtr pWin)
+#else
+FreeWindowResources(pWin)
+    register WindowPtr pWin;
+#endif
+{
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DeleteWindowFromAnySaveSet(pWin);
+    DeleteWindowFromAnySelections(pWin);
+    DeleteWindowFromAnyEvents(pWin, TRUE);
+    REGION_UNINIT(pScreen, &pWin->clipList);
+    REGION_UNINIT(pScreen, &pWin->winSize);
+    REGION_UNINIT(pScreen, &pWin->borderClip);
+    REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+    if (wBoundingShape (pWin))
+	REGION_DESTROY(pScreen, wBoundingShape (pWin));
+    if (wClipShape (pWin))
+	REGION_DESTROY(pScreen, wClipShape (pWin));
+#endif
+    if (pWin->borderIsPixel == FALSE)
+	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+    if (pWin->backgroundState == BackgroundPixmap)
+	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+    DeleteAllWindowProperties(pWin);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->DestroyWindow)(pWin);
+    DisposeWindowOptional (pWin);
+}
+
+static void
+#if NeedFunctionPrototypes
+CrushTree(WindowPtr pWin)
+#else
+CrushTree(pWin)
+    WindowPtr pWin;
+#endif
+{
+    register WindowPtr pChild, pSib, pParent;
+    UnrealizeWindowProcPtr UnrealizeWindow;
+    xEvent event;
+
+    if (!(pChild = pWin->firstChild))
+	return;
+    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+    while (1)
+    {
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (1)
+	{
+	    pParent = pChild->parent;
+	    if (SubStrSend(pChild, pParent))
+	    {
+		event.u.u.type = DestroyNotify;
+		event.u.destroyNotify.window = pChild->drawable.id;
+		DeliverEvents(pChild, &event, 1, NullWindow);		
+	    }
+	    FreeResource(pChild->drawable.id, RT_WINDOW);
+	    pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder && pChild->viewable)
+		deltaSaveUndersViewable--;
+#endif
+	    pChild->viewable = FALSE;
+	    if (pChild->realized)
+	    {
+		pChild->realized = FALSE;
+		(*UnrealizeWindow)(pChild);
+	    }
+	    FreeWindowResources(pChild);
+	    xfree(pChild);
+	    if ( (pChild = pSib) )
+		break;
+	    pChild = pParent;
+	    pChild->firstChild = NullWindow;
+	    pChild->lastChild = NullWindow;
+	    if (pChild == pWin)
+		return;
+	}
+    }
+}
+	
+/*****
+ *  DeleteWindow
+ *	 Deletes child of window then window itself
+ *	 If wid is None, don't send any events
+ *****/
+
+/*ARGSUSED*/
+int
+DeleteWindow(value, wid)
+    pointer value;
+    XID wid;
+ {
+    register WindowPtr pParent;
+    register WindowPtr pWin = (WindowPtr)value;
+    xEvent event;
+
+    UnmapWindow(pWin, FALSE);
+
+    CrushTree(pWin);
+
+    pParent = pWin->parent;
+    if (wid && pParent && SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = DestroyNotify;
+	event.u.destroyNotify.window = pWin->drawable.id;
+	DeliverEvents(pWin, &event, 1, NullWindow);		
+    }
+
+    FreeWindowResources(pWin);
+    if (pParent)
+    {
+	if (pParent->firstChild == pWin)
+	    pParent->firstChild = pWin->nextSib;
+	if (pParent->lastChild == pWin)
+	    pParent->lastChild = pWin->prevSib;
+	if (pWin->nextSib)
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	if (pWin->prevSib)
+	    pWin->prevSib->nextSib = pWin->nextSib;
+    }
+    xfree(pWin);
+    return Success;
+}
+
+/*ARGSUSED*/
+void
+DestroySubwindows(pWin, client)
+    register WindowPtr pWin;
+    ClientPtr client;
+{
+    /* XXX
+     * The protocol is quite clear that each window should be
+     * destroyed in turn, however, unmapping all of the first
+     * eliminates most of the calls to ValidateTree.  So,
+     * this implementation is incorrect in that all of the
+     * UnmapNotifies occur before all of the DestroyNotifies.
+     * If you care, simply delete the call to UnmapSubwindows.
+     */
+    UnmapSubwindows(pWin);
+    while (pWin->lastChild)
+	FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+    ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ *  ChangeWindowAttributes
+ *   
+ *  The value-mask specifies which attributes are to be changed; the
+ *  value-list contains one value for each one bit in the mask, from least
+ *  to most significant bit in the mask.  
+ *****/
+ 
+int
+ChangeWindowAttributes(pWin, vmask, vlist, client)
+    register WindowPtr pWin;
+    Mask vmask;
+    XID *vlist;
+    ClientPtr client;
+{
+    register Mask index2;
+    register XID *pVlist;
+    PixmapPtr pPixmap;
+    Pixmap pixID;
+    CursorPtr pCursor, pOldCursor;
+    Cursor cursorID;
+    WindowPtr pChild;
+    Colormap cmap;
+    ColormapPtr	pCmap;
+    xEvent xE;
+    int result;
+    register ScreenPtr pScreen;
+    Mask vmaskCopy = 0;
+    register Mask tmask;
+    unsigned int val;
+    int error;
+    Bool checkOptional = FALSE;
+    Bool borderRelative = FALSE;
+    WindowPtr pLayerWin;
+
+    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+	return BadMatch;
+
+    error = Success;
+    pScreen = pWin->drawable.pScreen;
+    pVlist = vlist;
+    tmask = vmask;
+    while (tmask)
+    {
+	index2 = (Mask) lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBackPixmap:
+	    pixID = (Pixmap )*pVlist;
+	    pVlist++;
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pixID == None)
+	    {
+#ifdef XCSECURITY
+		/*  can't let untrusted clients have background None windows */
+		if (client->trustLevel == XSecurityClientTrusted)
+		{
+#endif
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = None;
+#ifdef XCSECURITY
+		}
+		else
+		{ /* didn't change the background to None, so don't tell ddx */
+		    index2 = 0; 
+		}
+#endif
+	    }
+	    else if (pixID == ParentRelative)
+	    {
+		if (pWin->parent &&
+		    pWin->drawable.depth != pWin->parent->drawable.depth)
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = ParentRelative;
+		borderRelative = TRUE;
+		/* Note that the parent's backgroundTile's refcnt is NOT
+		 * incremented. */
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+						RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap != (PixmapPtr) NULL)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->backgroundState == BackgroundPixmap)
+			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    pWin->backgroundState = BackgroundPixmap;
+		    pWin->background.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBackPixel:
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pWin->backgroundState == BackgroundPixmap)
+		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+	    pWin->backgroundState = BackgroundPixel;
+	    pWin->background.pixel = (CARD32 ) *pVlist;
+		   /* background pixel overrides background pixmap,
+		      so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBackPixmap;
+	    pVlist++;
+	    break;
+	  case CWBorderPixmap:
+	    pixID = (Pixmap ) *pVlist;
+	    pVlist++;
+	    if (pixID == CopyFromParent)
+	    {
+		if (!pWin->parent ||
+		    (pWin->drawable.depth != pWin->parent->drawable.depth))
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->borderIsPixel == FALSE)
+		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		pWin->border = pWin->parent->border;
+		if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+		{
+		    index2 = CWBorderPixel;
+		}
+		else
+		{
+		    pWin->parent->border.pixmap->refcnt++;
+		}
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+					RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->borderIsPixel == FALSE)
+			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		    pWin->borderIsPixel = FALSE;
+		    pWin->border.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBorderPixel:
+	    if (pWin->borderIsPixel == FALSE)
+		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+	    pWin->borderIsPixel = TRUE;
+	    pWin->border.pixel = (CARD32) *pVlist;
+		    /* border pixel overrides border pixmap,
+		       so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBorderPixmap;
+	    pVlist++;
+	    break;
+	  case CWBitGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->bitGravity = val;
+	    break;
+	  case CWWinGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->winGravity = val;
+	    break;
+	  case CWBackingStore:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->backingStore = val;
+	    pWin->forcedBS = FALSE;
+	    break;
+	  case CWBackingPlanes:
+	    if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+		if ((CARD32)*pVlist == (CARD32)~0L)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWBackingPixel:
+	    if (pWin->optional || (CARD32) *pVlist) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingPixel = (CARD32) *pVlist;
+		if (!*pVlist)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWSaveUnder:
+	    val = (BOOL) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+		DO_SAVE_UNDERS(pWin))
+	    {
+		/*
+		 * Re-check all siblings and inferiors for obscurity or
+		 * exposition (hee hee).
+		 */
+		if (pWin->saveUnder)
+		    deltaSaveUndersViewable--;
+		else
+		    deltaSaveUndersViewable++;
+		pWin->saveUnder = val;
+
+		if (pWin->firstChild)
+		{
+                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+                                                       pWin->nextSib);
+               }
+               else
+               {
+                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pWin,
+                                                       pWin->nextSib);
+               }                                   
+	    }
+	    else
+	    {
+		/*  If we're changing the saveUnder attribute of the root 
+		 *  window, all we do is set pWin->saveUnder so that
+		 *  GetWindowAttributes returns the right value.  We don't
+		 *  do the "normal" save-under processing (as above).
+		 *  Hope that doesn't cause any problems.
+		 */
+		pWin->saveUnder = val;
+	    }
+#else
+	    pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+	    break;
+	  case CWEventMask:
+	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWDontPropagate:
+	    result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+					    &checkOptional);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWOverrideRedirect:
+	    val = (BOOL ) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->overrideRedirect = val;
+	    break;
+	  case CWColormap:
+	    cmap = (Colormap) *pVlist;
+	    pVlist++;
+	    if (cmap == CopyFromParent)
+	    {
+#ifdef XAPPGROUP
+		Colormap ag_colormap;
+		ClientPtr win_owner;
+
+		/*
+		 * win_owner == client for CreateWindow, other clients
+		 * can ChangeWindowAttributes
+		 */
+		win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+		if ( win_owner && win_owner->appgroup &&
+		    !pWin->parent->parent &&
+		    (ag_colormap = XagDefaultColormap (win_owner)))
+		    cmap = ag_colormap;
+		else
+#endif
+		if (pWin->parent &&
+		    (!pWin->optional ||
+		     pWin->optional->visual == wVisual (pWin->parent)))
+		{
+		    cmap = wColormap (pWin->parent);
+		}
+		else
+		    cmap = None;
+	    }
+	    if (cmap == None)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+					      RT_COLORMAP, SecurityReadAccess);
+	    if (!pCmap)
+	    {
+		error = BadColor;
+		client->errorValue = cmap;
+		goto PatchUp;
+	    }
+	    if (pCmap->pVisual->vid != wVisual (pWin) ||
+		pCmap->pScreen != pScreen)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    if (cmap != wColormap (pWin))
+	    {
+		if (!pWin->optional)
+		{
+		    if (!MakeWindowOptional (pWin))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+		else if (pWin->parent && cmap == wColormap (pWin->parent))
+		    checkOptional = TRUE;
+
+		/*
+		 * propagate the original colormap to any children
+		 * inheriting it
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pWin->optional->colormap = cmap;
+
+		/*
+		 * check on any children now matching the new colormap
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (pChild->optional->colormap == cmap)
+			CheckWindowOptionalNeed (pChild);
+		}
+	
+		xE.u.u.type = ColormapNotify;
+		xE.u.colormap.window = pWin->drawable.id;
+		xE.u.colormap.colormap = cmap;
+		xE.u.colormap.new = xTrue;
+		xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+		DeliverEvents(pWin, &xE, 1, NullWindow);
+	    }
+	    break;
+	  case CWCursor:
+	    cursorID = (Cursor ) *pVlist;
+	    pVlist++;
+	    /*
+	     * install the new
+	     */
+	    if ( cursorID == None)
+	    {
+		if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+		    pCursor = rootCursor;
+		else
+		    pCursor = (CursorPtr) None;
+	    }
+	    else
+	    {
+		pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+						RT_CURSOR, SecurityReadAccess);
+		if (!pCursor)
+		{
+		    error = BadCursor;
+		    client->errorValue = cursorID;
+		    goto PatchUp;
+		}
+	    }
+
+	    if (pCursor != wCursor (pWin))
+	    {
+		/*
+		 * patch up child windows so they don't lose cursors.
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !pChild->cursorIsNone &&
+			!MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pOldCursor = 0;
+		if (pCursor == (CursorPtr) None)
+		{
+		    pWin->cursorIsNone = TRUE;
+		    if (pWin->optional)
+		    {
+			pOldCursor = pWin->optional->cursor;
+			pWin->optional->cursor = (CursorPtr) None;
+			checkOptional = TRUE;
+		    }
+		} else {
+		    if (!pWin->optional)
+		    {
+			if (!MakeWindowOptional (pWin))
+			{
+			    error = BadAlloc;
+			    goto PatchUp;
+			}
+		    }
+		    else if (pWin->parent && pCursor == wCursor (pWin->parent))
+			checkOptional = TRUE;
+		    pOldCursor = pWin->optional->cursor;
+		    pWin->optional->cursor = pCursor;
+		    pCursor->refcnt++;
+		    pWin->cursorIsNone = FALSE;
+		    /*
+		     * check on any children now matching the new cursor
+		     */
+
+		    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+		    {
+			if (pChild->optional &&
+			    (pChild->optional->cursor == pCursor))
+			    CheckWindowOptionalNeed (pChild);
+		    }
+		}
+
+		if (pWin->realized)
+		    WindowHasNewCursor( pWin);
+
+		/* Can't free cursor until here - old cursor
+		 * is needed in WindowHasNewCursor
+		 */
+		if (pOldCursor)
+		    FreeCursor (pOldCursor, (Cursor)0);
+	    }
+	    break;
+	 default:
+	    error = BadValue;
+	    client->errorValue = vmask;
+	    goto PatchUp;
+      }
+      vmaskCopy |= index2;
+    }
+PatchUp:
+    if (checkOptional)
+	CheckWindowOptionalNeed (pWin);
+
+	/* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+    /* 
+	If the border contents have changed, redraw the border. 
+	Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+	for the tile to be rotated, and the correct function selected.
+    */
+    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+	&& pWin->viewable && HasBorder (pWin))
+    {
+	RegionRec exposed;
+
+	REGION_INIT(pScreen, &exposed, NullBox, 0);
+	REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+	(*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+	REGION_UNINIT(pScreen, &exposed);
+    }
+    return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ *    Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(pWin, client, wa)
+    register WindowPtr pWin;
+    ClientPtr client;
+    xGetWindowAttributesReply *wa;
+{
+    wa->type = X_Reply;
+    wa->bitGravity = pWin->bitGravity;
+    wa->winGravity = pWin->winGravity;
+    if (pWin->forcedBS && pWin->backingStore != Always)
+	wa->backingStore = NotUseful;
+    else
+	wa->backingStore = pWin->backingStore;
+    wa->length = (sizeof(xGetWindowAttributesReply) -
+		 sizeof(xGenericReply)) >> 2;
+    wa->sequenceNumber = client->sequence;
+    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
+    wa->backingPixel =  wBackingPixel (pWin);
+    wa->saveUnder = (BOOL)pWin->saveUnder;
+    wa->override = pWin->overrideRedirect;
+    if (!pWin->mapped)
+	wa->mapState = IsUnmapped;
+    else if (pWin->realized)
+	wa->mapState = IsViewable;
+    else
+	wa->mapState = IsUnviewable;
+
+    wa->colormap =  wColormap (pWin);
+    wa->mapInstalled = (wa->colormap == None) ? xFalse
+				: IsMapInstalled(wa->colormap, pWin);
+
+    wa->yourEventMask = EventMaskForClient(pWin, client);
+    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+    wa->doNotPropagateMask = wDontPropagateMask (pWin);
+    wa->class = pWin->drawable.class;
+    wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(pWin, pNextSib)
+    register WindowPtr pWin, pNextSib;
+{
+    register WindowPtr pParent = pWin->parent;
+    WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+    if (pWin->nextSib != pNextSib)
+    {
+	WindowPtr pOldNextSib = pWin->nextSib;
+
+	if (!pNextSib)	      /* move to bottom */
+	{
+	    if (pParent->firstChild == pWin)
+		pParent->firstChild = pWin->nextSib;
+	    /* if (pWin->nextSib) */	 /* is always True: pNextSib == NULL
+					  * and pWin->nextSib != pNextSib
+					  * therefore pWin->nextSib != NULL */
+	    pFirstChange = pWin->nextSib;
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pParent->lastChild->nextSib = pWin;
+	    pWin->prevSib = pParent->lastChild;
+	    pWin->nextSib = NullWindow;
+	    pParent->lastChild = pWin;
+	}
+	else if (pParent->firstChild == pNextSib) /* move to top */
+	{
+	    pFirstChange = pWin;
+	    if (pParent->lastChild == pWin)
+	       pParent->lastChild = pWin->prevSib;
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pParent->firstChild;
+	    pWin->prevSib = (WindowPtr ) NULL;
+	    pNextSib->prevSib = pWin;
+	    pParent->firstChild = pWin;
+	}
+	else			/* move in middle of list */
+	{
+	    WindowPtr pOldNext = pWin->nextSib;
+
+	    pFirstChange = NullWindow;
+	    if (pParent->firstChild == pWin)
+		pFirstChange = pParent->firstChild = pWin->nextSib;
+	    if (pParent->lastChild == pWin) {
+	       pFirstChange = pWin;
+	       pParent->lastChild = pWin->prevSib;
+	    }
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pNextSib;
+	    pWin->prevSib = pNextSib->prevSib;
+	    if (pNextSib->prevSib)
+		pNextSib->prevSib->nextSib = pWin;
+	    pNextSib->prevSib = pWin;
+	    if (!pFirstChange) {		     /* do we know it yet? */
+		pFirstChange = pParent->firstChild;  /* no, search from top */
+		while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+		     pFirstChange = pFirstChange->nextSib;
+	    }
+	}
+	if(pWin->drawable.pScreen->RestackWindow)
+	    (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+    }
+
+    return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (pWin)
+    register WindowPtr	 pWin;
+{
+    RegionPtr	pRgn;
+    BoxRec	box;
+
+    box.x1 = pWin->drawable.x;
+    box.y1 = pWin->drawable.y;
+    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	REGION_PTR(pScreen, pWin)
+
+	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+    }
+#endif
+    return pRgn;
+}
+
+void
+SetWinSize (pWin)
+    register WindowPtr pWin;
+{
+    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+			 pWin->drawable.x, pWin->drawable.y,
+			 (int)pWin->drawable.width,
+			 (int)pWin->drawable.height);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	REGION_PTR(pScreen, pWin)
+
+	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+			 pWin->drawable.y);
+    }
+#endif
+}
+
+void
+SetBorderSize (pWin)
+    register WindowPtr pWin;
+{
+    int	bw;
+
+    if (HasBorder (pWin)) {
+	bw = wBorderWidth (pWin);
+	ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+		pWin->drawable.x - bw, pWin->drawable.y - bw,
+		(int)(pWin->drawable.width + (bw<<1)),
+		(int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+	if (wBoundingShape (pWin)) {
+	    REGION_PTR(pScreen, pWin)
+
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+			     - pWin->drawable.y);
+	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+			     wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+			     pWin->drawable.y);
+	    REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+			 &pWin->winSize);
+	}
+#endif
+    } else {
+	REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+					       &pWin->winSize);
+    }
+}
+
+void
+GravityTranslate (x, y, oldx, oldy, dw, dh, gravity, destx, desty)
+    register int x, y;		/* new window position */
+    int		oldx, oldy;	/* old window position */
+    int		dw, dh;
+    unsigned	gravity;
+    register int *destx, *desty;	/* position relative to gravity */
+{
+    switch (gravity) {
+    case NorthGravity:
+	*destx = x + dw / 2;
+	*desty = y;
+	break;
+    case NorthEastGravity:
+	*destx = x + dw;
+	*desty = y;
+	break;
+    case WestGravity:
+	*destx = x;
+	*desty = y + dh / 2;
+	break;
+    case CenterGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh / 2;
+	break;
+    case EastGravity:
+	*destx = x + dw;
+	*desty = y + dh / 2;
+	break;
+    case SouthWestGravity:
+	*destx = x;
+	*desty = y + dh;
+	break;
+    case SouthGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh;
+	break;
+    case SouthEastGravity:
+	*destx = x + dw;
+	*desty = y + dh;
+	break;
+    case StaticGravity:
+	*destx = oldx;
+	*desty = oldy;
+	break;
+    default:
+	*destx = x;
+	*desty = y;
+	break;
+    }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(pWin, dx, dy, dw, dh)
+    register WindowPtr pWin;
+    int dx, dy, dw, dh;
+{
+    register ScreenPtr pScreen;
+    register WindowPtr pSib, pChild;
+    Bool resized = (dw || dh);
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+    {
+	if (resized && (pSib->winGravity > NorthWestGravity))
+	{
+	    int cwsx, cwsy;
+
+	    cwsx = pSib->origin.x;
+	    cwsy = pSib->origin.y;
+	    GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+			pSib->winGravity, &cwsx, &cwsy);
+	    if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+	    {
+		xEvent event;
+
+		event.u.u.type = GravityNotify;
+		event.u.gravity.window = pSib->drawable.id;
+		event.u.gravity.x = cwsx - wBorderWidth (pSib);
+		event.u.gravity.y = cwsy - wBorderWidth (pSib);
+		DeliverEvents (pSib, &event, 1, NullWindow);
+		pSib->origin.x = cwsx;
+		pSib->origin.y = cwsy;
+	    }
+	}
+	pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+	SetWinSize (pSib);
+	SetBorderSize (pSib);
+	(*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+
+	if ( (pChild = pSib->firstChild) )
+	{
+	    while (1)
+	    {
+		pChild->drawable.x = pChild->parent->drawable.x +
+				     pChild->origin.x;
+		pChild->drawable.y = pChild->parent->drawable.y +
+				     pChild->origin.y;
+		SetWinSize (pChild);
+		SetBorderSize (pChild);
+		(*pScreen->PositionWindow)(pChild,
+				    pChild->drawable.x, pChild->drawable.y);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+		while (!pChild->nextSib && (pChild != pSib))
+		    pChild = pChild->parent;
+		if (pChild == pSib)
+		    break;
+		pChild = pChild->nextSib;
+	    }
+	}
+    }
+}
+
+#define GET_INT16(m, f) \
+	if (m & mask) \
+	  { \
+	     f = (INT16) *pVlist;\
+	    pVlist++; \
+	 }
+#define GET_CARD16(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD16) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define GET_CARD8(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD8) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ *     returns Above if pSib above pMe in stack or Below otherwise 
+ */
+
+static int
+#if NeedFunctionPrototypes
+IsSiblingAboveMe(
+    register WindowPtr pMe,
+    register WindowPtr pSib)
+#else
+IsSiblingAboveMe(pMe, pSib)
+    register WindowPtr pMe, pSib;
+#endif
+{
+    register WindowPtr pWin;
+
+    pWin = pMe->parent->firstChild;
+    while (pWin)
+    {
+	if (pWin == pSib)
+	    return(Above);
+	else if (pWin == pMe)
+	    return(Below);
+	pWin = pWin->nextSib;
+    }
+    return(Below);
+}
+
+static BoxPtr
+#if NeedFunctionPrototypes
+WindowExtents(
+    register WindowPtr pWin,
+    register BoxPtr pBox)
+#else
+WindowExtents(pWin, pBox)
+    register WindowPtr pWin;
+    register BoxPtr pBox;
+#endif
+{
+    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+	       + wBorderWidth (pWin);
+    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+	       + wBorderWidth (pWin);
+    return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin)	(wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+#if NeedFunctionPrototypes
+MakeBoundingRegion (
+    register WindowPtr	pWin,
+    BoxPtr	pBox)
+#else
+MakeBoundingRegion (pWin, pBox)
+    register WindowPtr	pWin;
+    BoxPtr	pBox;
+#endif
+{
+    RegionPtr	pRgn;
+    REGION_PTR(pScreen, pWin)
+
+    pRgn = REGION_CREATE(pScreen, pBox, 1);
+    if (wBoundingShape (pWin)) {
+	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+						  -pWin->origin.y);
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+						  pWin->origin.y);
+    }
+    return pRgn;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+ShapeOverlap (
+    WindowPtr	pWin,
+    BoxPtr	pWinBox,
+    WindowPtr	pSib,
+    BoxPtr	pSibBox)
+#else
+ShapeOverlap (pWin, pWinBox, pSib, pSibBox)
+    WindowPtr	pWin, pSib;
+    BoxPtr	pWinBox, pSibBox;
+#endif
+{
+    RegionPtr	pWinRgn, pSibRgn;
+    register ScreenPtr	pScreen;
+    Bool	ret;
+
+    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+	return TRUE;
+    pScreen = pWin->drawable.pScreen;
+    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pSibRgn);
+    return ret;
+}
+#endif
+
+static Bool
+#if NeedFunctionPrototypes
+AnyWindowOverlapsMe(
+    WindowPtr pWin,
+    WindowPtr pHead,
+    register BoxPtr box)
+#else
+AnyWindowOverlapsMe(pWin, pHead, box)
+    WindowPtr pWin, pHead;
+    register BoxPtr box;
+#endif
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+static Bool
+#if NeedFunctionPrototypes
+IOverlapAnyWindow(
+    WindowPtr pWin,
+    register BoxPtr box)
+#else
+IOverlapAnyWindow(pWin, box)
+    WindowPtr pWin;
+    register BoxPtr box;
+#endif
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+/*
+ *   WhereDoIGoInTheStack() 
+ *	  Given pWin and pSib and the relationshipe smode, return
+ *	  the window that pWin should go ABOVE.
+ *	  If a pSib is specified:
+ *	      Above:  pWin is placed just above pSib
+ *	      Below:  pWin is placed just below pSib
+ *	      TopIf:  if pSib occludes pWin, then pWin is placed
+ *		      at the top of the stack
+ *	      BottomIf:	 if pWin occludes pSib, then pWin is 
+ *			 placed at the bottom of the stack
+ *	      Opposite: if pSib occludes pWin, then pWin is placed at the
+ *			top of the stack, else if pWin occludes pSib, then
+ *			pWin is placed at the bottom of the stack
+ *
+ *	  If pSib is NULL:
+ *	      Above:  pWin is placed at the top of the stack
+ *	      Below:  pWin is placed at the bottom of the stack
+ *	      TopIf:  if any sibling occludes pWin, then pWin is placed at
+ *		      the top of the stack
+ *	      BottomIf: if pWin occludes any sibline, then pWin is placed at
+ *			the bottom of the stack
+ *	      Opposite: if any sibling occludes pWin, then pWin is placed at
+ *			the top of the stack, else if pWin occludes any
+ *			sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+#if NeedFunctionPrototypes
+WhereDoIGoInTheStack(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    short x,
+    short y,
+    unsigned short w,
+    unsigned short h,
+    int smode)
+#else
+WhereDoIGoInTheStack(pWin, pSib, x, y, w, h, smode)
+    register WindowPtr pWin, pSib;
+    short x, y;
+    unsigned short w, h;
+    int smode;
+#endif
+{
+    BoxRec box;
+    register ScreenPtr pScreen;
+    WindowPtr pHead, pFirst;
+
+    if ((pWin == pWin->parent->firstChild) &&
+	(pWin == pWin->parent->lastChild))
+	return((WindowPtr ) NULL);
+    pHead = RealChildHead(pWin->parent);
+    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+    pScreen = pWin->drawable.pScreen;
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + (int)w;
+    box.y2 = y + (int)h;
+    switch (smode)
+    {
+      case Above:
+	if (pSib)
+	   return(pSib);
+	else if (pWin == pFirst)
+	    return(pWin->nextSib);
+	else
+	    return(pFirst);
+      case Below:
+	if (pSib)
+	    if (pSib->nextSib != pWin)
+		return(pSib->nextSib);
+	    else
+		return(pWin->nextSib);
+	else
+	    return NullWindow;
+      case TopIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return(pFirst);
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	    return(pFirst);
+	else
+	    return(pWin->nextSib);
+      case BottomIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return NullWindow;
+	    else
+		return(pWin->nextSib);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return(pWin->nextSib);
+      case Opposite:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+	    {
+		if (IsSiblingAboveMe(pWin, pSib) == Above)
+		    return(pFirst);
+		else
+		    return NullWindow;
+	    }
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	{
+	    /* If I'm occluded, I can't possibly be the first child
+	     * if (pWin == pWin->parent->firstChild)
+	     *	  return pWin->nextSib;
+	     */
+	    return(pFirst);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return pWin->nextSib;
+      default:
+      {
+	ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+	return pWin->nextSib;
+      }
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+ReflectStackChange(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    VTKind  kind)
+#else
+ReflectStackChange(pWin, pSib, kind)
+    register WindowPtr pWin, pSib;
+    VTKind  kind;
+#endif
+{
+/* Note that pSib might be NULL */
+
+    Bool WasViewable = (Bool)pWin->viewable;
+    WindowPtr pParent;
+    Bool anyMarked;
+    WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    /* if this is a root window, can't be restacked */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						      &pLayerWin);
+	if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(pWin, mask, vlist, client)
+    register WindowPtr pWin;
+    register Mask mask;
+    XID *vlist;
+    ClientPtr client;
+{
+#define RESTACK_WIN    0
+#define MOVE_WIN       1
+#define RESIZE_WIN     2
+#define REBORDER_WIN   3
+    register WindowPtr pSib = NullWindow;
+    register WindowPtr pParent = pWin->parent;
+    Window sibwid = 0;
+    Mask index2, tmask;
+    register XID *pVlist;
+    short x,   y, beforeX, beforeY;
+    unsigned short w = pWin->drawable.width,
+		   h = pWin->drawable.height,
+		   bw = pWin->borderWidth;
+    int action, smode = Above;
+#ifdef XAPPGROUP
+    ClientPtr win_owner;
+    ClientPtr ag_leader = NULL;
+#endif
+    xEvent event;
+
+    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+	return(BadMatch);
+
+    if ((mask & CWSibling) && !(mask & CWStackMode))
+	return(BadMatch);
+
+    pVlist = vlist;
+
+    if (pParent)
+    {
+	x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+	y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+    }
+    else
+    {
+	x = pWin->drawable.x;
+	y = pWin->drawable.y;
+    }
+    beforeX = x;
+    beforeY = y;
+    action = RESTACK_WIN;	
+    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	action = MOVE_WIN;
+    }
+	/* or should be resized */
+    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	GET_CARD16(CWWidth, w);
+	GET_CARD16 (CWHeight, h);
+	if (!w || !h)
+	{
+	    client->errorValue = 0;
+	    return BadValue;
+	}
+	action = RESIZE_WIN;
+    }
+    tmask = mask & ~ChangeMask;
+    while (tmask)
+    {
+	index2 = (Mask)lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBorderWidth:
+	    GET_CARD16(CWBorderWidth, bw);
+	    break;
+	  case CWSibling:
+	    sibwid = (Window ) *pVlist;
+	    pVlist++;
+	    pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+						RT_WINDOW, SecurityReadAccess);
+	    if (!pSib)
+	    {
+		client->errorValue = sibwid;
+		return(BadWindow);
+	    }
+	    if (pSib->parent != pParent)
+		return(BadMatch);
+	    if (pSib == pWin)
+		return(BadMatch);
+	    break;
+	  case CWStackMode:
+	    GET_CARD8(CWStackMode, smode);
+	    if ((smode != TopIf) && (smode != BottomIf) &&
+		(smode != Opposite) && (smode != Above) && (smode != Below))
+	    {
+		client->errorValue = smode;
+		return(BadValue);
+	    }
+	    break;
+	  default:
+	    client->errorValue = mask;
+	    return(BadValue);
+	}
+    }
+	/* root really can't be reconfigured, so just return */
+    if (!pParent)
+	return Success;
+
+	/* Figure out if the window should be moved.  Doesnt
+	   make the changes to the window if event sent */
+
+    if (mask & CWStackMode)
+	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+				    pParent->drawable.y + y,
+				    w + (bw << 1), h + (bw << 1), smode);
+    else
+	pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+    ag_leader = XagLeader (win_owner);
+#endif
+
+    if ((!pWin->overrideRedirect) && 
+	(RedirectSend(pParent)
+#ifdef XAPPGROUP
+	|| (win_owner->appgroup && ag_leader && 
+	    XagIsControlledRoot (client, pParent))
+#endif
+	))
+    {
+	event.u.u.type = ConfigureRequest;
+	event.u.configureRequest.window = pWin->drawable.id;
+	if (mask & CWSibling)
+	   event.u.configureRequest.sibling = sibwid;
+	else
+	    event.u.configureRequest.sibling = None;
+	if (mask & CWStackMode)
+	   event.u.u.detail = smode;
+	else
+	    event.u.u.detail = Above;
+	event.u.configureRequest.x = x;
+	event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+            event.u.configureRequest.x += panoramiXdataPtr[0].x;
+            event.u.configureRequest.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureRequest.width = w;
+	event.u.configureRequest.height = h;
+	event.u.configureRequest.borderWidth = bw;
+	event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+	/* make sure if the ag_leader maps the window it goes to the wm */
+	if (ag_leader && ag_leader != client && 
+	    XagIsControlledRoot (client, pParent)) {
+	    event.u.configureRequest.parent = XagId (win_owner);
+	    (void) TryClientEvents (ag_leader, &event, 1,
+				    NoEventMask, NoEventMask, NullGrab);
+	    return Success;
+	}
+#endif
+	event.u.configureRequest.parent = pParent->drawable.id;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+    if (action == RESIZE_WIN)
+    {
+	Bool size_change = (w != pWin->drawable.width)
+			|| (h != pWin->drawable.height);
+	if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+	{
+	    xEvent eventT;
+	    eventT.u.u.type = ResizeRequest;
+	    eventT.u.resizeRequest.window = pWin->drawable.id;
+	    eventT.u.resizeRequest.width = w;
+	    eventT.u.resizeRequest.height = h;
+	    if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+				       ResizeRedirectMask, client) == 1)
+	    {
+		/* if event is delivered, leave the actual size alone. */
+		w = pWin->drawable.width;
+		h = pWin->drawable.height;
+		size_change = FALSE;
+	    }
+	}
+	if (!size_change)
+	{
+	    if (mask & (CWX | CWY))
+		action = MOVE_WIN;
+	    else if (mask & (CWStackMode | CWBorderWidth))
+		action = RESTACK_WIN;
+	    else   /* really nothing to do */
+		return(Success) ;
+	}
+    }
+
+    if (action == RESIZE_WIN)
+	    /* we've already checked whether there's really a size change */
+	    goto ActuallyDoSomething;
+    if ((mask & CWX) && (x != beforeX))
+	    goto ActuallyDoSomething;
+    if ((mask & CWY) && (y != beforeY))
+	    goto ActuallyDoSomething;
+    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+	    goto ActuallyDoSomething;
+    if (mask & CWStackMode)
+    {
+	if (pWin->nextSib != pSib)
+	    goto ActuallyDoSomething;
+    }
+    return(Success);
+
+ActuallyDoSomething:
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = ConfigureNotify;
+	event.u.configureNotify.window = pWin->drawable.id;
+	if (pSib)
+	    event.u.configureNotify.aboveSibling = pSib->drawable.id;
+	else
+	    event.u.configureNotify.aboveSibling = None;
+	event.u.configureNotify.x = x;
+	event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+	    event.u.configureNotify.x += panoramiXdataPtr[0].x;
+            event.u.configureNotify.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureNotify.width = w;
+	event.u.configureNotify.height = h;
+	event.u.configureNotify.borderWidth = bw;
+	event.u.configureNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (mask & CWBorderWidth)
+    {
+	if (action == RESTACK_WIN)
+	{
+	    action = MOVE_WIN;
+	    pWin->borderWidth = bw;
+	}
+	else if ((action == MOVE_WIN) &&
+		 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+		 (beforeY + wBorderWidth (pWin) == y + (int)bw))
+	{
+	    action = REBORDER_WIN;
+	    (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+	}
+	else
+	    pWin->borderWidth = bw;
+    }
+    if (action == MOVE_WIN)
+	(*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+		   (mask & CWBorderWidth) ? VTOther : VTMove);
+    else if (action == RESIZE_WIN)
+	(*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+    else if (mask & CWStackMode)
+	ReflectStackChange(pWin, pSib, VTOther);
+
+    if (action != RESTACK_WIN)
+	CheckCursorConfinement(pWin);
+    return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ *    For RaiseLowest, raises the lowest mapped child (if any) that is
+ *    obscured by another child to the top of the stack.  For LowerHighest,
+ *    lowers the highest mapped child (if any) that is obscuring another
+ *    child to the bottom of the stack.	 Exposure processing is performed 
+ *
+ ******/
+
+int
+CirculateWindow(pParent, direction, client)
+    WindowPtr pParent;
+    int direction;
+    ClientPtr client;
+{
+    register WindowPtr pWin, pHead, pFirst;
+    xEvent event;
+    BoxRec box;
+
+    pHead = RealChildHead(pParent);
+    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+    if (direction == RaiseLowest)
+    {
+	for (pWin = pParent->lastChild;
+	     (pWin != pHead) &&
+	     !(pWin->mapped &&
+	       AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+	     pWin = pWin->prevSib) ;
+	if (pWin == pHead)
+	    return Success;
+    }
+    else
+    {
+	for (pWin = pFirst;
+	     pWin &&
+	     !(pWin->mapped &&
+	       IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+	     pWin = pWin->nextSib) ;
+	if (!pWin)
+	    return Success;
+    }
+
+    event.u.circulate.window = pWin->drawable.id;
+    event.u.circulate.parent = pParent->drawable.id;
+    event.u.circulate.event = pParent->drawable.id;
+    if (direction == RaiseLowest)
+	event.u.circulate.place = PlaceOnTop;
+    else
+	event.u.circulate.place = PlaceOnBottom;
+
+    if (RedirectSend(pParent))
+    {
+	event.u.u.type = CirculateRequest;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+
+    event.u.u.type = CirculateNotify;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+    ReflectStackChange(pWin,
+		       (direction == RaiseLowest) ? pFirst : NullWindow,
+		       VTStack);
+
+    return(Success);
+}
+
+static int
+#if NeedFunctionPrototypes
+CompareWIDs(
+    WindowPtr pWin,
+    pointer   value) /* must conform to VisitWindowProcPtr */
+#else
+CompareWIDs(pWin, value)
+    WindowPtr pWin;
+    pointer   value; /* must conform to VisitWindowProcPtr */
+#endif
+{
+    Window *wid = (Window *)value;
+
+    if (pWin->drawable.id == *wid)
+       return(WT_STOPWALKING);
+    else
+       return(WT_WALKCHILDREN);
+}
+
+/*****
+ *  ReparentWindow
+ *****/
+
+int
+ReparentWindow(pWin, pParent, x, y, client)
+    register WindowPtr pWin, pParent;
+    int x,y;
+    ClientPtr client;
+{
+    WindowPtr pPrev, pPriorParent;
+    Bool WasMapped = (Bool)(pWin->mapped);
+    xEvent event;
+    int bw = wBorderWidth (pWin);
+    register ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+	return(BadMatch);		
+    if (!MakeWindowOptional(pWin))
+	return(BadAlloc);
+
+    if (WasMapped)
+       UnmapWindow(pWin, FALSE);
+
+    event.u.u.type = ReparentNotify;
+    event.u.reparent.window = pWin->drawable.id;
+    event.u.reparent.parent = pParent->drawable.id;
+    event.u.reparent.x = x;
+    event.u.reparent.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && !pParent->parent) {
+	event.u.reparent.x += panoramiXdataPtr[0].x;
+	event.u.reparent.y += panoramiXdataPtr[0].y;
+    }
+#endif
+    event.u.reparent.override = pWin->overrideRedirect;
+    DeliverEvents(pWin, &event, 1, pParent);
+
+    /* take out of sibling chain */
+
+    pPriorParent = pPrev = pWin->parent;
+    if (pPrev->firstChild == pWin)
+	pPrev->firstChild = pWin->nextSib;
+    if (pPrev->lastChild == pWin)
+	pPrev->lastChild = pWin->prevSib;
+
+    if (pWin->nextSib)
+	pWin->nextSib->prevSib = pWin->prevSib;
+    if (pWin->prevSib)
+	pWin->prevSib->nextSib = pWin->nextSib;
+
+    /* insert at begining of pParent */
+    pWin->parent = pParent;
+    pPrev = RealChildHead(pParent);
+    if (pPrev)
+    {
+	pWin->nextSib = pPrev->nextSib;
+	if (pPrev->nextSib)
+	    pPrev->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pPrev->nextSib = pWin;
+	pWin->prevSib = pPrev;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	pWin->prevSib = NullWindow;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.x = x + bw + pParent->drawable.x;
+    pWin->drawable.y = y + bw + pParent->drawable.y;
+
+    /* clip to parent */
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    if (pScreen->ReparentWindow)
+	(*pScreen->ReparentWindow)(pWin, pPriorParent);
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    CheckWindowOptionalNeed(pWin);
+
+    if (WasMapped)
+	MapWindow(pWin, client);
+    RecalculateDeliverableEvents(pWin);
+    return(Success);
+}
+
+static void
+#if NeedFunctionPrototypes
+RealizeTree(WindowPtr pWin)
+#else
+RealizeTree(pWin)
+    WindowPtr pWin;
+#endif
+{
+    register WindowPtr pChild;
+    RealizeWindowProcPtr Realize;
+
+    Realize = pWin->drawable.pScreen->RealizeWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->mapped)
+	{
+	    pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder)
+		deltaSaveUndersViewable++;
+#endif
+	    pChild->viewable = (pChild->drawable.class == InputOutput);
+	    (* Realize)(pChild);
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * MapWindow
+ *    If some other client has selected SubStructureReDirect on the parent
+ *    and override-redirect is xFalse, then a MapRequest event is generated,
+ *    but the window remains unmapped.	Otherwise, the window is mapped and a
+ *    MapNotify event is generated.
+ *****/
+
+int
+MapWindow(pWin, client)
+    register WindowPtr pWin;
+    ClientPtr client;
+{
+    register ScreenPtr pScreen;
+
+    register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    if (pWin->mapped)
+	return(Success);
+
+#ifdef XCSECURITY
+    /*  don't let an untrusted client map a child-of-trusted-window, InputOnly
+     *  window; too easy to steal device input
+     */
+    if ( (client->trustLevel != XSecurityClientTrusted) &&
+	 (pWin->drawable.class == InputOnly) &&
+	 (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+	 return Success;
+#endif	
+
+    pScreen = pWin->drawable.pScreen;
+    if ( (pParent = pWin->parent) )
+    {
+	xEvent event;
+	Bool anyMarked;
+#ifdef XAPPGROUP
+	ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+	ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+	if ((!pWin->overrideRedirect) && 
+	    (RedirectSend(pParent)
+#ifdef XAPPGROUP
+	    || (win_owner->appgroup && ag_leader &&
+		XagIsControlledRoot (client, pParent))
+#endif
+	))
+	{
+	    event.u.u.type = MapRequest;
+	    event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+	    /* make sure if the ag_leader maps the window it goes to the wm */
+	    if (ag_leader && ag_leader != client &&
+		XagIsControlledRoot (client, pParent)) {
+		event.u.mapRequest.parent = XagId (win_owner);
+		(void) TryClientEvents (ag_leader, &event, 1,
+					NoEventMask, NoEventMask, NullGrab);
+		return Success;
+	    }
+#endif
+	    event.u.mapRequest.parent = pParent->drawable.id;
+
+	    if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+		return(Success);
+	}
+
+	pWin->mapped = TRUE;
+	if (SubStrSend(pWin, pParent))
+	{
+	    event.u.u.type = MapNotify;
+	    event.u.mapNotify.window = pWin->drawable.id;
+	    event.u.mapNotify.override = pWin->overrideRedirect;
+	    DeliverEvents(pWin, &event, 1, NullWindow);
+	}
+
+	if (!pParent->realized)
+	    return(Success);
+	RealizeTree(pWin);
+	if (pWin->viewable)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+	    if (DO_SAVE_UNDERS(pWin))
+	    {
+		dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+#endif /* DO_SAVE_UNDERS */
+	    if (anyMarked)
+	    {
+		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+		(*pScreen->HandleExposures)(pLayerWin->parent);
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (dosave)
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+	}
+	WindowsRestructured ();
+    }
+    else
+    {
+	RegionRec   temp;
+
+	pWin->mapped = TRUE;
+	pWin->realized = TRUE;	   /* for roots */
+	pWin->viewable = pWin->drawable.class == InputOutput;
+	/* We SHOULD check for an error value here XXX */
+	(*pScreen->RealizeWindow)(pWin);
+	if (pScreen->ClipNotify)
+	    (*pScreen->ClipNotify) (pWin, 0, 0);
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+	REGION_INIT(pScreen, &temp, NullBox, 0);
+	REGION_COPY(pScreen, &temp, &pWin->clipList);
+	(*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+	REGION_UNINIT(pScreen, &temp);
+    }
+
+    return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ *    Performs a MapWindow all unmapped children of the window, in top
+ *    to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(pParent, client)
+    register WindowPtr pParent;
+    ClientPtr client;
+{
+    register WindowPtr	pWin;
+    WindowPtr		pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+    WindowPtr		pFirstSaveUndered = NullWindow;
+#endif
+    register ScreenPtr	pScreen;
+    register Mask	parentRedirect;
+    register Mask	parentNotify;
+    xEvent		event;
+    Bool		anyMarked;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr		pLayerWin;
+
+    pScreen = pParent->drawable.pScreen;
+    parentRedirect = RedirectSend(pParent);
+    parentNotify = SubSend(pParent);
+    anyMarked = FALSE;
+    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+    {
+	if (!pWin->mapped)
+	{
+	    if (parentRedirect && !pWin->overrideRedirect)
+	    {
+		event.u.u.type = MapRequest;
+		event.u.mapRequest.window = pWin->drawable.id;
+		event.u.mapRequest.parent = pParent->drawable.id;
+    
+		if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		    SubstructureRedirectMask, client) == 1)
+		    continue;
+	    }
+    
+	    pWin->mapped = TRUE;
+	    if (parentNotify || StrSend(pWin))
+	    {
+		event.u.u.type = MapNotify;
+		event.u.mapNotify.window = pWin->drawable.id;
+		event.u.mapNotify.override = pWin->overrideRedirect;
+		DeliverEvents(pWin, &event, 1, NullWindow);
+	    }
+    
+	    if (!pFirstMapped)
+		pFirstMapped = pWin;
+	    if (pParent->realized)
+	    {
+		RealizeTree(pWin);
+		if (pWin->viewable)
+		{
+		    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							(WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave = TRUE;
+		    }
+#endif /* DO_SAVE_UNDERS */
+		}
+	    }
+	}
+    }
+
+    if (pFirstMapped)
+    {
+	pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+	if (pLayerWin->parent != pParent) {
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+							   pLayerWin,
+							   (WindowPtr *)NULL);
+	    pFirstMapped = pLayerWin;
+	}
+        if (anyMarked)
+        {
+#ifdef DO_SAVE_UNDERS
+	    if (pLayerWin->parent != pParent)
+	    {
+		if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+		{
+		    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+							 pLayerWin);
+		}
+	    }
+	    else if (dosave)
+	    {
+		dosave = FALSE;
+		for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+		{
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+							      pWin->nextSib);
+			if (dosave && !pFirstSaveUndered)
+			    pFirstSaveUndered = pWin;
+		    }
+		}
+            }
+#endif /* DO_SAVE_UNDERS */
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+        if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin,
+					    pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+        if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+					 VTMap);
+        WindowsRestructured ();
+    }
+}
+
+static void
+#if NeedFunctionPrototypes
+UnrealizeTree(
+    WindowPtr pWin,
+    Bool fromConfigure)
+#else
+UnrealizeTree(pWin, fromConfigure)
+    WindowPtr pWin;
+    Bool fromConfigure;
+#endif
+{
+    register WindowPtr pChild;
+    UnrealizeWindowProcPtr Unrealize;
+    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->realized)
+	{
+	    pChild->realized = FALSE;
+	    pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+		PanoramiXRes *win;
+		win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+							XRT_WINDOW);
+		if(win)
+		   win->u.win.visibility = VisibilityNotViewable;
+	    } 
+#endif
+	    (* Unrealize)(pChild);
+	    DeleteWindowFromAnyEvents(pChild, FALSE);
+	    if (pChild->viewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		if (pChild->saveUnder)
+		    deltaSaveUndersViewable--;
+#endif
+		pChild->viewable = FALSE;
+		if (pChild->backStorage)
+		    (*pChild->drawable.pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+		(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+		pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    }
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * UnmapWindow
+ *    If the window is already unmapped, this request has no effect.
+ *    Otherwise, the window is unmapped and an UnMapNotify event is
+ *    generated.  Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(pWin, fromConfigure)
+    register WindowPtr pWin;
+    Bool fromConfigure;
+{
+    register WindowPtr pParent;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+	return(Success);
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = UnmapNotify;
+	event.u.unmapNotify.window = pWin->drawable.id;
+	event.u.unmapNotify.fromConfigure = fromConfigure;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (wasViewable && !fromConfigure)
+    {
+	pWin->valdata = UnmapValData;
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+	(*pScreen->MarkWindow)(pLayerWin->parent);
+    }
+    pWin->mapped = FALSE;
+    if (wasRealized)
+	UnrealizeTree(pWin, fromConfigure);
+    if (wasViewable)
+    {
+	if (!fromConfigure)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+	    {
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+	}
+	pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+	if (!fromConfigure && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+    }
+    if (wasRealized && !fromConfigure)
+	WindowsRestructured ();
+    return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ *    Performs an UnmapWindow request with the specified mode on all mapped
+ *    children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(pWin)
+    register WindowPtr pWin;
+{
+    register WindowPtr pChild, pHead;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    Bool anyMarked = FALSE;
+    Mask parentNotify;
+    WindowPtr pLayerWin = NULL;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!pWin->firstChild)
+	return;
+    parentNotify = SubSend(pWin);
+    pHead = RealChildHead(pWin);
+
+    if (wasViewable)
+	pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+	if (pChild->mapped)
+	{
+	    if (parentNotify || StrSend(pChild))
+	    {
+		event.u.u.type = UnmapNotify;
+		event.u.unmapNotify.window = pChild->drawable.id;
+		event.u.unmapNotify.fromConfigure = xFalse;
+		DeliverEvents(pChild, &event, 1, NullWindow);
+	    }
+	    if (pChild->viewable)
+	    {
+		pChild->valdata = UnmapValData;
+		anyMarked = TRUE;
+	    }
+	    pChild->mapped = FALSE;
+	    if (pChild->realized)
+		UnrealizeTree(pChild, FALSE);
+	    if (wasViewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+		if (pChild->backStorage)
+		    (*pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+	    }
+	}
+    }
+    if (wasViewable)
+    {
+	if (anyMarked)
+	{
+	    if (pLayerWin->parent == pWin)
+		(*pScreen->MarkWindow)(pWin);
+	    else
+	    {
+		WindowPtr ptmp;
+                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						  (WindowPtr *)NULL);
+		(*pScreen->MarkWindow)(pLayerWin->parent);
+		
+		/* Windows between pWin and pLayerWin may not have been marked */
+		ptmp = pWin;
+ 
+		while (ptmp != pLayerWin->parent)
+		{
+		    (*pScreen->MarkWindow)(ptmp);
+		    ptmp = ptmp->parent;
+		}
+                pHead = pWin->firstChild;
+	    }
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+    }
+    if (wasRealized)
+	WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(client)
+    register ClientPtr client;
+{
+    register WindowPtr pParent, pWin;
+    register int j;
+
+    for (j=0; j<client->numSaved; j++)
+    {
+	pWin = (WindowPtr)client->saveSet[j];
+	pParent = pWin->parent;
+	while (pParent && (wClient (pParent) == client))
+	    pParent = pParent->parent;
+	if (pParent)
+	{
+	    if (pParent != pWin->parent)
+	    {
+		ReparentWindow(pWin, pParent,
+			       pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+			       pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+			       client);
+		if(!pWin->realized && pWin->mapped)
+		    pWin->mapped = FALSE;
+	    }
+	    MapWindow(pWin, client);
+	}
+    }
+    xfree(client->saveSet);
+    client->numSaved = 0;
+    client->saveSet = (pointer *)NULL;
+}
+
+Bool
+VisibleBoundingBoxFromPoint(pWin, x, y, box)
+    register WindowPtr pWin;
+    int x, y;	/* in root */
+    BoxPtr box;	  /* "return" value */
+{
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+	return(TRUE);
+    return(FALSE);
+}
+
+Bool
+PointInWindowIsVisible(pWin, x, y)
+    register WindowPtr pWin;
+    int x, y;	/* in root */
+{
+    BoxRec box;
+
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+						  x, y, &box))
+	return(TRUE);
+    return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(pWin)
+    register WindowPtr pWin;
+{
+    register ScreenPtr pScreen;
+    RegionPtr pReg;
+
+    pScreen = pWin->drawable.pScreen;
+    pReg = REGION_CREATE(pScreen, NullBox, 1);
+    if (pWin->parent ||
+	screenIsSaved != SCREEN_SAVER_ON ||
+	!HasSaverWindow (pWin->drawable.pScreen->myNum))
+    {
+	REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+    }
+    return(pReg);
+}
+
+void
+SendVisibilityNotify(pWin)
+    WindowPtr pWin;
+{
+    xEvent event;
+    unsigned int visibility = pWin->visibility;
+
+#ifdef PANORAMIX
+    /* This is not quite correct yet, but it's close */
+    if(!noPanoramiXExtension) {
+	PanoramiXRes *win;
+	WindowPtr pWin2;
+	int i, Scrnum;
+
+	Scrnum = pWin->drawable.pScreen->myNum;
+	
+	win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+	if(!win || (win->u.win.visibility == visibility))
+	    return;
+
+	switch(visibility) {
+	case VisibilityUnobscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+		if (pWin2) {
+		    if(pWin2->visibility == VisibilityPartiallyObscured)
+		   	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	case VisibilityPartiallyObscured:
+	    if(Scrnum) {
+	        pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+		if (pWin2) pWin = pWin2;
+	    }
+	    break;
+	case VisibilityFullyObscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+		
+		if (pWin2) {
+		    if(pWin2->visibility != VisibilityFullyObscured)
+		    	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	}
+	
+	win->u.win.visibility = visibility;
+    }
+#endif
+
+    event.u.u.type = VisibilityNotify;
+    event.u.visibility.window = pWin->drawable.id;
+    event.u.visibility.state = visibility;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+#if NeedFunctionPrototypes
+    WindowPtr /*pWin*/
+#endif
+);
+#endif
+
+void
+SaveScreens(on, mode)
+    int on;
+    int mode;
+{
+    int i;
+    int what;
+    int type;
+
+    if (on == SCREEN_SAVER_FORCER)
+    {
+	UpdateCurrentTimeIf();
+	lastDeviceEventTime = currentTime;
+	if (mode == ScreenSaverReset)
+	    what = SCREEN_SAVER_OFF;
+	else
+	    what = SCREEN_SAVER_ON;
+	type = what;
+    }
+    else
+    {
+	what = on;
+	type = what;
+	if (what == screenIsSaved)
+	    type = SCREEN_SAVER_CYCLE;
+    }
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+	if (on == SCREEN_SAVER_FORCER)
+	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+	if (savedScreenInfo[i].ExternalScreenSaver)
+	{
+	    if ((*savedScreenInfo[i].ExternalScreenSaver)
+		(screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+		continue;
+	}
+	if (type == screenIsSaved)
+	    continue;
+	switch (type) {
+	case SCREEN_SAVER_OFF:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+	       (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						      what);
+	    }
+	    else if (HasSaverWindow (i))
+	    {
+		savedScreenInfo[i].pWindow = NullWindow;
+		FreeResource(savedScreenInfo[i].wid, RT_NONE);
+	    }
+	    break;
+	case SCREEN_SAVER_CYCLE:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+	    {
+		WindowPtr pWin = savedScreenInfo[i].pWindow;
+		/* make it look like screen saver is off, so that
+		 * NotClippedByChildren will compute a clip list
+		 * for the root window, so miPaintWindow works
+		 */
+		screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+		(*pWin->drawable.pScreen->MoveWindow)(pWin,
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    DrawLogo(pWin);
+#endif
+		screenIsSaved = SCREEN_SAVER_ON;
+	    }
+	    /*
+	     * Call the DDX saver in case it wants to do something
+	     * at cycle time
+	     */
+	    else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+		(* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						       type);
+	    }
+	    break;
+	case SCREEN_SAVER_ON:
+	    if (ScreenSaverBlanking != DontPreferBlanking)
+	    {
+		if ((* screenInfo.screens[i]->SaveScreen)
+		   (screenInfo.screens[i], what))
+		{
+		   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+		   continue;
+		}
+		if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		    TileScreenSaver(i, SCREEN_IS_BLACK))
+		{
+		    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+		    continue;
+		}
+	    }
+	    if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		TileScreenSaver(i, SCREEN_IS_TILED))
+	    {
+		savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+	    }
+	    else
+		savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+	    break;
+	}
+    }
+    screenIsSaved = what;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+TileScreenSaver(int i, int kind)
+#else
+TileScreenSaver(i, kind)
+    int i;
+    int	kind;
+#endif
+{
+    int j;
+    int result;
+    XID attributes[3];
+    Mask mask;
+    WindowPtr pWin;		
+    CursorMetricRec cm;
+    unsigned char *srcbits, *mskbits;
+    CursorPtr cursor;
+    XID	cursorID = 0;
+    int	attri;
+
+    mask = 0;
+    attri = 0;
+    switch (kind) {
+    case SCREEN_IS_TILED:
+	switch (WindowTable[i]->backgroundState) {
+	case BackgroundPixel:
+	    attributes[attri++] = WindowTable[i]->background.pixel;
+	    mask |= CWBackPixel;
+	    break;
+	case BackgroundPixmap:
+	    attributes[attri++] = None;
+	    mask |= CWBackPixmap;
+	    break;
+	default:
+	    break;
+	}
+	break;
+    case SCREEN_IS_BLACK:
+	attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+	mask |= CWBackPixel;
+	break;
+    }
+    mask |= CWOverrideRedirect;
+    attributes[attri++] = xTrue;
+
+    /*
+     * create a blank cursor
+     */
+
+    cm.width=16;
+    cm.height=16;
+    cm.xhot=8;
+    cm.yhot=8;
+    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    if (!srcbits || !mskbits)
+    {
+	xfree(srcbits);
+	xfree(mskbits);
+	cursor = 0;
+    }
+    else
+    {
+	for (j=0; j<BitmapBytePad(32)*16; j++)
+	    srcbits[j] = mskbits[j] = 0x0;
+	cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+	if (cursor)
+	{
+	    cursorID = FakeClientID(0);
+	    if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+	    {
+		attributes[attri] = cursorID;
+		mask |= CWCursor;
+	    }
+	    else
+		cursor = 0;
+	}
+	else
+	{
+	    xfree (srcbits);
+	    xfree (mskbits);
+	}
+    }
+
+    pWin = savedScreenInfo[i].pWindow =
+	 CreateWindow(savedScreenInfo[i].wid,
+	      WindowTable[i],
+	      -RANDOM_WIDTH, -RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+	      0, InputOutput, mask, attributes, 0, serverClient,
+	      wVisual (WindowTable[i]), &result);
+
+    if (cursor)
+	FreeResource (cursorID, RT_NONE);
+
+    if (!pWin)
+	return FALSE;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW,
+		     (pointer)savedScreenInfo[i].pWindow))
+	return FALSE;
+
+    if (mask & CWBackPixmap)
+    {
+	MakeRootTile (pWin);
+	(*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+    }
+    MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+    if (kind == SCREEN_IS_TILED && logoScreenSaver)
+	DrawLogo(pWin);
+#endif
+    return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure.  Assumptions:	 some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (w)
+    register WindowPtr w;
+{
+    do
+	w = w->parent;
+    while (!w->optional);
+    return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules.	 If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (w)
+    register WindowPtr w;
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (!w->parent)
+	return;
+    optional = w->optional;
+    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+	return;
+    if (optional->otherEventMasks != 0)
+	return;
+    if (optional->otherClients != NULL)
+	return;
+    if (optional->passiveGrabs != NULL)
+	return;
+    if (optional->userProps != NULL)
+	return;
+    if (optional->backingBitPlanes != ~0L)
+	return;
+    if (optional->backingPixel != 0)
+	return;
+#ifdef SHAPE
+    if (optional->boundingShape != NULL)
+	return;
+    if (optional->clipShape != NULL)
+	return;
+#endif
+#ifdef XINPUT
+    if (optional->inputMasks != NULL)
+	return;
+#endif
+    parentOptional = FindWindowWithOptional(w)->optional;
+    if (optional->visual != parentOptional->visual)
+	return;
+    if (optional->cursor != None &&
+	(optional->cursor != parentOptional->cursor ||
+	 w->parent->cursorIsNone))
+	return;
+    if (optional->colormap != parentOptional->colormap)
+	return;
+    DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (pWin)
+    register WindowPtr pWin;
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (pWin->optional)
+	return TRUE;
+    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+    if (!optional)
+	return FALSE;
+    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+    optional->otherEventMasks = 0;
+    optional->otherClients = NULL;
+    optional->passiveGrabs = NULL;
+    optional->userProps = NULL;
+    optional->backingBitPlanes = ~0L;
+    optional->backingPixel = 0;
+#ifdef SHAPE
+    optional->boundingShape = NULL;
+    optional->clipShape = NULL;
+#endif
+#ifdef XINPUT
+    optional->inputMasks = NULL;
+#endif
+    parentOptional = FindWindowWithOptional(pWin)->optional;
+    optional->visual = parentOptional->visual;
+    if (!pWin->cursorIsNone)
+    {
+	optional->cursor = parentOptional->cursor;
+	optional->cursor->refcnt++;
+    }
+    else
+    {
+	optional->cursor = None;
+    }
+    optional->colormap = parentOptional->colormap;
+    pWin->optional = optional;
+    return TRUE;
+}
+
+void
+DisposeWindowOptional (pWin)
+    register WindowPtr pWin;
+{
+    if (!pWin->optional)
+	return;
+    /*
+     * everything is peachy.  Delete the optional record
+     * and clean up
+     */
+    /*
+     * TOG changed this code to:
+     *
+     *	    if (pWin->cursorIsNone == FALSE)
+     *		FreeCursor (pWin->optional->cursor, (Cursor)0);
+     *	    pWin->cursorIsNone = TRUE;
+     *
+     * This is blatently wrong; windows without optionals can have
+     * two different cursor values, either None or sharing their
+     * parents cursor.  This difference is controlled by the
+     * cursorIsNone value; when TRUE, the window has no cursor,
+     * when false, it shares its cursor with its parent; TOG
+     * made it impossible for a window to have a cursor without
+     * an optional record.
+     */
+    if (pWin->optional->cursor)
+    {
+	FreeCursor (pWin->optional->cursor, (Cursor)0);
+	pWin->cursorIsNone = FALSE;
+    }
+    else
+	pWin->cursorIsNone = TRUE;
+    xfree (pWin->optional);
+    pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+#if NeedFunctionPrototypes
+DrawLogo(WindowPtr pWin)
+#else
+DrawLogo(pWin)
+    WindowPtr pWin;
+#endif
+{
+    DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    int x, y;
+    unsigned int width, height, size;
+    GC *pGC;
+    int thin, gap, d31;
+    DDXPointRec poly[4];
+    ChangeGCVal fore[2], back[2];
+    xrgb rgb[2];
+    BITS32 fmask, bmask;
+    ColormapPtr cmap;
+
+    pDraw = (DrawablePtr)pWin;
+    pScreen = pDraw->pScreen;
+    x = -pWin->origin.x;
+    y = -pWin->origin.y;
+    width = pScreen->width;
+    height = pScreen->height;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pGC)
+	return;
+
+    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+	fore[0].val = pScreen->whitePixel;
+    else
+	fore[0].val = pScreen->blackPixel;
+    if ((pWin->backgroundState == BackgroundPixel) &&
+	(cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+	Pixel querypixels[2];
+
+	querypixels[0] = fore[0].val;
+	querypixels[1] = pWin->background.pixel;
+	QueryColors(cmap, 2, querypixels, rgb);
+	if ((rgb[0].red == rgb[1].red) &&
+	    (rgb[0].green == rgb[1].green) &&
+	    (rgb[0].blue == rgb[1].blue)) {
+	    if (fore[0].val == pScreen->blackPixel)
+		fore[0].val = pScreen->whitePixel;
+	    else
+		fore[0].val = pScreen->blackPixel;
+	}
+    }
+    fore[1].val = FillSolid;
+    fmask = GCForeground|GCFillStyle;
+    if (pWin->backgroundState == BackgroundPixel) {
+	back[0].val = pWin->background.pixel;
+	back[1].val = FillSolid;
+	bmask = GCForeground|GCFillStyle;
+    } else {
+	back[0].val = 0;
+	back[1].val = 0;
+	dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+		    NULL, back);
+	back[0].val = FillTiled;
+	back[1].ptr = pWin->background.pixmap;
+	bmask = GCFillStyle|GCTile;
+    }
+
+    /* should be the same as the reference function XmuDrawLogo() */
+
+    size = width;
+    if (height < width)
+	 size = height;
+    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+    size &= ~1;
+    x += rand() % (width - size);
+    y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ *           -----
+ *          /    /
+ *         /    /
+ *        /    /
+ *       /    /
+ *      /____/
+ *           d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+    thin = (size / 11);
+    if (thin < 1) thin = 1;
+    gap = (thin+3) / 4;
+    d31 = thin + thin + gap;
+    poly[0].x = x + size;	       poly[0].y = y;
+    poly[1].x = x + size-d31;	       poly[1].y = y;
+    poly[2].x = x + 0;		       poly[2].y = y + size;
+    poly[3].x = x + d31;	       poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ *           ------
+ *          /	  /
+ *         /  __ /
+ *        /  /	/
+ *       /  /  /
+ *      /__/__/
+ */
+
+    poly[0].x = x + d31/2;			 poly[0].y = y + size;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)+(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + d31;			 poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ *	     ------
+ *	    /  /  /
+ *	   /--/	 /
+ *	  /	/
+ *	 /     /
+ *	/_____/
+ */
+
+    poly[0].x = x + size - d31/2;		 poly[0].y = y;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)-(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + size - d31;			 poly[3].y = y;
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ *      b
+ * -----
+ * \	\
+ *  \	 \
+ *   \	  \
+ *    \	   \
+ *     \____\
+ */
+
+    poly[0].x = x;		       poly[0].y = y;
+    poly[1].x = x + size/4;	       poly[1].y = y;
+    poly[2].x = x + size;	       poly[2].y = y + size;
+    poly[3].x = x + size - size/4;     poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ *	    /
+ *	   /
+ *	  /
+ *	 /
+ *	/
+ */
+
+    poly[0].x = x + size- thin;	      poly[0].y = y;
+    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
+    poly[2].x = x + thin;	      poly[2].y = y + size;
+    poly[3].x = x + thin + gap;	      poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+    FreeScratchGC(pGC);
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
new file mode 100644
index 000000000..91dafb6c6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
@@ -0,0 +1,755 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/lib/Xrandr/Xrandr.c,v 1.13tsi Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation, Inc.
+ * Copyright © 2002 Hewlett Packard Company, 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 COMPAQ
+ * 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, HP.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+/* we need to be able to manipulate the Display structure on events */
+#include <X11/Xlibint.h>
+#include <X11/extensions/render.h>
+#include <X11/extensions/Xrender.h>
+
+#include "NXxrandrint.h"
+
+XExtensionInfo XRRExtensionInfo;
+char XRRExtensionName[] = RANDR_NAME;
+
+static Bool     XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
+static Status   XRREventToWire(Display *dpy, XEvent *event, xEvent *wire);
+
+static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window);
+
+static int
+XRRCloseDisplay (Display *dpy, XExtCodes *codes);
+
+static /* const */ XExtensionHooks rr_extension_hooks = {
+    NULL,				/* create_gc */
+    NULL,				/* copy_gc */
+    NULL,				/* flush_gc */
+    NULL,				/* free_gc */
+    NULL,				/* create_font */
+    NULL,				/* free_font */
+    XRRCloseDisplay,			/* close_display */
+    XRRWireToEvent,			/* wire_to_event */
+    XRREventToWire,			/* event_to_wire */
+    NULL,				/* error */
+    NULL,				/* error_string */
+};
+
+static Bool XRRWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
+{
+    XExtDisplayInfo *info = XRRFindDisplay(dpy);
+    XRRScreenChangeNotifyEvent *aevent;
+    xRRScreenChangeNotifyEvent *awire;
+
+    RRCheckExtension(dpy, info, False);
+
+    switch ((wire->u.u.type & 0x7F) - info->codes->first_event)
+    {
+      case RRScreenChangeNotify:
+	awire = (xRRScreenChangeNotifyEvent *) wire;
+	aevent = (XRRScreenChangeNotifyEvent *) event;
+	aevent->type = awire->type & 0x7F;
+	aevent->serial = _XSetLastRequestRead(dpy,
+					      (xGenericReply *) wire);
+	aevent->send_event = (awire->type & 0x80) != 0;
+	aevent->display = dpy;
+	aevent->window = awire->window;
+	aevent->root = awire->root;
+	aevent->timestamp = awire->timestamp;
+	aevent->config_timestamp = awire->configTimestamp;
+	aevent->size_index = awire->sizeID;
+	aevent->subpixel_order = awire->subpixelOrder;
+	aevent->rotation = awire->rotation;
+	aevent->width = awire->widthInPixels;
+	aevent->height = awire->heightInPixels;
+	aevent->mwidth = awire->widthInMillimeters;
+	aevent->mheight = awire->heightInMillimeters;
+	return True;
+    }
+
+    return False;
+}
+
+static Status XRREventToWire(Display *dpy, XEvent *event, xEvent *wire)
+{
+    XExtDisplayInfo *info = XRRFindDisplay(dpy);
+    XRRScreenChangeNotifyEvent *aevent;
+    xRRScreenChangeNotifyEvent *awire;
+
+    RRCheckExtension(dpy, info, False);
+
+    switch ((event->type & 0x7F) - info->codes->first_event)
+    {
+      case RRScreenChangeNotify:
+	awire = (xRRScreenChangeNotifyEvent *) wire;
+	aevent = (XRRScreenChangeNotifyEvent *) event;
+	awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
+	awire->rotation = (CARD8) aevent->rotation;
+	awire->sequenceNumber = aevent->serial & 0xFFFF;
+	awire->timestamp = aevent->timestamp;
+	awire->configTimestamp = aevent->config_timestamp;
+	awire->root = aevent->root;
+	awire->window = aevent->window;
+	awire->sizeID = aevent->size_index;
+	awire->subpixelOrder = aevent->subpixel_order;
+	awire->widthInPixels = aevent->width;
+	awire->heightInPixels = aevent->height;
+	awire->widthInMillimeters = aevent->mwidth;
+	awire->heightInMillimeters = aevent->mheight;
+	return True;
+    }
+    return False;
+}
+
+XExtDisplayInfo *
+XRRFindDisplay (Display *dpy)
+{
+    XExtDisplayInfo *dpyinfo;
+    XRandRInfo *xrri;
+    int i, numscreens;
+
+    dpyinfo = XextFindDisplay (&XRRExtensionInfo, dpy);
+    if (!dpyinfo) {
+	dpyinfo = XextAddDisplay (&XRRExtensionInfo, dpy, 
+				  XRRExtensionName,
+				  &rr_extension_hooks,
+				  RRNumberEvents, 0);
+	numscreens = ScreenCount(dpy);
+	xrri = Xmalloc (sizeof(XRandRInfo) + 
+				 sizeof(char *) * numscreens);
+	xrri->config = (XRRScreenConfiguration **)(xrri + 1);
+	for(i = 0; i < numscreens; i++) 
+	  xrri->config[i] = NULL;
+	xrri->major_version = -1;
+	dpyinfo->data = (char *) xrri;
+    }
+    return dpyinfo;
+}
+
+static int
+XRRCloseDisplay (Display *dpy, XExtCodes *codes)
+{
+    int i;
+    XRRScreenConfiguration **configs;
+    XExtDisplayInfo *info = XRRFindDisplay (dpy);
+    XRandRInfo *xrri;
+
+    LockDisplay(dpy);
+    /*
+     * free cached data
+     */
+    if (XextHasExtension(info)) {
+	xrri = (XRandRInfo *) info->data;
+	if (xrri) {
+	    configs = xrri->config;
+
+	    for (i = 0; i < ScreenCount(dpy); i++) {
+		if (configs[i] != NULL) XFree (configs[i]);
+	    }
+	    XFree (xrri);
+	}
+    }
+    UnlockDisplay(dpy);
+    return XextRemoveDisplay (&XRRExtensionInfo, dpy);
+}
+    
+
+Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation)
+{
+  *current_rotation = config->current_rotation;
+  return config->rotations;
+}
+
+XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes)
+{
+   *nsizes = config->nsizes;
+  return config->sizes;
+}
+
+short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates)
+{
+    short   *r = config->rates;
+    int	    nents = config->nrates;
+
+    /* Skip over the intervening rate lists */
+    while (sizeID > 0 && nents > 0)
+    {
+	int i = (*r + 1);
+	r += i;
+	nents -= i;
+	sizeID--;
+    }
+    if (!nents)
+    {
+	*nrates = 0;
+	return 0;
+    }
+    *nrates = (int) *r;
+    return r + 1;
+}
+
+Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp)
+{
+    *config_timestamp = config->config_timestamp;
+    return config->timestamp;
+}
+
+
+SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config, 
+			      Rotation *rotation)
+{
+    *rotation = (Rotation) config->current_rotation;
+    return (SizeID) config->current_size;
+}
+
+short XRRConfigCurrentRate (XRRScreenConfiguration *config)
+{
+    return config->current_rate;
+}
+
+/* 
+ * Go get the screen configuration data and salt it away for future use; 
+ * returns NULL if extension not supported
+ */
+static XRRScreenConfiguration *_XRRValidateCache (Display *dpy, int screen)
+{
+    XExtDisplayInfo *info = XRRFindDisplay (dpy);
+    XRRScreenConfiguration **configs;
+    XRandRInfo *xrri;
+
+    if (XextHasExtension(info)) {
+	xrri = (XRandRInfo *) info->data;
+	configs = xrri->config;
+
+	if (configs[screen] == NULL)
+	    configs[screen] = _XRRGetScreenInfo (dpy, RootWindow(dpy, screen));
+	return configs[screen];
+    } else {
+	return NULL;
+    }
+}
+
+/* given a screen, return the information from the (possibly) cached data */
+Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation)
+{
+  XRRScreenConfiguration *config;
+  Rotation cr;
+  LockDisplay(dpy);
+  if ((config = _XRRValidateCache(dpy, screen))) {
+    *current_rotation = config->current_rotation;
+    cr = config->rotations;
+    UnlockDisplay(dpy);
+    return cr;
+  }
+  else {
+    UnlockDisplay(dpy);
+    *current_rotation = RR_Rotate_0;
+    return 0;	/* no rotations supported */
+  }
+}
+
+/* given a screen, return the information from the (possibly) cached data */
+XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes)
+{
+  XRRScreenConfiguration *config; 
+  XRRScreenSize *sizes;
+
+  LockDisplay(dpy);
+  if ((config = _XRRValidateCache(dpy, screen))) {
+    *nsizes = config->nsizes;
+    sizes = config->sizes;
+    UnlockDisplay(dpy);
+    return sizes;
+    }
+  else {
+    UnlockDisplay(dpy);
+    *nsizes = 0;
+    return NULL;
+  }  
+}
+
+short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates)
+{
+  XRRScreenConfiguration *config; 
+  short *rates;
+
+  LockDisplay(dpy);
+  if ((config = _XRRValidateCache(dpy, screen))) {
+    rates = XRRConfigRates (config, sizeID, nrates);
+    UnlockDisplay(dpy);
+    return rates;
+    }
+  else {
+    UnlockDisplay(dpy);
+    *nrates = 0;
+    return NULL;
+  }  
+}
+
+/* given a screen, return the information from the (possibly) cached data */
+Time XRRTimes (Display *dpy, int screen, Time *config_timestamp)
+{
+  XRRScreenConfiguration *config; 
+  Time ts;
+
+  LockDisplay(dpy);
+  if ((config = _XRRValidateCache(dpy, screen))) {
+      *config_timestamp = config->config_timestamp;
+      ts = config->timestamp;
+      UnlockDisplay(dpy);
+      return ts;
+    } else {
+      UnlockDisplay(dpy);
+	return CurrentTime;
+    }
+}
+
+int XRRRootToScreen(Display *dpy, Window root)
+{
+  int snum;
+  for (snum = 0; snum < ScreenCount(dpy); snum++) {
+    if (RootWindow(dpy, snum) == root) return snum;
+  }
+  return -1;
+}
+
+
+Bool XRRQueryExtension (Display *dpy, int *event_basep, int *error_basep)
+{
+  XExtDisplayInfo *info = XRRFindDisplay (dpy);
+
+    if (XextHasExtension(info)) {
+	*event_basep = info->codes->first_event;
+	*error_basep = info->codes->first_error;
+	return True;
+    } else {
+	return False;
+    }
+}
+
+static Bool
+_XRRHasRates (int major, int minor)
+{
+    return major > 1 || (major == 1 && minor >= 1);
+}
+
+Status XRRQueryVersion (Display *dpy,
+			    int	    *major_versionp,
+			    int	    *minor_versionp)
+{
+    XExtDisplayInfo *info = XRRFindDisplay (dpy);
+    xRRQueryVersionReply rep;
+    xRRQueryVersionReq  *req;
+    XRandRInfo *xrri;
+
+    RRCheckExtension (dpy, info, 0);
+
+    xrri = (XRandRInfo *) info->data;
+
+    /* 
+     * only get the version information from the server if we don't have it already
+     */
+    if (xrri->major_version == -1) {
+      LockDisplay (dpy);
+      GetReq (RRQueryVersion, req);
+      req->reqType = info->codes->major_opcode;
+      req->randrReqType = X_RRQueryVersion;
+      req->majorVersion = RANDR_MAJOR;
+      req->minorVersion = RANDR_MINOR;
+      if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
+	UnlockDisplay (dpy);
+	SyncHandle ();
+	return 0;
+      }
+      xrri->major_version = rep.majorVersion;
+      xrri->minor_version = rep.minorVersion;
+      xrri->has_rates = _XRRHasRates (xrri->major_version, xrri->minor_version);
+    }
+    *major_versionp = xrri->major_version;
+    *minor_versionp = xrri->minor_version;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return 1;
+}
+
+typedef struct _randrVersionState {
+    unsigned long   version_seq;
+    Bool	    error;
+    int		    major_version;
+    int		    minor_version;
+} _XRRVersionState;
+
+static Bool
+_XRRVersionHandler (Display	    *dpy,
+			xReply	    *rep,
+			char	    *buf,
+			int	    len,
+			XPointer    data)
+{
+    xRRQueryVersionReply	replbuf;
+    xRRQueryVersionReply	*repl;
+    _XRRVersionState	*state = (_XRRVersionState *) data;
+
+    if (dpy->last_request_read != state->version_seq)
+	return False;
+    if (rep->generic.type == X_Error)
+    {
+	state->error = True;
+	return False;
+    }
+    repl = (xRRQueryVersionReply *)
+	_XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len,
+		     (SIZEOF(xRRQueryVersionReply) - SIZEOF(xReply)) >> 2,
+			True);
+    state->major_version = repl->majorVersion;
+    state->minor_version = repl->minorVersion;
+    return True;
+}
+/* need a version that does not hold the display lock */
+static XRRScreenConfiguration *_XRRGetScreenInfo (Display *dpy, Window window)
+{
+    XExtDisplayInfo *info = XRRFindDisplay(dpy);
+    xRRGetScreenInfoReply   rep;
+    xRRGetScreenInfoReq	    *req;
+    _XAsyncHandler 	    async;
+    _XRRVersionState	    async_state;
+    int			    nbytes, nbytesRead, rbytes;
+    int			    i;
+    xScreenSizes	    size;
+    struct _XRRScreenConfiguration  *scp;
+    XRRScreenSize	    *ssp;
+    short    		    *rates;
+    xRRQueryVersionReq      *vreq;
+    XRandRInfo		    *xrri;
+    Bool		    getting_version = False;
+
+    RRCheckExtension (dpy, info, 0);
+
+    xrri = (XRandRInfo *) info->data;
+
+    if (xrri->major_version == -1)
+    {
+	/* hide a version query in the request */
+	GetReq (RRQueryVersion, vreq);
+	vreq->reqType = info->codes->major_opcode;
+	vreq->randrReqType = X_RRQueryVersion;
+	vreq->majorVersion = RANDR_MAJOR;
+	vreq->minorVersion = RANDR_MINOR;
+    
+	async_state.version_seq = dpy->request;
+	async_state.error = False;
+	async.next = dpy->async_handlers;
+	async.handler = _XRRVersionHandler;
+	async.data = (XPointer) &async_state;
+	dpy->async_handlers = &async;
+
+	getting_version = True;
+    }
+
+    GetReq (RRGetScreenInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRGetScreenInfo;
+    req->window = window;
+
+    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
+    {
+	if (getting_version)
+	    DeqAsyncHandler (dpy, &async);
+	SyncHandle ();
+	return NULL;
+    }
+    if (getting_version)
+    {
+	DeqAsyncHandler (dpy, &async);
+	if (async_state.error)
+	{
+	  SyncHandle();
+	}
+	xrri->major_version = async_state.major_version;
+	xrri->minor_version = async_state.minor_version;
+	xrri->has_rates = _XRRHasRates (xrri->minor_version, xrri->major_version);
+    }
+
+    /*
+     * Make the reply compatible with v1.1
+     */
+    if (!xrri->has_rates)
+    {
+	rep.rate = 0;
+	rep.nrateEnts = 0;
+    }
+    
+    nbytes = (long) rep.length << 2;
+
+    nbytesRead = (long) (rep.nSizes * SIZEOF (xScreenSizes) +
+			 ((rep.nrateEnts + 1)& ~1) * 2 /* SIZEOF (CARD16) */);
+    
+    /* 
+     * first we must compute how much space to allocate for 
+     * randr library's use; we'll allocate the structures in a single
+     * allocation, on cleanlyness grounds.
+     */
+
+    rbytes = sizeof (XRRScreenConfiguration) +
+      (rep.nSizes * sizeof (XRRScreenSize) +
+       rep.nrateEnts * sizeof (int));
+
+    scp = (struct _XRRScreenConfiguration *) Xmalloc(rbytes);
+    if (scp == NULL) {
+	_XEatData (dpy, (unsigned long) nbytes);
+	SyncHandle ();
+	return NULL;
+    }
+
+
+    ssp = (XRRScreenSize *)(scp + 1);
+    rates = (short *) (ssp + rep.nSizes);
+
+    /* set up the screen configuration structure */
+    scp->screen = 
+      ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root));
+
+    scp->sizes = ssp;
+    scp->rates = rates;
+    scp->rotations = rep.setOfRotations;
+    scp->current_size = rep.sizeID;
+    scp->current_rate = rep.rate;
+    scp->current_rotation = rep.rotation;
+    scp->timestamp = rep.timestamp;
+    scp->config_timestamp = rep.configTimestamp;
+    scp->nsizes = rep.nSizes;
+    scp->nrates = rep.nrateEnts;
+
+    /*
+     * Time to unpack the data from the server.
+     */
+
+    /*
+     * First the size information
+     */
+    for (i = 0; i < rep.nSizes; i++)  {
+	_XReadPad (dpy, (char *) &size, SIZEOF (xScreenSizes));
+	
+        ssp[i].width = size.widthInPixels;
+	ssp[i].height = size.heightInPixels;
+	ssp[i].mwidth = size.widthInMillimeters;
+	ssp[i].mheight = size.heightInMillimeters;
+    }
+    /*
+     * And the rates
+     */
+    _XRead16Pad (dpy, rates, 2 /* SIZEOF (CARD16) */ * rep.nrateEnts);
+    
+    /*
+     * Skip any extra data
+     */
+    if (nbytes > nbytesRead)
+	_XEatData (dpy, (unsigned long) (nbytes - nbytesRead));
+    
+    return (XRRScreenConfiguration *)(scp);
+}
+
+XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy, Window window)
+{
+  XRRScreenConfiguration *config;
+  XRRFindDisplay(dpy);
+  LockDisplay (dpy);
+  config = _XRRGetScreenInfo(dpy, window);
+  UnlockDisplay (dpy);
+  SyncHandle ();
+  return config;
+}
+
+    
+void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config)
+{
+    Xfree (config);
+}
+
+
+/* 
+ * in protocol version 0.1, routine added to allow selecting for new events.
+ */
+
+void XRRSelectInput (Display *dpy, Window window, int mask)
+{
+    XExtDisplayInfo *info = XRRFindDisplay (dpy);
+    xRRSelectInputReq  *req;
+
+    RRSimpleCheckExtension (dpy, info);
+
+    LockDisplay (dpy);
+    GetReq (RRSelectInput, req);
+    req->reqType = info->codes->major_opcode;
+    req->randrReqType = X_RRSelectInput;
+    req->window = window;
+    req->enable = 0;
+    if (mask) req->enable = mask;
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return;
+}
+
+Status XRRSetScreenConfigAndRate (Display *dpy,
+				  XRRScreenConfiguration *config,
+				  Drawable draw,
+				  int size_index,
+				  Rotation rotation, 
+				  short rate,
+				  Time timestamp)
+{
+    XExtDisplayInfo *info = XRRFindDisplay (dpy);
+    xRRSetScreenConfigReply rep;
+    XRandRInfo *xrri;
+    int major, minor;
+
+    RRCheckExtension (dpy, info, 0);
+
+    /* Make sure has_rates is set */
+    if (!XRRQueryVersion (dpy, &major, &minor))
+	return 0;
+    
+    LockDisplay (dpy);
+    xrri = (XRandRInfo *) info->data;
+    if (xrri->has_rates)
+    {
+	xRRSetScreenConfigReq  *req;
+	GetReq (RRSetScreenConfig, req);
+	req->reqType = info->codes->major_opcode;
+	req->randrReqType = X_RRSetScreenConfig;
+	req->drawable = draw;
+	req->sizeID = size_index;
+	req->rotation = rotation;
+	req->timestamp = timestamp;
+	req->configTimestamp = config->config_timestamp;
+	req->rate = rate;
+    }
+    else
+    {
+	xRR1_0SetScreenConfigReq  *req;
+	GetReq (RR1_0SetScreenConfig, req);
+	req->reqType = info->codes->major_opcode;
+	req->randrReqType = X_RRSetScreenConfig;
+	req->drawable = draw;
+	req->sizeID = size_index;
+	req->rotation = rotation;
+	req->timestamp = timestamp;
+	req->configTimestamp = config->config_timestamp;
+    }
+    
+    (void) _XReply (dpy, (xReply *) &rep, 0, xTrue);
+
+    if (rep.status == RRSetConfigSuccess) {
+      /* if we succeed, set our view of reality to what we set it to */
+      config->config_timestamp = rep.newConfigTimestamp;
+      config->timestamp = rep.newTimestamp;
+      config->screen = ScreenOfDisplay (dpy, XRRRootToScreen(dpy, rep.root));
+      config->current_size = size_index;
+      config->current_rotation = rotation;
+    }
+    UnlockDisplay (dpy);
+    SyncHandle ();
+    return(rep.status);
+}
+
+Status XRRSetScreenConfig (Display *dpy,
+			   XRRScreenConfiguration *config,
+			   Drawable draw,
+			   int size_index,
+			   Rotation rotation, Time timestamp)
+{
+    return XRRSetScreenConfigAndRate (dpy, config, draw, size_index,
+				      rotation, 0, timestamp);
+}
+    
+int XRRUpdateConfiguration(XEvent *event)
+{
+    XRRScreenChangeNotifyEvent *scevent;
+    XConfigureEvent *rcevent;
+    Display *dpy = event->xany.display;
+    XExtDisplayInfo *info;
+    XRandRInfo *xrri;
+    int snum;
+
+    /* first, see if it is a vanilla configure notify event */
+    if (event->type == ConfigureNotify) {
+	rcevent = (XConfigureEvent *) event;
+	snum = XRRRootToScreen(dpy, rcevent->window);
+	dpy->screens[snum].width   = rcevent->width;
+	dpy->screens[snum].height  = rcevent->height;
+	return 1;
+    }
+
+    info = XRRFindDisplay(dpy);
+    RRCheckExtension (dpy, info, 0);
+
+    switch (event->type - info->codes->first_event) {
+    case RRScreenChangeNotify:
+	scevent = (XRRScreenChangeNotifyEvent *) event;
+	snum = XRRRootToScreen(dpy, 
+			       ((XRRScreenChangeNotifyEvent *) event)->root);
+	dpy->screens[snum].width   = scevent->width;
+	dpy->screens[snum].height  = scevent->height;
+	dpy->screens[snum].mwidth  = scevent->mwidth;
+	dpy->screens[snum].mheight = scevent->mheight;
+	XRenderSetSubpixelOrder (dpy, snum, scevent->subpixel_order);
+	break;
+    default:
+	return 0;
+    }
+    xrri = (XRandRInfo *) info->data;
+    /* 
+     * so the next time someone wants some data, it will be fetched; 
+     * it might be better to force the round trip immediately, but 
+     * I dislike pounding the server simultaneously when not necessary
+     */
+    if (xrri->config[snum] != NULL) {
+	XFree (xrri->config[snum]);
+	xrri->config[snum] = NULL;
+    }
+    return 1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
new file mode 100644
index 000000000..3fb504ea9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
@@ -0,0 +1,168 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/lib/Xrandr/Xrandr.h,v 1.9 2002/09/29 23:39:44 keithp Exp $
+ *
+ * Copyright © 2000 Compaq Computer Corporation, Inc.
+ * Copyright © 2002 Hewlett-Packard Company, 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 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 COMPAQ
+ * 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, HP.
+ */
+
+#ifndef _XRANDR_H_
+#define _XRANDR_H_
+
+#include <X11/extensions/randr.h>
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+    
+typedef struct {
+    int	width, height;
+    int	mwidth, mheight;
+} XRRScreenSize;
+
+/*
+ *  Events.
+ */
+
+typedef struct {
+    int type;			/* event base */
+    unsigned long serial;	/* # of last request processed by server */
+    Bool send_event;		/* true if this came from a SendEvent request */
+    Display *display;		/* Display the event was read from */
+    Window window;		/* window which selected for this event */
+    Window root;		/* Root window for changed screen */
+    Time timestamp;		/* when the screen change occurred */
+    Time config_timestamp;	/* when the last configuration change */
+    SizeID size_index;
+    SubpixelOrder subpixel_order;
+    Rotation rotation;
+    int width;
+    int height;
+    int mwidth;
+    int mheight;
+} XRRScreenChangeNotifyEvent;
+
+
+/* internal representation is private to the library */
+typedef struct _XRRScreenConfiguration XRRScreenConfiguration;	
+
+Bool XRRQueryExtension (Display *dpy, int *event_basep, int *error_basep);
+Status XRRQueryVersion (Display *dpy,
+			    int     *major_versionp,
+			    int     *minor_versionp);
+
+XRRScreenConfiguration *XRRGetScreenInfo (Display *dpy,
+					  Drawable draw);
+    
+void XRRFreeScreenConfigInfo (XRRScreenConfiguration *config);
+
+/* 
+ * Note that screen configuration changes are only permitted if the client can
+ * prove it has up to date configuration information.  We are trying to
+ * insist that it become possible for screens to change dynamically, so
+ * we want to ensure the client knows what it is talking about when requesting
+ * changes.
+ */
+Status XRRSetScreenConfig (Display *dpy, 
+			   XRRScreenConfiguration *config,
+			   Drawable draw,
+			   int size_index,
+			   Rotation rotation,
+			   Time timestamp);
+
+/* added in v1.1, sorry for the lame name */
+Status XRRSetScreenConfigAndRate (Display *dpy, 
+				  XRRScreenConfiguration *config,
+				  Drawable draw,
+				  int size_index,
+				  Rotation rotation,
+				  short rate,
+				  Time timestamp);
+
+
+Rotation XRRConfigRotations(XRRScreenConfiguration *config, Rotation *current_rotation);
+
+Time XRRConfigTimes (XRRScreenConfiguration *config, Time *config_timestamp);
+
+XRRScreenSize *XRRConfigSizes(XRRScreenConfiguration *config, int *nsizes);
+
+short *XRRConfigRates (XRRScreenConfiguration *config, int sizeID, int *nrates);
+
+SizeID XRRConfigCurrentConfiguration (XRRScreenConfiguration *config, 
+			      Rotation *rotation);
+    
+short XRRConfigCurrentRate (XRRScreenConfiguration *config);
+
+int XRRRootToScreen(Display *dpy, Window root);
+
+/* 
+ * returns the screen configuration for the specified screen; does a lazy
+ * evalution to delay getting the information, and caches the result.
+ * These routines should be used in preference to XRRGetScreenInfo
+ * to avoid unneeded round trips to the X server.  These are new
+ * in protocol version 0.1.
+ */
+
+
+XRRScreenConfiguration *XRRScreenConfig(Display *dpy, int screen);
+XRRScreenConfiguration *XRRConfig(Screen *screen);
+void XRRSelectInput(Display *dpy, Window window, int mask);
+
+/* 
+ * the following are always safe to call, even if RandR is not implemented 
+ * on a screen 
+ */
+
+
+Rotation XRRRotations(Display *dpy, int screen, Rotation *current_rotation);
+XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes);
+short *XRRRates (Display *dpy, int screen, int sizeID, int *nrates);
+Time XRRTimes (Display *dpy, int screen, Time *config_timestamp);
+
+
+/* 
+ * intended to take RRScreenChangeNotify,  or 
+ * ConfigureNotify (on the root window)
+ * returns 1 if it is an event type it understands, 0 if not
+ */
+int XRRUpdateConfiguration(XEvent *event);
+
+_XFUNCPROTOEND
+
+#endif /* _XRANDR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
new file mode 100644
index 000000000..33b05b1f0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
@@ -0,0 +1,104 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/lib/Xrandr/Xrandrint.h,v 1.2 2001/06/07 15:33:43 keithp 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.
+ */
+
+#ifndef _XRANDRINT_H_
+#define _XRANDRINT_H_
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <X11/extensions/randr.h>
+#include <X11/extensions/randrproto.h>
+#include "NXxrandr.h"
+
+extern XExtensionInfo XrandrExtensionInfo;
+extern char XrandrExtensionName[];
+
+#define RRCheckExtension(dpy,i,val) \
+  XextCheckExtension (dpy, i, XRRExtensionName, val)
+#define RRSimpleCheckExtension(dpy,i) \
+  XextSimpleCheckExtension (dpy, i, XRRExtensionName)
+
+XExtDisplayInfo *XRRFindDisplay (Display *dpy);
+
+
+/* deliberately opaque internal data structure; can be extended, 
+   but not reordered */
+struct _XRRScreenConfiguration {
+  Screen *screen;	/* the root window in GetScreenInfo */
+  XRRScreenSize *sizes;
+  Rotation rotations;
+  Rotation current_rotation;
+  int nsizes;
+  int current_size;
+  short current_rate;
+  Time timestamp;
+  Time config_timestamp;
+  int subpixel_order;	/* introduced in randr v0.1 */
+  short *rates;		/* introduced in randr v1.1 */
+  int nrates;
+};
+
+/*
+ * if a configure notify on the root is recieved, or
+ * an XRRScreenChangeNotify is recieved,
+ * XRRUpdateConfiguration should be called to update the X library's
+ * view of the screen configuration; it will also invalidate the cache
+ * provided by XRRScreenConfig and XRRConfig, and force a round trip
+ * when next used.  Returns invalid status if not an event type
+ * the library routine understand.
+ */
+ 
+/* we cache one screen configuration/screen */
+
+typedef struct _XRandRInfo {
+  XRRScreenConfiguration **config;
+  int major_version, minor_version;	/* major_version = -1 means we don't know */
+  Bool has_rates;			/* Server supports refresh rates */
+} XRandRInfo;
+
+#endif /* _XRANDRINT_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c
new file mode 100644
index 000000000..f3bfcf58a
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c
@@ -0,0 +1,2277 @@
+#ifdef NXAGENT_UPGRADE
+
+#if !defined(__sun) && !defined(__CYGWIN__)
+
+#include "X/NXxvdisp.c"
+
+#endif
+
+#else
+
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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/programs/Xserver/Xext/xvdisp.c,v 1.25 2001/11/18 23:55:48 mvojkovi Exp $ */
+
+/*
+** File: 
+**
+**   xvdisp.c --- Xv server extension dispatch module.
+**
+** Author: 
+**
+**   David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+**   11.06.91 Carver
+**     - changed SetPortControl to SetPortAttribute
+**     - changed GetPortControl to GetPortAttribute
+**     - changed QueryBestSize
+**
+**   15.05.91 Carver
+**     - version 2.0 upgrade
+**
+**   24.01.91 Carver
+**     - version 1.4 upgrade
+**
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+
+#include "Xv.h"
+#include "Xvproto.h"
+#include "xvdix.h"
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include "shmstr.h"
+#endif
+
+#include "Trap.h"
+
+#undef  TEST
+#undef  DEBUG
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+		ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+		ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#define _WriteQueryAdaptorsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
+
+#define _WriteQueryExtensionReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
+
+#define _WriteQueryEncodingsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
+
+#define _WriteAdaptorInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
+
+#define _WriteAttributeInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
+
+#define _WriteEncodingInfo(_c,_d) \
+  if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
+
+#define _WriteFormat(_c,_d) \
+  if ((_c)->swapped) SWriteFormat(_c, _d); \
+  else WriteToClient(_c, sz_xvFormat, (char*)_d)
+
+#define _WriteGrabPortReply(_c,_d) \
+  if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
+
+#define _WriteGetPortAttributeReply(_c,_d) \
+  if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
+
+#define _WriteQueryBestSizeReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
+
+#define _WriteQueryPortAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
+
+#define _WriteQueryImageAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
+
+#define _WriteListImageFormatsReply(_c,_d) \
+  if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
+
+#define _WriteImageFormatInfo(_c,_d) \
+  if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
+
+#define _AllocatePort(_i,_p) \
+  ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+    case xv_PutVideo:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutVideo(client)); break;
+        else
+#endif
+            result = (ProcXvPutVideo(client)); break;
+    case xv_PutStill:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutStill(client)); break
+        else
+#endif
+    	    result = (ProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (ProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvStopVideo(client)); break;
+	else
+#endif
+	    result = (ProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvSetPortAttribute(client)); break;
+	else
+#endif
+	    result = (ProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvShmPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest);  break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
+    case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
+    case xv_PutStill: result = (SProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (SProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage: result = (SProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest); break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+static int
+ProcXvQueryExtension(ClientPtr client)
+{
+  xvQueryExtensionReply rep;
+  /* REQUEST(xvQueryExtensionReq); */
+  REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.version = XvVersion;
+  rep.revision = XvRevision;
+
+  _WriteQueryExtensionReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvQueryAdaptors(ClientPtr client)
+{
+  xvFormat format;
+  xvAdaptorInfo ainfo;
+  xvQueryAdaptorsReply rep;
+  int totalSize;
+  int na;
+  XvAdaptorPtr pa;
+  int nf;
+  XvFormatPtr pf;
+  WindowPtr pWin;
+  ScreenPtr pScreen;
+  XvScreenPtr pxvs;
+
+  REQUEST(xvQueryAdaptorsReq);
+  REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+  if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+    {
+      client->errorValue = stuff->window;
+      return (BadWindow);
+    }
+
+  pScreen = pWin->drawable.pScreen;
+  pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+  if (!pxvs)
+    {
+      rep.type = X_Reply;
+      rep.sequenceNumber = client->sequence;
+      rep.num_adaptors = 0;
+      rep.length = 0;
+
+      _WriteQueryAdaptorsReply(client, &rep);
+
+      return Success;
+    }
+
+  (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_adaptors = pxvs->nAdaptors;
+
+  /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
+
+  totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
+
+  /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+      totalSize += (strlen(pa->name) + 3) & ~3;
+      totalSize += pa->nFormats * sz_xvFormat;
+      pa++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryAdaptorsReply(client, &rep);
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+
+      ainfo.base_id = pa->base_id;
+      ainfo.num_ports = pa->nPorts;
+      ainfo.type = pa->type;
+      ainfo.name_size = strlen(pa->name);
+      ainfo.num_formats = pa->nFormats;
+
+      _WriteAdaptorInfo(client, &ainfo);
+
+      WriteToClient(client, ainfo.name_size, pa->name);
+
+      nf = pa->nFormats;
+      pf = pa->pFormats;
+      while (nf--)
+	{
+	  format.depth = pf->depth;
+	  format.visual = pf->visual;
+	  _WriteFormat(client, &format);
+	  pf++;
+	}
+
+      pa++;
+
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+  xvEncodingInfo einfo;
+  xvQueryEncodingsReply rep;
+  int totalSize;
+  XvPortPtr pPort;
+  int ne;
+  XvEncodingPtr pe;
+  int status;
+
+  REQUEST(xvQueryEncodingsReq);
+  REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_encodings = pPort->pAdaptor->nEncodings;
+
+  /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  totalSize = ne * sz_xvEncodingInfo;
+  while (ne--)
+    {
+      totalSize += (strlen(pe->name) + 3) & ~3;
+      pe++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryEncodingsReply(client, &rep);
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  while (ne--) 
+    {
+      einfo.encoding = pe->id;
+      einfo.name_size = strlen(pe->name);
+      einfo.width = pe->width;
+      einfo.height = pe->height;
+      einfo.rate.numerator = pe->rate.numerator;
+      einfo.rate.denominator = pe->rate.denominator;
+      _WriteEncodingInfo(client, &einfo);
+      WriteToClient(client, einfo.name_size, pe->name);
+      pe++;
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutVideoReq);
+  REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvPutStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutStillReq);
+  REQUEST_SIZE_MATCH(xvPutStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetVideoReq);
+  REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetStillReq);
+  REQUEST_SIZE_MATCH(xvGetStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvSelectVideoNotify(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  REQUEST(xvSelectVideoNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+  if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadWindow);
+    }
+
+  return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSelectPortNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+  int result, status;
+  XvPortPtr pPort;
+  xvGrabPortReply rep;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result);
+
+  if (status != Success)
+    {
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.result = result;
+
+  _WriteGrabPortReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvUngrabPort(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+  int status;
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  REQUEST(xvStopVideoReq);
+  REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadDrawable);
+    }
+
+  return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diSetPortAttribute)(client, pPort, 
+				    stuff->attribute, stuff->value);
+
+  if (status == BadMatch) 
+      client->errorValue = stuff->attribute;
+  else
+      client->errorValue = stuff->value;
+
+  return status;
+}
+
+static int
+ProcXvGetPortAttribute(ClientPtr client)
+{
+  INT32 value;
+  int status;
+  XvPortPtr pPort;
+  xvGetPortAttributeReply rep;
+  REQUEST(xvGetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value);
+  if (status != Success)
+    {
+      client->errorValue = stuff->attribute;
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.value = value;
+ 
+  _WriteGetPortAttributeReply(client, &rep);
+
+  return Success;
+}
+
+static int
+ProcXvQueryBestSize(ClientPtr client)
+{
+  int status;
+  unsigned int actual_width, actual_height;
+  XvPortPtr pPort;
+  xvQueryBestSizeReply rep;
+  REQUEST(xvQueryBestSizeReq);
+  REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+
+  (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
+				       stuff->vid_w, stuff->vid_h, 
+				       stuff->drw_w, stuff->drw_h, 
+				       &actual_width, &actual_height);
+
+  rep.actual_width = actual_width;
+  rep.actual_height = actual_height;
+ 
+  _WriteQueryBestSizeReply(client, &rep);
+
+  return Success;
+}
+
+
+static int
+ProcXvQueryPortAttributes(ClientPtr client)
+{
+  int status, size, i;
+  XvPortPtr pPort;
+  XvAttributePtr pAtt;
+  xvQueryPortAttributesReply rep;
+  xvAttributeInfo Info;
+  REQUEST(xvQueryPortAttributesReq);
+  REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_attributes = pPort->pAdaptor->nAttributes;
+  rep.text_size = 0;
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {    
+      rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+  }
+
+  rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+  rep.length >>= 2;
+
+  _WriteQueryPortAttributesReply(client, &rep);
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {
+      size = strlen(pAtt->name) + 1;  /* pass the NULL */
+      Info.flags = pAtt->flags;
+      Info.min = pAtt->min_value;
+      Info.max = pAtt->max_value;
+      Info.size = (size + 3) & ~3L;
+
+      _WriteAttributeInfo(client, &Info);
+
+      WriteToClient(client, size, pAtt->name);
+  }
+
+  return Success;
+}
+
+
+
+static int 
+ProcXvPutImage(ClientPtr client)
+{
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, i, size;
+  CARD16 width, height;
+
+  REQUEST(xvPutImageReq);
+  REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  width = stuff->width;
+  height = stuff->height;
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  size += sizeof(xvPutImageReq);
+  size = (size + 3) >> 2;
+  
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+
+  if(client->req_len < size)
+     return BadLength;
+
+  return XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h,
+			    pImage, (unsigned char*)(&stuff[1]), FALSE,
+			    stuff->width, stuff->height);
+}
+
+#ifdef MITSHM
+/* redefined here since it's not in any header file */
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+extern RESTYPE ShmSegType;
+extern int BadShmSegCode;
+extern int ShmCompletionCode;
+
+static int 
+ProcXvShmPutImage(ClientPtr client)
+{
+  ShmDescPtr shmdesc;
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, size_needed, i;
+  CARD16 width, height;
+
+  REQUEST(xvShmPutImageReq);
+  REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) 
+    {
+      client->errorValue = stuff->shmseg;
+      return BadShmSegCode;  
+    }	
+ 
+  width = stuff->width;
+  height = stuff->height;
+  size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  if((size_needed + stuff->offset) > shmdesc->size)
+      return BadAccess;
+
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+     
+  status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h, pImage,
+			    (unsigned char *)shmdesc->addr + stuff->offset, 
+			    stuff->send_event, stuff->width, stuff->height);
+
+  if((status == Success) && stuff->send_event) {
+        xShmCompletionEvent ev;
+
+        ev.type = ShmCompletionCode;
+        ev.drawable = stuff->drawable;
+        ev.sequenceNumber = client->sequence;
+        ev.minorEvent = xv_ShmPutImage;
+        ev.majorEvent = XvReqCode;
+        ev.shmseg = stuff->shmseg;
+        ev.offset = stuff->offset;
+        WriteEventsToClient(client, 1, (xEvent *) &ev);
+  }
+
+  return status;
+}
+#endif
+
+#ifdef XvMCExtension
+XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id);
+#endif
+
+static int 
+ProcXvQueryImageAttributes(ClientPtr client)
+{
+  xvQueryImageAttributesReply rep;
+  int size, num_planes, i;
+  CARD16 width, height;
+  XvImagePtr pImage = NULL;
+  XvPortPtr pPort;
+  int *offsets;
+  int *pitches;
+  REQUEST(xvQueryImageAttributesReq);
+
+  REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+  
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+#ifdef XvMCExtension
+  if(!pImage)
+     pImage = XvMCFindXvImage(pPort, stuff->id);
+#endif
+
+  if(!pImage)
+     return BadMatch;
+
+  num_planes = pImage->num_planes;
+
+  if(!(offsets = xalloc(num_planes << 3)))
+	return BadAlloc;
+  pitches = offsets + num_planes;
+
+  width = stuff->width;
+  height = stuff->height;
+
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
+					&width, &height, offsets, pitches);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = num_planes << 1;
+  rep.num_planes = num_planes;
+  rep.width = width;
+  rep.height = height;
+  rep.data_size = size;
+ 
+  _WriteQueryImageAttributesReply(client, &rep);
+  if(client->swapped)
+    SwapLongs((CARD32*)offsets, rep.length);
+  WriteToClient(client, rep.length << 2, (char*)offsets);
+
+  xfree(offsets);
+
+  return Success;
+}
+
+static int 
+ProcXvListImageFormats(ClientPtr client)
+{
+  XvPortPtr pPort;
+  XvImagePtr pImage;
+  int i;
+  xvListImageFormatsReply rep;
+  xvImageFormatInfo info;
+  REQUEST(xvListImageFormatsReq);
+
+  REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_formats = pPort->pAdaptor->nImages;
+  rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+  _WriteListImageFormatsReply(client, &rep);
+
+  pImage = pPort->pAdaptor->pImages;
+  
+  for(i = 0; i < rep.num_formats; i++, pImage++) {
+     info.id = pImage->id; 	
+     info.type = pImage->type; 	
+     info.byte_order = pImage->byte_order; 
+     memcpy(&info.guid, pImage->guid, 16);	
+     info.bpp = pImage->bits_per_pixel; 	
+     info.num_planes = pImage->num_planes; 	
+     info.depth = pImage->depth; 	
+     info.red_mask = pImage->red_mask; 	
+     info.green_mask = pImage->green_mask; 	
+     info.blue_mask = pImage->blue_mask; 	
+     info.format = pImage->format; 	
+     info.y_sample_bits = pImage->y_sample_bits; 	
+     info.u_sample_bits = pImage->u_sample_bits; 	
+     info.v_sample_bits = pImage->v_sample_bits; 	
+     info.horz_y_period = pImage->horz_y_period; 	
+     info.horz_u_period = pImage->horz_u_period; 	
+     info.horz_v_period = pImage->horz_v_period; 	
+     info.vert_y_period = pImage->vert_y_period; 	
+     info.vert_u_period = pImage->vert_u_period; 	
+     info.vert_v_period = pImage->vert_v_period; 	
+     memcpy(&info.comp_order, pImage->component_order, 32);	
+     info.scanline_order = pImage->scanline_order;
+     _WriteImageFormatInfo(client, &info);
+  }  
+
+  return Success;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryExtensionReq);
+  swaps(&stuff->length, n);
+  return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryAdaptorsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->window, n);
+  return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryEncodingsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvUngrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvShmPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->shmseg, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->offset, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectVideoNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectPortNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvStopVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryBestSizeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryPortAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryImageAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->width, n);
+  return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvListImageFormatsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+   ClientPtr client,
+   xvQueryExtensionReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->version, n);
+  swaps(&rep->revision, n);
+  
+  (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryAdaptorsReply(
+   ClientPtr client,
+   xvQueryAdaptorsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_adaptors, n);
+  
+  (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryEncodingsReply(
+   ClientPtr client,
+   xvQueryEncodingsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_encodings, n);
+  
+  (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteAdaptorInfo(
+   ClientPtr client,
+   xvAdaptorInfo *pAdaptor
+){
+  register char n;
+
+  swapl(&pAdaptor->base_id, n);
+  swaps(&pAdaptor->name_size, n);
+  swaps(&pAdaptor->num_ports, n);
+  swaps(&pAdaptor->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
+
+  return Success;
+}
+
+static int
+SWriteEncodingInfo(
+   ClientPtr client,
+   xvEncodingInfo *pEncoding
+){
+  register char n;
+  
+  swapl(&pEncoding->encoding, n);
+  swaps(&pEncoding->name_size, n);
+  swaps(&pEncoding->width, n);
+  swaps(&pEncoding->height, n);
+  swapl(&pEncoding->rate.numerator, n);
+  swapl(&pEncoding->rate.denominator, n);
+  (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
+
+  return Success;
+}
+
+static int
+SWriteFormat(
+   ClientPtr client,
+   xvFormat *pFormat
+){
+  register char n;
+
+  swapl(&pFormat->visual, n);
+  (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+  return Success;
+}
+
+static int
+SWriteAttributeInfo(
+   ClientPtr client,
+   xvAttributeInfo *pAtt
+){
+  register char n;
+
+  swapl(&pAtt->flags, n);
+  swapl(&pAtt->size, n);
+  swapl(&pAtt->min, n);
+  swapl(&pAtt->max, n);
+  (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
+
+  return Success;
+}
+
+static int
+SWriteImageFormatInfo(
+   ClientPtr client,
+   xvImageFormatInfo *pImage
+){
+  register char n;
+
+  swapl(&pImage->id, n);
+  swapl(&pImage->red_mask, n);
+  swapl(&pImage->green_mask, n);
+  swapl(&pImage->blue_mask, n);
+  swapl(&pImage->y_sample_bits, n);
+  swapl(&pImage->u_sample_bits, n);
+  swapl(&pImage->v_sample_bits, n);
+  swapl(&pImage->horz_y_period, n);
+  swapl(&pImage->horz_u_period, n);
+  swapl(&pImage->horz_v_period, n);
+  swapl(&pImage->vert_y_period, n);
+  swapl(&pImage->vert_u_period, n);
+  swapl(&pImage->vert_v_period, n);
+
+  (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
+
+  return Success;
+}
+
+
+
+static int
+SWriteGrabPortReply(
+   ClientPtr client,
+   xvGrabPortReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+
+  (void)WriteToClient(client, sz_xvGrabPortReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteGetPortAttributeReply(
+   ClientPtr client,
+   xvGetPortAttributeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->value, n);
+
+  (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryBestSizeReply(
+   ClientPtr client,
+   xvQueryBestSizeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->actual_width, n);
+  swaps(&rep->actual_height, n);
+
+  (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryPortAttributesReply(
+   ClientPtr client,
+   xvQueryPortAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_attributes, n);
+  swapl(&rep->text_size, n);
+
+  (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryImageAttributesReply(
+   ClientPtr client,
+   xvQueryImageAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_planes, n);
+  swapl(&rep->data_size, n);
+  swaps(&rep->width, n);
+  swaps(&rep->height, n);
+
+  (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+
+static int
+SWriteListImageFormatsReply(
+   ClientPtr client,
+   xvListImageFormatsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+  return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+   int result = Success, i;
+   PanoramiXRes *draw, *port;
+   REQUEST(xvStopVideoReq);
+   REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+   if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+   if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+   FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   result = ProcXvStopVideo(client);
+     	}
+   }
+
+   return result;
+}
+
+static int
+XineramaXvSetPortAttribute(ClientPtr client)
+{
+    REQUEST(xvSetPortAttributeReq);
+    PanoramiXRes *port;
+    int result = Success, i;
+
+    REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->port = port->info[i].id;
+	   result = ProcXvSetPortAttribute(client);
+	}
+    }
+    return result;
+}
+
+
+#ifdef MITSHM
+static int 
+XineramaXvShmPutImage(ClientPtr client)
+{
+    REQUEST(xvShmPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool send_event = stuff->send_event;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+	   stuff->send_event = (send_event && !i) ? 1 : 0;
+
+	   result = ProcXvShmPutImage(client);
+	}
+    }
+    return result;
+}
+#endif
+
+static int 
+XineramaXvPutImage(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+		client, stuff->port, XvXRTPort, SecurityReadAccess)))
+	return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+
+	   result = ProcXvPutImage(client);
+	}
+    }
+    return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutVideo(client);
+        }
+    }
+    return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutStill(client);
+        }
+    }
+    return result;
+}
+
+
+void XineramifyXv(void)
+{
+   ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+   XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+   XvAdaptorPtr refAdapt, pAdapt;
+   XvAttributePtr pAttr;
+   XvScreenPtr xvsp;
+   Bool isOverlay, hasOverlay;
+   PanoramiXRes *port;
+   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   int i, j, k, l;
+
+   XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+   if(!xvsp0) return;
+   
+   for(i = 0; i < xvsp0->nAdaptors; i++) {
+      refAdapt = xvsp0->pAdaptors + i;
+
+      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+      
+      MatchingAdaptors[0] = refAdapt;
+   
+      if(!(refAdapt->type & XvInputMask)) continue;
+      
+      isOverlay = FALSE;
+      for(j = 0; j < refAdapt->nAttributes; j++) {
+         pAttr = refAdapt->pAttributes + j;
+         if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+	    isOverlay = TRUE;
+	    break;
+	 }
+      }
+   
+      for(j = 1; j < PanoramiXNumScreens; j++) {
+         pScreen = screenInfo.screens[j];
+	 xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+         /* Do not try to go on if xv is not supported on this screen */
+         if (xvsp==NULL) continue ;
+	 
+         /* if the adaptor has the same name it's a perfect match */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	   pAdapt = xvsp->pAdaptors + k;
+           if(!strcmp(refAdapt->name, pAdapt->name)) {
+	       MatchingAdaptors[j] = pAdapt;
+	       break;
+	   }
+         }
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* otherwise we only look for XvImage adaptors */
+	 if(!(refAdapt->type & XvImageMask)) continue;
+	 if(refAdapt->nImages <= 0) continue;
+	 
+	 /* prefer overlay/overlay non-overlay/non-overlay pairing */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      hasOverlay = FALSE;
+              for(l = 0; l < pAdapt->nAttributes; l++) {
+	         if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+		   hasOverlay = TRUE;
+		   break;
+		 }
+	      }
+	      if(isOverlay && hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+              else if(!isOverlay && !hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+	    }
+         }
+	 
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* but we'll take any XvImage pairing if we can get it */
+	 	 
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	    }
+         }
+      }
+
+      /* now create a resource for each port */
+      for(j = 0; j < refAdapt->nPorts; j++) {
+         if(!(port = xalloc(sizeof(PanoramiXRes))))
+	    break;
+	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
+	 AddResource(port->info[0].id, XvXRTPort, port);
+
+	 for(k = 1; k < PanoramiXNumScreens; k++) {
+	    if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 
+		port->info[k].id = MatchingAdaptors[k]->base_id + j;
+	    else
+		port->info[k].id = 0;
+	 } 
+      }
+   }
+}
+
+#endif
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.NX.original
new file mode 100644
index 000000000..f3bfcf58a
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.NX.original
@@ -0,0 +1,2277 @@
+#ifdef NXAGENT_UPGRADE
+
+#if !defined(__sun) && !defined(__CYGWIN__)
+
+#include "X/NXxvdisp.c"
+
+#endif
+
+#else
+
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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/programs/Xserver/Xext/xvdisp.c,v 1.25 2001/11/18 23:55:48 mvojkovi Exp $ */
+
+/*
+** File: 
+**
+**   xvdisp.c --- Xv server extension dispatch module.
+**
+** Author: 
+**
+**   David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+**   11.06.91 Carver
+**     - changed SetPortControl to SetPortAttribute
+**     - changed GetPortControl to GetPortAttribute
+**     - changed QueryBestSize
+**
+**   15.05.91 Carver
+**     - version 2.0 upgrade
+**
+**   24.01.91 Carver
+**     - version 1.4 upgrade
+**
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+
+#include "Xv.h"
+#include "Xvproto.h"
+#include "xvdix.h"
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include "shmstr.h"
+#endif
+
+#include "Trap.h"
+
+#undef  TEST
+#undef  DEBUG
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+		ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+		ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#define _WriteQueryAdaptorsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
+
+#define _WriteQueryExtensionReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
+
+#define _WriteQueryEncodingsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
+
+#define _WriteAdaptorInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
+
+#define _WriteAttributeInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
+
+#define _WriteEncodingInfo(_c,_d) \
+  if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
+
+#define _WriteFormat(_c,_d) \
+  if ((_c)->swapped) SWriteFormat(_c, _d); \
+  else WriteToClient(_c, sz_xvFormat, (char*)_d)
+
+#define _WriteGrabPortReply(_c,_d) \
+  if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
+
+#define _WriteGetPortAttributeReply(_c,_d) \
+  if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
+
+#define _WriteQueryBestSizeReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
+
+#define _WriteQueryPortAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
+
+#define _WriteQueryImageAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
+
+#define _WriteListImageFormatsReply(_c,_d) \
+  if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
+
+#define _WriteImageFormatInfo(_c,_d) \
+  if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
+
+#define _AllocatePort(_i,_p) \
+  ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+    case xv_PutVideo:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutVideo(client)); break;
+        else
+#endif
+            result = (ProcXvPutVideo(client)); break;
+    case xv_PutStill:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutStill(client)); break
+        else
+#endif
+    	    result = (ProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (ProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvStopVideo(client)); break;
+	else
+#endif
+	    result = (ProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvSetPortAttribute(client)); break;
+	else
+#endif
+	    result = (ProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvShmPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest);  break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
+    case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
+    case xv_PutStill: result = (SProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (SProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage: result = (SProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest); break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+static int
+ProcXvQueryExtension(ClientPtr client)
+{
+  xvQueryExtensionReply rep;
+  /* REQUEST(xvQueryExtensionReq); */
+  REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.version = XvVersion;
+  rep.revision = XvRevision;
+
+  _WriteQueryExtensionReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvQueryAdaptors(ClientPtr client)
+{
+  xvFormat format;
+  xvAdaptorInfo ainfo;
+  xvQueryAdaptorsReply rep;
+  int totalSize;
+  int na;
+  XvAdaptorPtr pa;
+  int nf;
+  XvFormatPtr pf;
+  WindowPtr pWin;
+  ScreenPtr pScreen;
+  XvScreenPtr pxvs;
+
+  REQUEST(xvQueryAdaptorsReq);
+  REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+  if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+    {
+      client->errorValue = stuff->window;
+      return (BadWindow);
+    }
+
+  pScreen = pWin->drawable.pScreen;
+  pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+  if (!pxvs)
+    {
+      rep.type = X_Reply;
+      rep.sequenceNumber = client->sequence;
+      rep.num_adaptors = 0;
+      rep.length = 0;
+
+      _WriteQueryAdaptorsReply(client, &rep);
+
+      return Success;
+    }
+
+  (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_adaptors = pxvs->nAdaptors;
+
+  /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
+
+  totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
+
+  /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+      totalSize += (strlen(pa->name) + 3) & ~3;
+      totalSize += pa->nFormats * sz_xvFormat;
+      pa++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryAdaptorsReply(client, &rep);
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+
+      ainfo.base_id = pa->base_id;
+      ainfo.num_ports = pa->nPorts;
+      ainfo.type = pa->type;
+      ainfo.name_size = strlen(pa->name);
+      ainfo.num_formats = pa->nFormats;
+
+      _WriteAdaptorInfo(client, &ainfo);
+
+      WriteToClient(client, ainfo.name_size, pa->name);
+
+      nf = pa->nFormats;
+      pf = pa->pFormats;
+      while (nf--)
+	{
+	  format.depth = pf->depth;
+	  format.visual = pf->visual;
+	  _WriteFormat(client, &format);
+	  pf++;
+	}
+
+      pa++;
+
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+  xvEncodingInfo einfo;
+  xvQueryEncodingsReply rep;
+  int totalSize;
+  XvPortPtr pPort;
+  int ne;
+  XvEncodingPtr pe;
+  int status;
+
+  REQUEST(xvQueryEncodingsReq);
+  REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_encodings = pPort->pAdaptor->nEncodings;
+
+  /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  totalSize = ne * sz_xvEncodingInfo;
+  while (ne--)
+    {
+      totalSize += (strlen(pe->name) + 3) & ~3;
+      pe++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryEncodingsReply(client, &rep);
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  while (ne--) 
+    {
+      einfo.encoding = pe->id;
+      einfo.name_size = strlen(pe->name);
+      einfo.width = pe->width;
+      einfo.height = pe->height;
+      einfo.rate.numerator = pe->rate.numerator;
+      einfo.rate.denominator = pe->rate.denominator;
+      _WriteEncodingInfo(client, &einfo);
+      WriteToClient(client, einfo.name_size, pe->name);
+      pe++;
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutVideoReq);
+  REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvPutStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutStillReq);
+  REQUEST_SIZE_MATCH(xvPutStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetVideoReq);
+  REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetStillReq);
+  REQUEST_SIZE_MATCH(xvGetStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvSelectVideoNotify(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  REQUEST(xvSelectVideoNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+  if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadWindow);
+    }
+
+  return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSelectPortNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+  int result, status;
+  XvPortPtr pPort;
+  xvGrabPortReply rep;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result);
+
+  if (status != Success)
+    {
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.result = result;
+
+  _WriteGrabPortReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvUngrabPort(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+  int status;
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  REQUEST(xvStopVideoReq);
+  REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadDrawable);
+    }
+
+  return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diSetPortAttribute)(client, pPort, 
+				    stuff->attribute, stuff->value);
+
+  if (status == BadMatch) 
+      client->errorValue = stuff->attribute;
+  else
+      client->errorValue = stuff->value;
+
+  return status;
+}
+
+static int
+ProcXvGetPortAttribute(ClientPtr client)
+{
+  INT32 value;
+  int status;
+  XvPortPtr pPort;
+  xvGetPortAttributeReply rep;
+  REQUEST(xvGetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value);
+  if (status != Success)
+    {
+      client->errorValue = stuff->attribute;
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.value = value;
+ 
+  _WriteGetPortAttributeReply(client, &rep);
+
+  return Success;
+}
+
+static int
+ProcXvQueryBestSize(ClientPtr client)
+{
+  int status;
+  unsigned int actual_width, actual_height;
+  XvPortPtr pPort;
+  xvQueryBestSizeReply rep;
+  REQUEST(xvQueryBestSizeReq);
+  REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+
+  (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
+				       stuff->vid_w, stuff->vid_h, 
+				       stuff->drw_w, stuff->drw_h, 
+				       &actual_width, &actual_height);
+
+  rep.actual_width = actual_width;
+  rep.actual_height = actual_height;
+ 
+  _WriteQueryBestSizeReply(client, &rep);
+
+  return Success;
+}
+
+
+static int
+ProcXvQueryPortAttributes(ClientPtr client)
+{
+  int status, size, i;
+  XvPortPtr pPort;
+  XvAttributePtr pAtt;
+  xvQueryPortAttributesReply rep;
+  xvAttributeInfo Info;
+  REQUEST(xvQueryPortAttributesReq);
+  REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_attributes = pPort->pAdaptor->nAttributes;
+  rep.text_size = 0;
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {    
+      rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+  }
+
+  rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+  rep.length >>= 2;
+
+  _WriteQueryPortAttributesReply(client, &rep);
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {
+      size = strlen(pAtt->name) + 1;  /* pass the NULL */
+      Info.flags = pAtt->flags;
+      Info.min = pAtt->min_value;
+      Info.max = pAtt->max_value;
+      Info.size = (size + 3) & ~3L;
+
+      _WriteAttributeInfo(client, &Info);
+
+      WriteToClient(client, size, pAtt->name);
+  }
+
+  return Success;
+}
+
+
+
+static int 
+ProcXvPutImage(ClientPtr client)
+{
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, i, size;
+  CARD16 width, height;
+
+  REQUEST(xvPutImageReq);
+  REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  width = stuff->width;
+  height = stuff->height;
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  size += sizeof(xvPutImageReq);
+  size = (size + 3) >> 2;
+  
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+
+  if(client->req_len < size)
+     return BadLength;
+
+  return XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h,
+			    pImage, (unsigned char*)(&stuff[1]), FALSE,
+			    stuff->width, stuff->height);
+}
+
+#ifdef MITSHM
+/* redefined here since it's not in any header file */
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+extern RESTYPE ShmSegType;
+extern int BadShmSegCode;
+extern int ShmCompletionCode;
+
+static int 
+ProcXvShmPutImage(ClientPtr client)
+{
+  ShmDescPtr shmdesc;
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, size_needed, i;
+  CARD16 width, height;
+
+  REQUEST(xvShmPutImageReq);
+  REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) 
+    {
+      client->errorValue = stuff->shmseg;
+      return BadShmSegCode;  
+    }	
+ 
+  width = stuff->width;
+  height = stuff->height;
+  size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  if((size_needed + stuff->offset) > shmdesc->size)
+      return BadAccess;
+
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+     
+  status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h, pImage,
+			    (unsigned char *)shmdesc->addr + stuff->offset, 
+			    stuff->send_event, stuff->width, stuff->height);
+
+  if((status == Success) && stuff->send_event) {
+        xShmCompletionEvent ev;
+
+        ev.type = ShmCompletionCode;
+        ev.drawable = stuff->drawable;
+        ev.sequenceNumber = client->sequence;
+        ev.minorEvent = xv_ShmPutImage;
+        ev.majorEvent = XvReqCode;
+        ev.shmseg = stuff->shmseg;
+        ev.offset = stuff->offset;
+        WriteEventsToClient(client, 1, (xEvent *) &ev);
+  }
+
+  return status;
+}
+#endif
+
+#ifdef XvMCExtension
+XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id);
+#endif
+
+static int 
+ProcXvQueryImageAttributes(ClientPtr client)
+{
+  xvQueryImageAttributesReply rep;
+  int size, num_planes, i;
+  CARD16 width, height;
+  XvImagePtr pImage = NULL;
+  XvPortPtr pPort;
+  int *offsets;
+  int *pitches;
+  REQUEST(xvQueryImageAttributesReq);
+
+  REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+  
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+#ifdef XvMCExtension
+  if(!pImage)
+     pImage = XvMCFindXvImage(pPort, stuff->id);
+#endif
+
+  if(!pImage)
+     return BadMatch;
+
+  num_planes = pImage->num_planes;
+
+  if(!(offsets = xalloc(num_planes << 3)))
+	return BadAlloc;
+  pitches = offsets + num_planes;
+
+  width = stuff->width;
+  height = stuff->height;
+
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
+					&width, &height, offsets, pitches);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = num_planes << 1;
+  rep.num_planes = num_planes;
+  rep.width = width;
+  rep.height = height;
+  rep.data_size = size;
+ 
+  _WriteQueryImageAttributesReply(client, &rep);
+  if(client->swapped)
+    SwapLongs((CARD32*)offsets, rep.length);
+  WriteToClient(client, rep.length << 2, (char*)offsets);
+
+  xfree(offsets);
+
+  return Success;
+}
+
+static int 
+ProcXvListImageFormats(ClientPtr client)
+{
+  XvPortPtr pPort;
+  XvImagePtr pImage;
+  int i;
+  xvListImageFormatsReply rep;
+  xvImageFormatInfo info;
+  REQUEST(xvListImageFormatsReq);
+
+  REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_formats = pPort->pAdaptor->nImages;
+  rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+  _WriteListImageFormatsReply(client, &rep);
+
+  pImage = pPort->pAdaptor->pImages;
+  
+  for(i = 0; i < rep.num_formats; i++, pImage++) {
+     info.id = pImage->id; 	
+     info.type = pImage->type; 	
+     info.byte_order = pImage->byte_order; 
+     memcpy(&info.guid, pImage->guid, 16);	
+     info.bpp = pImage->bits_per_pixel; 	
+     info.num_planes = pImage->num_planes; 	
+     info.depth = pImage->depth; 	
+     info.red_mask = pImage->red_mask; 	
+     info.green_mask = pImage->green_mask; 	
+     info.blue_mask = pImage->blue_mask; 	
+     info.format = pImage->format; 	
+     info.y_sample_bits = pImage->y_sample_bits; 	
+     info.u_sample_bits = pImage->u_sample_bits; 	
+     info.v_sample_bits = pImage->v_sample_bits; 	
+     info.horz_y_period = pImage->horz_y_period; 	
+     info.horz_u_period = pImage->horz_u_period; 	
+     info.horz_v_period = pImage->horz_v_period; 	
+     info.vert_y_period = pImage->vert_y_period; 	
+     info.vert_u_period = pImage->vert_u_period; 	
+     info.vert_v_period = pImage->vert_v_period; 	
+     memcpy(&info.comp_order, pImage->component_order, 32);	
+     info.scanline_order = pImage->scanline_order;
+     _WriteImageFormatInfo(client, &info);
+  }  
+
+  return Success;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryExtensionReq);
+  swaps(&stuff->length, n);
+  return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryAdaptorsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->window, n);
+  return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryEncodingsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvUngrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvShmPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->shmseg, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->offset, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectVideoNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectPortNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvStopVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryBestSizeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryPortAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryImageAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->width, n);
+  return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvListImageFormatsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+   ClientPtr client,
+   xvQueryExtensionReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->version, n);
+  swaps(&rep->revision, n);
+  
+  (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryAdaptorsReply(
+   ClientPtr client,
+   xvQueryAdaptorsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_adaptors, n);
+  
+  (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryEncodingsReply(
+   ClientPtr client,
+   xvQueryEncodingsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_encodings, n);
+  
+  (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteAdaptorInfo(
+   ClientPtr client,
+   xvAdaptorInfo *pAdaptor
+){
+  register char n;
+
+  swapl(&pAdaptor->base_id, n);
+  swaps(&pAdaptor->name_size, n);
+  swaps(&pAdaptor->num_ports, n);
+  swaps(&pAdaptor->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
+
+  return Success;
+}
+
+static int
+SWriteEncodingInfo(
+   ClientPtr client,
+   xvEncodingInfo *pEncoding
+){
+  register char n;
+  
+  swapl(&pEncoding->encoding, n);
+  swaps(&pEncoding->name_size, n);
+  swaps(&pEncoding->width, n);
+  swaps(&pEncoding->height, n);
+  swapl(&pEncoding->rate.numerator, n);
+  swapl(&pEncoding->rate.denominator, n);
+  (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
+
+  return Success;
+}
+
+static int
+SWriteFormat(
+   ClientPtr client,
+   xvFormat *pFormat
+){
+  register char n;
+
+  swapl(&pFormat->visual, n);
+  (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+  return Success;
+}
+
+static int
+SWriteAttributeInfo(
+   ClientPtr client,
+   xvAttributeInfo *pAtt
+){
+  register char n;
+
+  swapl(&pAtt->flags, n);
+  swapl(&pAtt->size, n);
+  swapl(&pAtt->min, n);
+  swapl(&pAtt->max, n);
+  (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
+
+  return Success;
+}
+
+static int
+SWriteImageFormatInfo(
+   ClientPtr client,
+   xvImageFormatInfo *pImage
+){
+  register char n;
+
+  swapl(&pImage->id, n);
+  swapl(&pImage->red_mask, n);
+  swapl(&pImage->green_mask, n);
+  swapl(&pImage->blue_mask, n);
+  swapl(&pImage->y_sample_bits, n);
+  swapl(&pImage->u_sample_bits, n);
+  swapl(&pImage->v_sample_bits, n);
+  swapl(&pImage->horz_y_period, n);
+  swapl(&pImage->horz_u_period, n);
+  swapl(&pImage->horz_v_period, n);
+  swapl(&pImage->vert_y_period, n);
+  swapl(&pImage->vert_u_period, n);
+  swapl(&pImage->vert_v_period, n);
+
+  (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
+
+  return Success;
+}
+
+
+
+static int
+SWriteGrabPortReply(
+   ClientPtr client,
+   xvGrabPortReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+
+  (void)WriteToClient(client, sz_xvGrabPortReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteGetPortAttributeReply(
+   ClientPtr client,
+   xvGetPortAttributeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->value, n);
+
+  (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryBestSizeReply(
+   ClientPtr client,
+   xvQueryBestSizeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->actual_width, n);
+  swaps(&rep->actual_height, n);
+
+  (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryPortAttributesReply(
+   ClientPtr client,
+   xvQueryPortAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_attributes, n);
+  swapl(&rep->text_size, n);
+
+  (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryImageAttributesReply(
+   ClientPtr client,
+   xvQueryImageAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_planes, n);
+  swapl(&rep->data_size, n);
+  swaps(&rep->width, n);
+  swaps(&rep->height, n);
+
+  (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+
+static int
+SWriteListImageFormatsReply(
+   ClientPtr client,
+   xvListImageFormatsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+  return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+   int result = Success, i;
+   PanoramiXRes *draw, *port;
+   REQUEST(xvStopVideoReq);
+   REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+   if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+   if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+   FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   result = ProcXvStopVideo(client);
+     	}
+   }
+
+   return result;
+}
+
+static int
+XineramaXvSetPortAttribute(ClientPtr client)
+{
+    REQUEST(xvSetPortAttributeReq);
+    PanoramiXRes *port;
+    int result = Success, i;
+
+    REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->port = port->info[i].id;
+	   result = ProcXvSetPortAttribute(client);
+	}
+    }
+    return result;
+}
+
+
+#ifdef MITSHM
+static int 
+XineramaXvShmPutImage(ClientPtr client)
+{
+    REQUEST(xvShmPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool send_event = stuff->send_event;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+	   stuff->send_event = (send_event && !i) ? 1 : 0;
+
+	   result = ProcXvShmPutImage(client);
+	}
+    }
+    return result;
+}
+#endif
+
+static int 
+XineramaXvPutImage(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+		client, stuff->port, XvXRTPort, SecurityReadAccess)))
+	return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+
+	   result = ProcXvPutImage(client);
+	}
+    }
+    return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutVideo(client);
+        }
+    }
+    return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutStill(client);
+        }
+    }
+    return result;
+}
+
+
+void XineramifyXv(void)
+{
+   ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+   XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+   XvAdaptorPtr refAdapt, pAdapt;
+   XvAttributePtr pAttr;
+   XvScreenPtr xvsp;
+   Bool isOverlay, hasOverlay;
+   PanoramiXRes *port;
+   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   int i, j, k, l;
+
+   XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+   if(!xvsp0) return;
+   
+   for(i = 0; i < xvsp0->nAdaptors; i++) {
+      refAdapt = xvsp0->pAdaptors + i;
+
+      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+      
+      MatchingAdaptors[0] = refAdapt;
+   
+      if(!(refAdapt->type & XvInputMask)) continue;
+      
+      isOverlay = FALSE;
+      for(j = 0; j < refAdapt->nAttributes; j++) {
+         pAttr = refAdapt->pAttributes + j;
+         if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+	    isOverlay = TRUE;
+	    break;
+	 }
+      }
+   
+      for(j = 1; j < PanoramiXNumScreens; j++) {
+         pScreen = screenInfo.screens[j];
+	 xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+         /* Do not try to go on if xv is not supported on this screen */
+         if (xvsp==NULL) continue ;
+	 
+         /* if the adaptor has the same name it's a perfect match */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	   pAdapt = xvsp->pAdaptors + k;
+           if(!strcmp(refAdapt->name, pAdapt->name)) {
+	       MatchingAdaptors[j] = pAdapt;
+	       break;
+	   }
+         }
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* otherwise we only look for XvImage adaptors */
+	 if(!(refAdapt->type & XvImageMask)) continue;
+	 if(refAdapt->nImages <= 0) continue;
+	 
+	 /* prefer overlay/overlay non-overlay/non-overlay pairing */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      hasOverlay = FALSE;
+              for(l = 0; l < pAdapt->nAttributes; l++) {
+	         if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+		   hasOverlay = TRUE;
+		   break;
+		 }
+	      }
+	      if(isOverlay && hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+              else if(!isOverlay && !hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+	    }
+         }
+	 
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* but we'll take any XvImage pairing if we can get it */
+	 	 
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	    }
+         }
+      }
+
+      /* now create a resource for each port */
+      for(j = 0; j < refAdapt->nPorts; j++) {
+         if(!(port = xalloc(sizeof(PanoramiXRes))))
+	    break;
+	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
+	 AddResource(port->info[0].id, XvXRTPort, port);
+
+	 for(k = 1; k < PanoramiXNumScreens; k++) {
+	    if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 
+		port->info[k].id = MatchingAdaptors[k]->base_id + j;
+	    else
+		port->info[k].id = 0;
+	 } 
+      }
+   }
+}
+
+#endif
+
+#endif /* #ifdef NXAGENT_UPGRADE */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.XF86.original
new file mode 100644
index 000000000..3d321e8ae
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxvdisp.c.XF86.original
@@ -0,0 +1,2214 @@
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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/programs/Xserver/Xext/xvdisp.c,v 1.25 2001/11/18 23:55:48 mvojkovi Exp $ */
+
+/*
+** File: 
+**
+**   xvdisp.c --- Xv server extension dispatch module.
+**
+** Author: 
+**
+**   David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+**   11.06.91 Carver
+**     - changed SetPortControl to SetPortAttribute
+**     - changed GetPortControl to GetPortAttribute
+**     - changed QueryBestSize
+**
+**   15.05.91 Carver
+**     - version 2.0 upgrade
+**
+**   24.01.91 Carver
+**     - version 1.4 upgrade
+**
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+
+#include "Xv.h"
+#include "Xvproto.h"
+#include "xvdix.h"
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include "shmstr.h"
+#endif
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+		ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+		ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#define _WriteQueryAdaptorsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
+
+#define _WriteQueryExtensionReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
+
+#define _WriteQueryEncodingsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
+
+#define _WriteAdaptorInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
+
+#define _WriteAttributeInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
+
+#define _WriteEncodingInfo(_c,_d) \
+  if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
+
+#define _WriteFormat(_c,_d) \
+  if ((_c)->swapped) SWriteFormat(_c, _d); \
+  else WriteToClient(_c, sz_xvFormat, (char*)_d)
+
+#define _WriteGrabPortReply(_c,_d) \
+  if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
+
+#define _WriteGetPortAttributeReply(_c,_d) \
+  if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
+
+#define _WriteQueryBestSizeReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
+
+#define _WriteQueryPortAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
+
+#define _WriteQueryImageAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
+
+#define _WriteListImageFormatsReply(_c,_d) \
+  if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
+
+#define _WriteImageFormatInfo(_c,_d) \
+  if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
+
+#define _AllocatePort(_i,_p) \
+  ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: return(ProcXvQueryExtension(client));
+    case xv_QueryAdaptors: return(ProcXvQueryAdaptors(client));
+    case xv_QueryEncodings: return(ProcXvQueryEncodings(client));
+    case xv_PutVideo:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            return(XineramaXvPutVideo(client));
+        else
+#endif
+            return(ProcXvPutVideo(client));
+    case xv_PutStill:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            return(XineramaXvPutStill(client));
+        else
+#endif
+    	    return(ProcXvPutStill(client));
+    case xv_GetVideo: return(ProcXvGetVideo(client));
+    case xv_GetStill: return(ProcXvGetStill(client));
+    case xv_GrabPort: return(ProcXvGrabPort(client));
+    case xv_UngrabPort: return(ProcXvUngrabPort(client));
+    case xv_SelectVideoNotify: return(ProcXvSelectVideoNotify(client));
+    case xv_SelectPortNotify: return(ProcXvSelectPortNotify(client));
+    case xv_StopVideo: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvStopVideo(client));
+	else
+#endif
+	    return(ProcXvStopVideo(client));
+    case xv_SetPortAttribute: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvSetPortAttribute(client));
+	else
+#endif
+	    return(ProcXvSetPortAttribute(client));
+    case xv_GetPortAttribute: return(ProcXvGetPortAttribute(client));
+    case xv_QueryBestSize: return(ProcXvQueryBestSize(client));
+    case xv_QueryPortAttributes: return(ProcXvQueryPortAttributes(client));
+    case xv_PutImage:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvPutImage(client));
+	else
+#endif
+	    return(ProcXvPutImage(client));
+#ifdef MITSHM
+    case xv_ShmPutImage: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvShmPutImage(client));
+	else
+#endif
+	    return(ProcXvShmPutImage(client));
+#endif
+    case xv_QueryImageAttributes: return(ProcXvQueryImageAttributes(client));
+    case xv_ListImageFormats: return(ProcXvListImageFormats(client));
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  return(BadImplementation);
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  return(BadRequest);
+	}
+    }
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: return(SProcXvQueryExtension(client));
+    case xv_QueryAdaptors: return(SProcXvQueryAdaptors(client));
+    case xv_QueryEncodings: return(SProcXvQueryEncodings(client));
+    case xv_PutVideo: return(SProcXvPutVideo(client));
+    case xv_PutStill: return(SProcXvPutStill(client));
+    case xv_GetVideo: return(SProcXvGetVideo(client));
+    case xv_GetStill: return(SProcXvGetStill(client));
+    case xv_GrabPort: return(SProcXvGrabPort(client));
+    case xv_UngrabPort: return(SProcXvUngrabPort(client));
+    case xv_SelectVideoNotify: return(SProcXvSelectVideoNotify(client));
+    case xv_SelectPortNotify: return(SProcXvSelectPortNotify(client));
+    case xv_StopVideo: return(SProcXvStopVideo(client));
+    case xv_SetPortAttribute: return(SProcXvSetPortAttribute(client));
+    case xv_GetPortAttribute: return(SProcXvGetPortAttribute(client));
+    case xv_QueryBestSize: return(SProcXvQueryBestSize(client));
+    case xv_QueryPortAttributes: return(SProcXvQueryPortAttributes(client));
+    case xv_PutImage: return(SProcXvPutImage(client));
+#ifdef MITSHM
+    case xv_ShmPutImage: return(SProcXvShmPutImage(client));
+#endif
+    case xv_QueryImageAttributes: return(SProcXvQueryImageAttributes(client));
+    case xv_ListImageFormats: return(SProcXvListImageFormats(client));
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  return(BadImplementation);
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  return(BadRequest);
+	}
+    }
+}
+
+static int
+ProcXvQueryExtension(ClientPtr client)
+{
+  xvQueryExtensionReply rep;
+  /* REQUEST(xvQueryExtensionReq); */
+  REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.version = XvVersion;
+  rep.revision = XvRevision;
+
+  _WriteQueryExtensionReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvQueryAdaptors(ClientPtr client)
+{
+  xvFormat format;
+  xvAdaptorInfo ainfo;
+  xvQueryAdaptorsReply rep;
+  int totalSize;
+  int na;
+  XvAdaptorPtr pa;
+  int nf;
+  XvFormatPtr pf;
+  WindowPtr pWin;
+  ScreenPtr pScreen;
+  XvScreenPtr pxvs;
+
+  REQUEST(xvQueryAdaptorsReq);
+  REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+  if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+    {
+      client->errorValue = stuff->window;
+      return (BadWindow);
+    }
+
+  pScreen = pWin->drawable.pScreen;
+  pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+  if (!pxvs)
+    {
+      rep.type = X_Reply;
+      rep.sequenceNumber = client->sequence;
+      rep.num_adaptors = 0;
+      rep.length = 0;
+
+      _WriteQueryAdaptorsReply(client, &rep);
+
+      return Success;
+    }
+
+  (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_adaptors = pxvs->nAdaptors;
+
+  /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
+
+  totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
+
+  /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+      totalSize += (strlen(pa->name) + 3) & ~3;
+      totalSize += pa->nFormats * sz_xvFormat;
+      pa++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryAdaptorsReply(client, &rep);
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+
+      ainfo.base_id = pa->base_id;
+      ainfo.num_ports = pa->nPorts;
+      ainfo.type = pa->type;
+      ainfo.name_size = strlen(pa->name);
+      ainfo.num_formats = pa->nFormats;
+
+      _WriteAdaptorInfo(client, &ainfo);
+
+      WriteToClient(client, ainfo.name_size, pa->name);
+
+      nf = pa->nFormats;
+      pf = pa->pFormats;
+      while (nf--)
+	{
+	  format.depth = pf->depth;
+	  format.visual = pf->visual;
+	  _WriteFormat(client, &format);
+	  pf++;
+	}
+
+      pa++;
+
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+  xvEncodingInfo einfo;
+  xvQueryEncodingsReply rep;
+  int totalSize;
+  XvPortPtr pPort;
+  int ne;
+  XvEncodingPtr pe;
+  int status;
+
+  REQUEST(xvQueryEncodingsReq);
+  REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_encodings = pPort->pAdaptor->nEncodings;
+
+  /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  totalSize = ne * sz_xvEncodingInfo;
+  while (ne--)
+    {
+      totalSize += (strlen(pe->name) + 3) & ~3;
+      pe++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryEncodingsReply(client, &rep);
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  while (ne--) 
+    {
+      einfo.encoding = pe->id;
+      einfo.name_size = strlen(pe->name);
+      einfo.width = pe->width;
+      einfo.height = pe->height;
+      einfo.rate.numerator = pe->rate.numerator;
+      einfo.rate.denominator = pe->rate.denominator;
+      _WriteEncodingInfo(client, &einfo);
+      WriteToClient(client, einfo.name_size, pe->name);
+      pe++;
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutVideoReq);
+  REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvPutStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutStillReq);
+  REQUEST_SIZE_MATCH(xvPutStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetVideoReq);
+  REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetStillReq);
+  REQUEST_SIZE_MATCH(xvGetStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvSelectVideoNotify(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  REQUEST(xvSelectVideoNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+  if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadWindow);
+    }
+
+  return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSelectPortNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+  int result, status;
+  XvPortPtr pPort;
+  xvGrabPortReply rep;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result);
+
+  if (status != Success)
+    {
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.result = result;
+
+  _WriteGrabPortReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvUngrabPort(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+  int status;
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  REQUEST(xvStopVideoReq);
+  REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadDrawable);
+    }
+
+  return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diSetPortAttribute)(client, pPort, 
+				    stuff->attribute, stuff->value);
+
+  if (status == BadMatch) 
+      client->errorValue = stuff->attribute;
+  else
+      client->errorValue = stuff->value;
+
+  return status;
+}
+
+static int
+ProcXvGetPortAttribute(ClientPtr client)
+{
+  INT32 value;
+  int status;
+  XvPortPtr pPort;
+  xvGetPortAttributeReply rep;
+  REQUEST(xvGetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value);
+  if (status != Success)
+    {
+      client->errorValue = stuff->attribute;
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.value = value;
+ 
+  _WriteGetPortAttributeReply(client, &rep);
+
+  return Success;
+}
+
+static int
+ProcXvQueryBestSize(ClientPtr client)
+{
+  int status;
+  unsigned int actual_width, actual_height;
+  XvPortPtr pPort;
+  xvQueryBestSizeReply rep;
+  REQUEST(xvQueryBestSizeReq);
+  REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+
+  (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
+				       stuff->vid_w, stuff->vid_h, 
+				       stuff->drw_w, stuff->drw_h, 
+				       &actual_width, &actual_height);
+
+  rep.actual_width = actual_width;
+  rep.actual_height = actual_height;
+ 
+  _WriteQueryBestSizeReply(client, &rep);
+
+  return Success;
+}
+
+
+static int
+ProcXvQueryPortAttributes(ClientPtr client)
+{
+  int status, size, i;
+  XvPortPtr pPort;
+  XvAttributePtr pAtt;
+  xvQueryPortAttributesReply rep;
+  xvAttributeInfo Info;
+  REQUEST(xvQueryPortAttributesReq);
+  REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_attributes = pPort->pAdaptor->nAttributes;
+  rep.text_size = 0;
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {    
+      rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+  }
+
+  rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+  rep.length >>= 2;
+
+  _WriteQueryPortAttributesReply(client, &rep);
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {
+      size = strlen(pAtt->name) + 1;  /* pass the NULL */
+      Info.flags = pAtt->flags;
+      Info.min = pAtt->min_value;
+      Info.max = pAtt->max_value;
+      Info.size = (size + 3) & ~3L;
+
+      _WriteAttributeInfo(client, &Info);
+
+      WriteToClient(client, size, pAtt->name);
+  }
+
+  return Success;
+}
+
+
+
+static int 
+ProcXvPutImage(ClientPtr client)
+{
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, i, size;
+  CARD16 width, height;
+
+  REQUEST(xvPutImageReq);
+  REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  width = stuff->width;
+  height = stuff->height;
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  size += sizeof(xvPutImageReq);
+  size = (size + 3) >> 2;
+  
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+
+  if(client->req_len < size)
+     return BadLength;
+
+  return XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h,
+			    pImage, (unsigned char*)(&stuff[1]), FALSE,
+			    stuff->width, stuff->height);
+}
+
+#ifdef MITSHM
+/* redefined here since it's not in any header file */
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+extern RESTYPE ShmSegType;
+extern int BadShmSegCode;
+extern int ShmCompletionCode;
+
+static int 
+ProcXvShmPutImage(ClientPtr client)
+{
+  ShmDescPtr shmdesc;
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, size_needed, i;
+  CARD16 width, height;
+
+  REQUEST(xvShmPutImageReq);
+  REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) 
+    {
+      client->errorValue = stuff->shmseg;
+      return BadShmSegCode;  
+    }	
+ 
+  width = stuff->width;
+  height = stuff->height;
+  size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  if((size_needed + stuff->offset) > shmdesc->size)
+      return BadAccess;
+
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+     
+  status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h, pImage,
+			    (unsigned char *)shmdesc->addr + stuff->offset, 
+			    stuff->send_event, stuff->width, stuff->height);
+
+  if((status == Success) && stuff->send_event) {
+        xShmCompletionEvent ev;
+
+        ev.type = ShmCompletionCode;
+        ev.drawable = stuff->drawable;
+        ev.sequenceNumber = client->sequence;
+        ev.minorEvent = xv_ShmPutImage;
+        ev.majorEvent = XvReqCode;
+        ev.shmseg = stuff->shmseg;
+        ev.offset = stuff->offset;
+        WriteEventsToClient(client, 1, (xEvent *) &ev);
+  }
+
+  return status;
+}
+#endif
+
+#ifdef XvMCExtension
+XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id);
+#endif
+
+static int 
+ProcXvQueryImageAttributes(ClientPtr client)
+{
+  xvQueryImageAttributesReply rep;
+  int size, num_planes, i;
+  CARD16 width, height;
+  XvImagePtr pImage = NULL;
+  XvPortPtr pPort;
+  int *offsets;
+  int *pitches;
+  REQUEST(xvQueryImageAttributesReq);
+
+  REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+  
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+#ifdef XvMCExtension
+  if(!pImage)
+     pImage = XvMCFindXvImage(pPort, stuff->id);
+#endif
+
+  if(!pImage)
+     return BadMatch;
+
+  num_planes = pImage->num_planes;
+
+  if(!(offsets = xalloc(num_planes << 3)))
+	return BadAlloc;
+  pitches = offsets + num_planes;
+
+  width = stuff->width;
+  height = stuff->height;
+
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
+					&width, &height, offsets, pitches);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = num_planes << 1;
+  rep.num_planes = num_planes;
+  rep.width = width;
+  rep.height = height;
+  rep.data_size = size;
+ 
+  _WriteQueryImageAttributesReply(client, &rep);
+  if(client->swapped)
+    SwapLongs((CARD32*)offsets, rep.length);
+  WriteToClient(client, rep.length << 2, (char*)offsets);
+
+  xfree(offsets);
+
+  return Success;
+}
+
+static int 
+ProcXvListImageFormats(ClientPtr client)
+{
+  XvPortPtr pPort;
+  XvImagePtr pImage;
+  int i;
+  xvListImageFormatsReply rep;
+  xvImageFormatInfo info;
+  REQUEST(xvListImageFormatsReq);
+
+  REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_formats = pPort->pAdaptor->nImages;
+  rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+  _WriteListImageFormatsReply(client, &rep);
+
+  pImage = pPort->pAdaptor->pImages;
+  
+  for(i = 0; i < rep.num_formats; i++, pImage++) {
+     info.id = pImage->id; 	
+     info.type = pImage->type; 	
+     info.byte_order = pImage->byte_order; 
+     memcpy(&info.guid, pImage->guid, 16);	
+     info.bpp = pImage->bits_per_pixel; 	
+     info.num_planes = pImage->num_planes; 	
+     info.depth = pImage->depth; 	
+     info.red_mask = pImage->red_mask; 	
+     info.green_mask = pImage->green_mask; 	
+     info.blue_mask = pImage->blue_mask; 	
+     info.format = pImage->format; 	
+     info.y_sample_bits = pImage->y_sample_bits; 	
+     info.u_sample_bits = pImage->u_sample_bits; 	
+     info.v_sample_bits = pImage->v_sample_bits; 	
+     info.horz_y_period = pImage->horz_y_period; 	
+     info.horz_u_period = pImage->horz_u_period; 	
+     info.horz_v_period = pImage->horz_v_period; 	
+     info.vert_y_period = pImage->vert_y_period; 	
+     info.vert_u_period = pImage->vert_u_period; 	
+     info.vert_v_period = pImage->vert_v_period; 	
+     memcpy(&info.comp_order, pImage->component_order, 32);	
+     info.scanline_order = pImage->scanline_order;
+     _WriteImageFormatInfo(client, &info);
+  }  
+
+  return Success;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryExtensionReq);
+  swaps(&stuff->length, n);
+  return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryAdaptorsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->window, n);
+  return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryEncodingsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvUngrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvShmPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->shmseg, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->offset, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectVideoNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectPortNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvStopVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryBestSizeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryPortAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryImageAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->width, n);
+  return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvListImageFormatsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+   ClientPtr client,
+   xvQueryExtensionReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->version, n);
+  swaps(&rep->revision, n);
+  
+  (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryAdaptorsReply(
+   ClientPtr client,
+   xvQueryAdaptorsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_adaptors, n);
+  
+  (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryEncodingsReply(
+   ClientPtr client,
+   xvQueryEncodingsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_encodings, n);
+  
+  (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteAdaptorInfo(
+   ClientPtr client,
+   xvAdaptorInfo *pAdaptor
+){
+  register char n;
+
+  swapl(&pAdaptor->base_id, n);
+  swaps(&pAdaptor->name_size, n);
+  swaps(&pAdaptor->num_ports, n);
+  swaps(&pAdaptor->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
+
+  return Success;
+}
+
+static int
+SWriteEncodingInfo(
+   ClientPtr client,
+   xvEncodingInfo *pEncoding
+){
+  register char n;
+  
+  swapl(&pEncoding->encoding, n);
+  swaps(&pEncoding->name_size, n);
+  swaps(&pEncoding->width, n);
+  swaps(&pEncoding->height, n);
+  swapl(&pEncoding->rate.numerator, n);
+  swapl(&pEncoding->rate.denominator, n);
+  (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
+
+  return Success;
+}
+
+static int
+SWriteFormat(
+   ClientPtr client,
+   xvFormat *pFormat
+){
+  register char n;
+
+  swapl(&pFormat->visual, n);
+  (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+  return Success;
+}
+
+static int
+SWriteAttributeInfo(
+   ClientPtr client,
+   xvAttributeInfo *pAtt
+){
+  register char n;
+
+  swapl(&pAtt->flags, n);
+  swapl(&pAtt->size, n);
+  swapl(&pAtt->min, n);
+  swapl(&pAtt->max, n);
+  (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
+
+  return Success;
+}
+
+static int
+SWriteImageFormatInfo(
+   ClientPtr client,
+   xvImageFormatInfo *pImage
+){
+  register char n;
+
+  swapl(&pImage->id, n);
+  swapl(&pImage->red_mask, n);
+  swapl(&pImage->green_mask, n);
+  swapl(&pImage->blue_mask, n);
+  swapl(&pImage->y_sample_bits, n);
+  swapl(&pImage->u_sample_bits, n);
+  swapl(&pImage->v_sample_bits, n);
+  swapl(&pImage->horz_y_period, n);
+  swapl(&pImage->horz_u_period, n);
+  swapl(&pImage->horz_v_period, n);
+  swapl(&pImage->vert_y_period, n);
+  swapl(&pImage->vert_u_period, n);
+  swapl(&pImage->vert_v_period, n);
+
+  (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
+
+  return Success;
+}
+
+
+
+static int
+SWriteGrabPortReply(
+   ClientPtr client,
+   xvGrabPortReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+
+  (void)WriteToClient(client, sz_xvGrabPortReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteGetPortAttributeReply(
+   ClientPtr client,
+   xvGetPortAttributeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->value, n);
+
+  (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryBestSizeReply(
+   ClientPtr client,
+   xvQueryBestSizeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->actual_width, n);
+  swaps(&rep->actual_height, n);
+
+  (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryPortAttributesReply(
+   ClientPtr client,
+   xvQueryPortAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_attributes, n);
+  swapl(&rep->text_size, n);
+
+  (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryImageAttributesReply(
+   ClientPtr client,
+   xvQueryImageAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_planes, n);
+  swapl(&rep->data_size, n);
+  swaps(&rep->width, n);
+  swaps(&rep->height, n);
+
+  (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+
+static int
+SWriteListImageFormatsReply(
+   ClientPtr client,
+   xvListImageFormatsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+  return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+   int result = Success, i;
+   PanoramiXRes *draw, *port;
+   REQUEST(xvStopVideoReq);
+   REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+   if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+   if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+   FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   result = ProcXvStopVideo(client);
+     	}
+   }
+
+   return result;
+}
+
+static int
+XineramaXvSetPortAttribute(ClientPtr client)
+{
+    REQUEST(xvSetPortAttributeReq);
+    PanoramiXRes *port;
+    int result = Success, i;
+
+    REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->port = port->info[i].id;
+	   result = ProcXvSetPortAttribute(client);
+	}
+    }
+    return result;
+}
+
+
+#ifdef MITSHM
+static int 
+XineramaXvShmPutImage(ClientPtr client)
+{
+    REQUEST(xvShmPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool send_event = stuff->send_event;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+	   stuff->send_event = (send_event && !i) ? 1 : 0;
+
+	   result = ProcXvShmPutImage(client);
+	}
+    }
+    return result;
+}
+#endif
+
+static int 
+XineramaXvPutImage(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+		client, stuff->port, XvXRTPort, SecurityReadAccess)))
+	return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+
+	   result = ProcXvPutImage(client);
+	}
+    }
+    return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutVideo(client);
+        }
+    }
+    return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) &&
+                (stuff->drawable == WindowTable[0]->drawable.id);
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutStill(client);
+        }
+    }
+    return result;
+}
+
+
+void XineramifyXv(void)
+{
+   ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+   XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+   XvAdaptorPtr refAdapt, pAdapt;
+   XvAttributePtr pAttr;
+   XvScreenPtr xvsp;
+   Bool isOverlay, hasOverlay;
+   PanoramiXRes *port;
+   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   int i, j, k, l;
+
+   XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+   if(!xvsp0) return;
+   
+   for(i = 0; i < xvsp0->nAdaptors; i++) {
+      refAdapt = xvsp0->pAdaptors + i;
+
+      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+      
+      MatchingAdaptors[0] = refAdapt;
+   
+      if(!(refAdapt->type & XvInputMask)) continue;
+      
+      isOverlay = FALSE;
+      for(j = 0; j < refAdapt->nAttributes; j++) {
+         pAttr = refAdapt->pAttributes + j;
+         if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+	    isOverlay = TRUE;
+	    break;
+	 }
+      }
+   
+      for(j = 1; j < PanoramiXNumScreens; j++) {
+         pScreen = screenInfo.screens[j];
+	 xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+         /* Do not try to go on if xv is not supported on this screen */
+         if (xvsp==NULL) continue ;
+	 
+         /* if the adaptor has the same name it's a perfect match */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	   pAdapt = xvsp->pAdaptors + k;
+           if(!strcmp(refAdapt->name, pAdapt->name)) {
+	       MatchingAdaptors[j] = pAdapt;
+	       break;
+	   }
+         }
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* otherwise we only look for XvImage adaptors */
+	 if(!(refAdapt->type & XvImageMask)) continue;
+	 if(refAdapt->nImages <= 0) continue;
+	 
+	 /* prefer overlay/overlay non-overlay/non-overlay pairing */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      hasOverlay = FALSE;
+              for(l = 0; l < pAdapt->nAttributes; l++) {
+	         if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+		   hasOverlay = TRUE;
+		   break;
+		 }
+	      }
+	      if(isOverlay && hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+              else if(!isOverlay && !hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+	    }
+         }
+	 
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* but we'll take any XvImage pairing if we can get it */
+	 	 
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	    }
+         }
+      }
+
+      /* now create a resource for each port */
+      for(j = 0; j < refAdapt->nPorts; j++) {
+         if(!(port = xalloc(sizeof(PanoramiXRes))))
+	    break;
+	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
+	 AddResource(port->info[0].id, XvXRTPort, port);
+
+	 for(k = 1; k < PanoramiXNumScreens; k++) {
+	    if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 
+		port->info[k].id = MatchingAdaptors[k]->base_id + j;
+	    else
+		port->info[k].id = 0;
+	 } 
+      }
+   }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
new file mode 100644
index 000000000..3a27e0da0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -0,0 +1,178 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "X.h"
+
+#include "Agent.h"
+#include "Args.h"
+#include "Options.h"
+#include "Utils.h"
+
+/*
+ * Instead of having a single options repository
+ * data could be attached to the display or the
+ * screen. The macro nxagentOption() should make
+ * the transition simple.
+ */
+
+AgentOptionsRec nxagentOptions;
+
+AgentOptionsRec nxagentOptionsBackup;
+
+AgentOptionsPtr nxagentOptionsPtr = &nxagentOptions;
+
+/*
+ * This must be called at startup to initialize
+ * the options repository to the default values.
+ */
+
+void nxagentInitOptions()
+{
+  nxagentOptions.LinkType = UNDEFINED;
+
+  nxagentOptions.Desktop    = UNDEFINED;
+  nxagentOptions.Persistent = 1;
+  nxagentOptions.Rootless   = UNDEFINED;
+  nxagentOptions.Fullscreen = UNDEFINED;
+
+  nxagentOptions.X           = 0;
+  nxagentOptions.Y           = 0;
+  nxagentOptions.Width       = 0;
+  nxagentOptions.Height      = 0;
+  nxagentOptions.BorderWidth = 0;
+
+  nxagentOptions.SavedX      = 0;
+  nxagentOptions.SavedY      = 0;
+  nxagentOptions.SavedWidth  = 0;
+  nxagentOptions.SavedHeight = 0;
+
+  nxagentOptions.Timeout = 0;
+
+  nxagentOptions.Nested = 0;
+
+  nxagentOptions.BackingStore = BackingStoreUndefined;
+
+  nxagentOptions.Clipboard = ClipboardBoth;
+
+  nxagentOptions.SharedMemory = 1;
+
+  nxagentOptions.SharedPixmaps = 1;
+
+  nxagentOptions.DeviceControl = 0;
+
+  nxagentOptions.ResetKeyboardAtResume = 1;
+
+  nxagentOptions.Reset = 0;
+
+  nxagentOptions.RootX = 0;
+  nxagentOptions.RootY = 0;
+  nxagentOptions.RootWidth = 0;
+  nxagentOptions.RootHeight = 0;
+
+  nxagentOptions.ViewportXSpan = 0;
+  nxagentOptions.ViewportYSpan = 0;
+
+  #ifndef __CYGWIN32__
+
+  nxagentOptions.DesktopResize = 1;
+
+  #else
+
+  nxagentOptions.DesktopResize = 0;
+
+  #endif
+
+  nxagentOptions.Ratio  = DONT_SCALE;
+  nxagentOptions.XRatio = DONT_SCALE;
+  nxagentOptions.YRatio = DONT_SCALE;
+
+  nxagentOptions.FloatRatio  = 1.0;
+  nxagentOptions.FloatXRatio = 1.0;
+  nxagentOptions.FloatYRatio = 1.0;
+
+  nxagentOptions.UseDamage = 1;
+
+  nxagentOptions.Binder = UNDEFINED;
+  nxagentOptions.BinderOptions = NULL;
+
+  nxagentOptions.Xdmcp = 0;
+
+  nxagentOptions.DisplayLatency = 0;
+  nxagentOptions.DisplayBuffer  = UNDEFINED;
+  nxagentOptions.DisplayCoalescence = 0;
+
+  nxagentOptions.Composite = 1;
+
+  nxagentOptions.IgnoreVisibility = 0;
+
+  nxagentOptions.ViewOnly = 0;
+
+  nxagentOptions.Adaptive = 0;
+
+  nxagentOptions.Streaming = 0;
+
+  nxagentOptions.DeferLevel   = UNDEFINED;
+  nxagentOptions.DeferTimeout = 200;
+
+  nxagentOptions.TileWidth  = UNDEFINED;
+  nxagentOptions.TileHeight = UNDEFINED;
+
+  nxagentOptions.Menu = 1;
+
+  nxagentOptions.ClientOs = UNDEFINED;
+
+  nxagentOptions.InhibitXkb = 1;
+}
+
+/*
+ * This is called at session reconnection
+ * to reset some options to their default
+ * values. The reason to avoid calling the
+ * nxagentInitOptions() is that not all the
+ * options can change value when reconnec-
+ * ting.
+ */
+
+void nxagentResetOptions()
+{
+  if (nxagentLockDeferLevel == 0)
+  {
+    nxagentOptions.DeferLevel   = UNDEFINED;
+  }
+
+  nxagentOptions.DeferTimeout = 200;
+
+  nxagentOptions.TileWidth  = UNDEFINED;
+  nxagentOptions.TileHeight = UNDEFINED;
+}
+
+void nxagentSaveOptions()
+{
+  memcpy(&nxagentOptionsBackup, &nxagentOptions, sizeof(AgentOptionsRec));
+}
+
+void nxagentRestoreOptions()
+{
+  nxagentOptions.DeferLevel   = nxagentOptionsBackup.DeferLevel;
+  nxagentOptions.DeferTimeout = nxagentOptionsBackup.DeferTimeout;
+
+  nxagentOptions.TileWidth  = nxagentOptionsBackup.TileWidth;
+  nxagentOptions.TileHeight = nxagentOptionsBackup.TileHeight;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
new file mode 100644
index 000000000..493ba6f61
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -0,0 +1,397 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Options_H__
+#define __Options_H__
+
+#ifndef True
+#define True   1
+#endif
+
+#ifndef False
+#define False  0
+#endif
+
+#define UNDEFINED -1
+
+typedef enum _BackingStoreMode
+{
+  BackingStoreUndefined = -1,
+  BackingStoreNever,
+  BackingStoreWhenRequested,
+  BackingStoreForce
+
+} BackingStoreMode;
+
+typedef enum _ClipboardMode
+{
+  ClipboardBoth,
+  ClipboardClient,
+  ClipboardServer,
+  ClipboardNone
+
+} ClipboardMode;
+
+typedef enum _ClientOsType
+{
+  ClientOsWinnt = 0,
+  ClientOsLinux,
+  ClientOsSolaris,
+  ClientOsMac
+
+} ClientOsType;
+
+/*
+ * Set of options affecting agent operations.
+ */
+
+typedef struct _AgentOptions
+{
+  /*
+   * Link type of the NX connection or none,
+   * if this is a direct X11 connection.
+   */
+
+  int LinkType;
+
+  /*
+   * Is agent running in desktop mode? This
+   * is presently the default.
+   */
+
+  int Desktop;
+
+  /*
+   * True if user activated rootless mode.
+   */
+
+  int Rootless;
+
+  /*
+   * True for shadow mode.
+   */
+
+  int Shadow;
+
+  /*
+   * True if user activated persistent mode.
+   */
+
+  int Persistent;
+
+  /*
+   * True if user activated fullscreen mode.
+   */
+
+  int Fullscreen;
+
+  /*
+   * Set to the auto-disconnect timeout, if
+   * the user activated this feature.
+   */
+
+  int Timeout;
+
+  /*
+   * Geometry of the agent's window.
+   */
+
+  int X;
+  int Y;
+  int Width;
+  int Height;
+  int BorderWidth;
+
+  /*
+   * Geometry of the agent's window in window
+   * mode. Used to restore window size when
+   * switching back to window mode from full-
+   * screen.
+   */
+
+  int SavedX;
+  int SavedY;
+  int SavedWidth;
+  int SavedHeight;
+
+  int SavedRootWidth;
+  int SavedRootHeight;
+
+  /*
+   * Set if agent is running nested in another
+   * agent X server.
+   */
+
+  int Nested;
+
+  /*
+   * Selected backing-store mode.
+   */
+
+  BackingStoreMode BackingStore;
+
+  /*
+   * Selected clipboard mode.
+   */
+
+  ClipboardMode Clipboard;
+
+  /*
+   * Enable agent to use the MITSHM extension in
+   * path from remote proxy to the real X server.
+   */
+
+  int SharedMemory;
+
+  /*
+   * Enable agent to use shared Pixmaps
+   */
+
+  int SharedPixmaps;
+
+  /*
+   * Enable agent to propagate keyboard and pointer
+   * device configuration to the remote X server.
+   */
+
+  int DeviceControl;
+
+  /*
+   * Resuming keyboard device corrects keymap if session
+   * migrates across platforms with different keycode
+   * layout.
+   */
+
+  int ResetKeyboardAtResume;
+
+  /*
+   * Reset server when the last client disconnects.
+   */
+
+  int Reset;
+
+  /* 
+   * Geometry of the agent root window, relative to
+   * the agent default window.
+   */
+
+  int RootX;
+  int RootY;
+  int RootWidth;
+  int RootHeight;
+
+  /*
+   * Horizontal and vertical span of the
+   * agent viewport.
+   */
+
+  int ViewportXSpan;
+  int ViewportYSpan;
+
+  /*
+   * True if the user can resize the desktop
+   * by dragging the window border.
+   */
+
+  int DesktopResize;
+
+  /*
+   * The scaling ratio of the shadow agent.
+   */
+
+  int Ratio;
+
+  int XRatio;
+
+  int YRatio;
+
+  float FloatRatio;
+
+  float FloatXRatio;
+
+  float FloatYRatio;
+
+  /*
+   * The shadow agent uses the Damage extension.
+   */
+
+  int UseDamage;
+
+  /*
+   * Was the agent run with the -B option?
+   */
+
+  int Binder;
+
+  char *BinderOptions;
+
+  /*
+   * Set if the agent has to connect to a
+   * desktop manager to start the session.
+   */
+
+  int Xdmcp;
+
+  /*
+   * Latency of the link. It is simply set
+   * to a reference value, calculated based
+   * on the time required to complete the
+   * query of the agent's atoms at session
+   * startup.
+   */
+
+  int DisplayLatency;
+
+  /*
+   * Size of the Xlib display buffer. The
+   * default is set according to the link
+   * type.
+   */
+
+  int DisplayBuffer;
+
+  /*
+   * Buffer coalescence timeout.
+   */
+
+  int DisplayCoalescence;
+
+  /*
+   * Use the composite extension when
+   * available on the remote display.
+   */
+
+  int Composite;
+
+  /*
+   * If set, don't skip internal operations
+   * when the agent window is not fully visible.
+   */
+
+  int IgnoreVisibility;
+
+  /*
+   * If set, prevent the shadow session to
+   * interact with master diplay.
+   */
+
+  int ViewOnly;
+
+  /*
+   * If true select a lossy or lossless comp-
+   * ression method based on the characterist-
+   * ics of the image.
+   */
+
+  int Adaptive;
+
+  /*
+   * Stream the images and update the display
+   * when the image has been completely trans-
+   * ferred.
+   */
+
+  int Streaming;
+
+  /*
+   * Use a lazy approach in updating the remote
+   * display. This means delaying the bandwidth
+   * consuming graphic operations and synchroniz-
+   * ing the screen at idle time.
+   */
+
+  int DeferLevel;
+
+  /*
+   * Maxuimum elapsed time before a new full
+   * synchronization.
+   */
+
+  unsigned long DeferTimeout;
+
+  /*
+   * Maximum size of the tile used when sending
+   * an image to the remote display.
+   */
+
+  int TileWidth;
+  int TileHeight;
+
+  /*
+   * Enabling/disabling the pulldown menu.
+   */
+
+  int Menu;
+
+  /*
+   * Specify the Operative System of the client.
+   */
+
+  int ClientOs;
+
+  /*
+   * Inhibit some XKEYBOARD requests.
+   */
+
+  int InhibitXkb;
+
+} AgentOptionsRec;
+
+typedef AgentOptionsRec *AgentOptionsPtr;
+
+extern AgentOptionsPtr nxagentOptionsPtr;
+
+/*
+ * Macros and functions giving access to options.
+ */
+
+#define nxagentOption(option) \
+    (nxagentOptionsPtr -> option)
+
+#define nxagentChangeOption(option, value) \
+    (nxagentOptionsPtr -> option = (value))
+
+#define nxagentOptions() \
+    (nxagentOptionsPtr)
+
+/*
+ * Initialize the options to the default values.
+ */
+
+extern void nxagentInitOptions(void);
+
+/*
+ * Initialize some options to the default values
+ * at reconnection.
+ */
+
+extern void nxagentResetOptions(void);
+
+/*
+ * Save a copy of the current option repository.
+ */
+
+extern void nxagentSaveOptions(void);
+
+/*
+ * Restore the options reset by nxagentResetOptions
+ * to their backup value.
+ */
+
+extern void nxagentRestoreOptions(void);
+
+#endif /* __Options_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
new file mode 100644
index 000000000..03970a14f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
@@ -0,0 +1,384 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Xmd.h"
+#include "Xlib.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#define PIXEL_ELEMENTS  256
+#define PIXEL_THRESHOLD 8
+#define PIXEL_STEP      7
+
+unsigned int Get16(const char *buffer, int order);
+unsigned int Get24(const char *buffer, int order);
+unsigned int Get32(const char *buffer, int order);
+
+void Put16(unsigned int value, char *buffer, int order);
+void Put24(unsigned int value, char *buffer, int order);
+void Put32(unsigned int value, char *buffer, int order);
+
+static int nxagentComparePixels(const void *p1, const void *p2)
+{
+  int pixel1 = *((int *) p1);
+  int pixel2 = *((int *) p2);
+
+  return (pixel1 < pixel2 ? -1 : (pixel1 == pixel2 ? 0 : 1));
+}
+
+int nxagentUniquePixels(XImage *image)
+{
+  int i = 0;
+
+  int pixels[PIXEL_ELEMENTS];
+
+  int elements = PIXEL_ELEMENTS;
+  int unique   = 0;
+
+  int total;
+  int ratio;
+  int step;
+
+  int last = -1;
+
+  const char *next = image -> data;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUniquePixels: Image geometry [%d,%d] depth [%d] bits per pixel [%d].\n",
+              image -> width, image -> height, image -> depth, image -> bits_per_pixel);
+  #endif
+
+  /*
+   * Take at most 256 pixels from the image.
+   */
+
+  total = image -> width * image -> height;
+  
+  step = total / elements;
+
+  if (step < PIXEL_STEP)
+  {
+    step = PIXEL_STEP;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUniquePixels: Step is [%d] with [%d] pixels and [%d] elements.\n",
+              step, total, elements);
+  #endif
+
+  /*
+   * Shift at the left after each scanline.
+   */
+   
+  if (image -> bytes_per_line % step == 0)
+  {
+    step++;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentUniquePixels: Increasing step to [%d] with [%d] bytes per line.\n",
+                step, image -> bytes_per_line);
+    #endif
+  }
+
+  elements = total / step;
+
+  if (elements > PIXEL_ELEMENTS)
+  {
+    elements = PIXEL_ELEMENTS;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUniquePixels: Step is now [%d] with [%d] elements.\n",
+              step, elements);
+  #endif
+
+  if (elements < PIXEL_THRESHOLD)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentUniquePixels: Assuming ratio [100] with only [%d] elements.\n",
+                elements);
+    #endif
+
+    return 100;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUniquePixels: Scanning [%d] pixels out of [%d] with step [%d].\n",
+              elements, total, step);
+  #endif
+
+  /*
+   * Take one pixel every n from the image and
+   * add it to the array.
+   */
+
+  switch (image -> bits_per_pixel)
+  {
+    case 32:
+    {
+      for (i = 0; i < elements; i++)
+      {
+        pixels[i] = Get32(next, image -> byte_order);
+
+        next += (4 * step);
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+                    i, pixels[i]);
+        #endif
+      }
+
+      break;
+    }
+    case 24:
+    {
+      for (i = 0; i < elements; i++)
+      {
+        pixels[i] = Get24(next, image -> byte_order);
+
+        next += (3 * step);
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+                    i, pixels[i]);
+        #endif
+      }
+
+      break;
+    }
+    case 16:
+    case 15:
+    {
+      /*
+       * Note that the padding bytes at the end
+       * of the scanline are included in the set.
+       * This is not a big problem. What we want
+       * to find out is just how compressible is
+       * the image data.
+       */
+
+      for (i = 0; i < elements; i++)
+      {
+        pixels[i] = Get16(next, image -> byte_order);
+
+        next += (2 * step);
+
+        #ifdef DEBUG
+        fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+                    i, pixels[i]);
+        #endif
+      }
+
+      break;
+    }
+    default:
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentUniquePixels: PANIC! Assuming ratio [100] with [%d] bits per pixel.\n",
+                  image -> bits_per_pixel);
+      #endif
+
+      return 100;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUniquePixels: Sorting [%d] elements in the list.\n", i);
+  #endif
+
+  qsort(pixels, elements, sizeof(int), nxagentComparePixels);
+
+  for (i = 0; i < elements; i++)
+  {
+    if (last != pixels[i])
+    {
+      unique++;
+
+      last = pixels[i];
+    }
+
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentUniquePixels: pixels[%d][0x%08x].\n",
+                i, pixels[i]);
+    #endif
+  }
+
+  ratio = unique * 100 / elements;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentUniquePixels: Found [%d] unique pixels out of [%d] with ratio [%d%%].\n",
+              unique, elements, ratio);
+  #endif
+
+  return ratio;
+}
+
+unsigned int Get16(const char *buffer, int order)
+{
+  unsigned int result;
+
+  if (order == MSBFirst)
+  {
+    result = *buffer;
+
+    result <<= 8;
+
+    result += buffer[1];
+  }
+  else
+  {
+    result = buffer[1];
+
+    result <<= 8;
+
+    result += *buffer;
+  }
+
+  return result;
+}
+
+unsigned int Get24(const char *buffer, int order)
+{
+  int i;
+
+  const char *next = (order == MSBFirst ? buffer : buffer + 2);
+
+  unsigned int result = 0;
+
+  for (i = 0; i < 3; i++)
+  {
+    result <<= 8;
+
+    result += *next;
+
+    if (order == MSBFirst)
+    {
+      next++;
+    }
+    else
+    {
+      next--;
+    }
+  }
+
+  return result;
+}
+
+unsigned int Get32(const char *buffer, int order)
+{
+  int i;
+
+  const char *next = (order == MSBFirst ? buffer : buffer + 3);
+
+  unsigned int result = 0;
+
+  for (i = 0; i < 4; i++)
+  {
+    result <<= 8;
+
+    result += *next;
+
+    if (order == MSBFirst)
+    {
+      next++;
+    }
+    else
+    {
+      next--;
+    }
+  }
+
+  return result;
+}
+
+void Put16(unsigned int value, char *buffer, int order)
+{
+  if (order == MSBFirst)
+  {
+    buffer[1] = (unsigned char) (value & 0xff);
+
+    value >>= 8;
+
+    *buffer = (unsigned char) value;
+  }
+  else
+  {
+    *buffer = (unsigned char) (value & 0xff);
+
+    value >>= 8;
+
+    buffer[1] = (unsigned char) value;
+  }
+}
+
+void Put24(unsigned int value, char *buffer, int order)
+{
+  int i;
+
+  if (order == MSBFirst)
+  {
+    buffer += 2;
+
+    for (i = 3; i > 0; i--)
+    {
+      *buffer-- = (unsigned char) (value & 0xff);
+
+      value >>= 8;
+    }
+  }
+  else
+  {
+    for (i = 3; i > 0; i--)
+    {
+      *buffer++ = (unsigned char) (value & 0xff);
+
+      value >>= 8;
+    }
+  }
+}
+
+void Put32(unsigned int value, char *buffer, int order)
+{
+  int i;
+
+  if (order == MSBFirst)
+  {
+    buffer += 3;
+
+    for (i = 4; i > 0; i--)
+    {
+      *buffer-- = (unsigned char) (value & 0xff);
+
+      value >>= 8;
+    }
+  }
+  else
+  {
+    for (i = 4; i > 0; i--)
+    {
+      *buffer++ = (unsigned char) (value & 0xff);
+
+      value >>= 8;
+    }
+  }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
new file mode 100644
index 000000000..f9f88233e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -0,0 +1,162 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Pixels_H__
+#define __Pixels_H__
+
+#include "Visual.h"
+#include "Drawable.h"
+#include "Composite.h"
+
+/*
+ * Count how many pixels are different
+ * in the image.
+ */
+
+int nxagentUniquePixels(XImage *image);
+
+/*
+ * Convert a 32 bit pixel to 16 bit.
+ */
+
+#define Color32to16(color) \
+do \
+{ \
+  Visual *pVisual; \
+\
+  pVisual = nxagentDefaultVisual(nxagentDefaultScreen); \
+\
+    if (pVisual -> green_mask == 0x7e0) \
+    { \
+      /* \
+       * bit mask 5-6-5 \
+       */ \
+\
+      color = (((color & (pVisual -> blue_mask << 3)) >> 3) |        \
+                   ((color & (pVisual -> green_mask << 5)) >> 5) |   \
+                       ((color & (pVisual -> red_mask << 8)) >> 8)); \
+    } \
+    else \
+    { \
+      /* \
+       * bit mask 5-5-5 \
+       */ \
+\
+      color = (((color & (pVisual -> blue_mask << 3)) >> 3) |        \
+                   ((color & (pVisual -> green_mask << 6)) >> 6) |   \
+                       ((color & (pVisual -> red_mask << 9)) >> 9)); \
+    } \
+} \
+while (0)
+
+/*
+ * Rules to break the synchronization loop.
+ */
+
+#define breakOnBlocking(mask)                                \
+    (((mask) != NEVER_BREAK) && ((mask) & BLOCKING_BREAK) && \
+        nxagentBlocking == 1)
+
+#define breakOnCongestion(mask)                                \
+    (((mask) != NEVER_BREAK) && ((mask) & CONGESTION_BREAK) && \
+        nxagentCongestion > 4)
+
+#define breakOnBlockingOrCongestion(mask) \
+    (breakOnBlocking(mask) != 0 || breakOnCongestion(mask) != 0)
+
+#define breakOnCongestionDrawable(mask, pDrawable)             \
+    (((mask) != NEVER_BREAK) && ((mask) & CONGESTION_BREAK) && \
+        (nxagentCongestion > 4 ||                              \
+            ((pDrawable) -> type == DRAWABLE_PIXMAP &&         \
+                nxagentCongestion > 1)))
+
+#define breakOnEvent(mask)                                \
+    (((mask) != NEVER_BREAK) && ((mask) & EVENT_BREAK) && \
+        nxagentUserInput(NULL) == 1)
+
+#define canBreakOnTimeout(mask) \
+    (((mask) != NEVER_BREAK) && nxagentOption(Shadow) == 0)
+
+/*
+ * Macros defining the conditions to
+ * defer X requests.
+ */
+
+#define NXAGENT_SHOULD_DEFER_TRAPEZOIDS(pDrawable)       \
+    (nxagentOption(DeferLevel) >= 2 &&                   \
+         nxagentDrawableContainGlyphs(pDrawable) == 0 && \
+             nxagentOption(LinkType) < LINK_TYPE_ADSL && \
+                 nxagentCongestion > 4)
+
+/*
+FIXME: The condition checking for the render
+       version is a workaround implemented to
+       avoid problems with the render composi-
+       te on XFree86 remote server.
+*/
+#define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)                 \
+    ((nxagentRenderVersionMajor == 0 &&                                   \
+     nxagentRenderVersionMinor == 8 &&                                \
+     (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP) ||                        \
+         ((pDst) -> pDrawable -> type == DRAWABLE_PIXMAP &&                    \
+          (nxagentDrawableStatus((pSrc) -> pDrawable) == NotSynchronized || \
+          ((pMask) && nxagentDrawableStatus((pMask) -> pDrawable) == NotSynchronized)) &&  \
+          nxagentOption(DeferLevel) == 1) ||               \
+             (nxagentOption(DeferLevel) >= 2 &&           \
+              nxagentOption(LinkType) < LINK_TYPE_ADSL))
+
+#define NXAGENT_SHOULD_DEFER_PUTIMAGE(pDrawable) \
+    (nxagentSplitTrap == 0 &&                    \
+         nxagentOption(DeferLevel) > 0)
+
+/*
+ * Macros defining the conditions to
+ * start the synchronization loops of
+ * resources.
+ */
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_WINDOWS(mask)            \
+    ((nxagentCorruptedWindows > 0 && breakOnBlockingOrCongestion(mask) == 0) || \
+         mask == NEVER_BREAK)
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_BACKGROUNDS(mask)           \
+    ((nxagentCorruptedWindows == 0 && nxagentCorruptedBackgrounds > 0 && \
+         breakOnBlockingOrCongestion(mask) == 0) || mask == NEVER_BREAK)
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_CORRUPTED_PIXMAPS(mask)           \
+    ((nxagentCorruptedWindows == 0 && nxagentCorruptedPixmaps > 0 && \
+         nxagentCongestion == 0 && nxagentBlocking == 0) ||          \
+             mask == NEVER_BREAK)
+
+/*
+ * Macros defining the conditions to
+ * synchronize a single resource.
+ */
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_WINDOW(pDrawable)  \
+    (nxagentWindowIsVisible((WindowPtr) pDrawable) == 1 && \
+        (nxagentDefaultWindowIsVisible() == 1 || nxagentCompositeEnable == 1))
+
+#define MINIMUM_PIXMAP_USAGE_COUNTER 2
+
+#define NXAGENT_SHOULD_SYNCHRONIZE_PIXMAP(pDrawable)      \
+    (nxagentPixmapUsageCounter((PixmapPtr) pDrawable) >=  \
+         MINIMUM_PIXMAP_USAGE_COUNTER ||                  \
+             nxagentIsCorruptedBackground((PixmapPtr) pDrawable) == 1)
+
+#endif /* __Pixels_H__ */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
new file mode 100644
index 000000000..4aea92e2d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
@@ -0,0 +1,1646 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "miscstruct.h"
+#include "pixmapstr.h"
+#include "dixstruct.h"
+#include "regionstr.h"
+#include "../../include/gc.h"
+#include "servermd.h"
+#include "mi.h"
+
+#include "../../fb/fb.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Trap.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Image.h"
+#include "Split.h"
+#include "Drawable.h"
+#include "Visual.h"
+#include "Client.h"
+#include "Events.h"
+#include "Holder.h"
+#include "Args.h"
+
+#include "NXlib.h"
+#include "NXpack.h"
+
+RESTYPE  RT_NX_PIXMAP;
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  DUMP
+
+#ifdef TEST
+#include "Font.h"
+#endif
+
+int nxagentPixmapPrivateIndex;
+
+int nxagentCorruptedPixmaps;
+int nxagentCorruptedBackgrounds;
+
+/*
+ * Force deallocation of the virtual pixmap.
+ */
+
+static Bool nxagentDestroyVirtualPixmap(PixmapPtr pPixmap);
+
+/*
+ * This serves as a tool to check the synchronization
+ * between pixmaps in framebuffer and the correspondent
+ * pixmaps in the real X server.
+ */
+
+#ifdef TEST
+Bool nxagentCheckPixmapIntegrity(PixmapPtr pPixmap);
+#endif
+
+struct nxagentPixmapPair
+{
+  Pixmap pixmap;
+  PixmapPtr pMap;
+};
+
+PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width,
+                                  int height, int depth)
+{
+  nxagentPrivPixmapPtr pPixmapPriv, pVirtualPriv;
+
+  PixmapPtr pPixmap;
+  PixmapPtr pVirtual;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentCreatePixmap: Creating pixmap with width [%d] "
+              "height [%d] depth [%d].\n", width, height, depth);
+  #endif
+
+  /*
+   * Create the pixmap structure but do
+   * not allocate memory for the data.
+   */
+
+  pPixmap = AllocatePixmap(pScreen, 0);
+
+  if (!pPixmap)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreatePixmap: WARNING! Failed to create pixmap with "
+                "width [%d] height [%d] depth [%d].\n", width, height, depth);
+    #endif
+
+    return NullPixmap;
+  }
+
+  /*
+   * Initialize the core members.
+   */
+
+  pPixmap -> drawable.type = DRAWABLE_PIXMAP;
+  pPixmap -> drawable.class = 0;
+  pPixmap -> drawable.pScreen = pScreen;
+  pPixmap -> drawable.depth = depth;
+  pPixmap -> drawable.bitsPerPixel = BitsPerPixel(depth);
+  pPixmap -> drawable.id = 0;
+  pPixmap -> drawable.serialNumber = NEXT_SERIAL_NUMBER;
+  pPixmap -> drawable.x = 0;
+  pPixmap -> drawable.y = 0;
+  pPixmap -> drawable.width = width;
+  pPixmap -> drawable.height = height;
+  pPixmap -> devKind = 0;
+  pPixmap -> refcnt = 1;
+  pPixmap -> devPrivate.ptr = NULL;
+
+  /*
+   * Initialize the privates of the real picture.
+   */
+
+  pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+  pPixmapPriv -> isVirtual = False;
+  pPixmapPriv -> isShared = nxagentShmPixmapTrap;
+
+  /*
+   * The shared memory pixmaps are never
+   * synchronized with the remote X Server.
+   */
+
+  if (pPixmapPriv -> isShared == 1)
+  {
+    BoxRec box;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = width;
+    box.y2 = height;
+
+    pPixmapPriv -> corruptedRegion = REGION_CREATE(pPixmap -> drawable.pScreen, &box, 1);
+  }
+  else
+  {
+    pPixmapPriv -> corruptedRegion = REGION_CREATE(pPixmap -> drawable.pScreen, (BoxRec *) NULL, 1);
+  }
+
+  pPixmapPriv -> corruptedBackground = 0;
+
+  pPixmapPriv -> containGlyphs = 0;
+  pPixmapPriv -> containTrapezoids = 0;
+
+  /*
+   * The lazy encoding policy generally does
+   * not send on remote X server the off-screen
+   * images, by preferring to synchronize the
+   * windows content. Anyway this behaviour may
+   * be inadvisable if a pixmap is used, for
+   * example, for multiple copy areas on screen.
+   * This counter serves the purpose, taking in-
+   * to account the number of times the pixmap
+   * has been used as source for a deferred
+   * operation. 
+   */
+
+  pPixmapPriv -> usageCounter = 0;
+
+  pPixmapPriv -> corruptedBackgroundId = 0;
+  pPixmapPriv -> corruptedId = 0;
+
+  pPixmapPriv -> synchronizationBitmap = NullPixmap;
+
+  pPixmapPriv -> corruptedTimestamp = 0;
+
+  pPixmapPriv -> splitResource = NULL;
+
+  pPixmapPriv -> isBackingPixmap = 0;
+
+  /*
+   * Create the pixmap based on the default
+   * windows. The proxy knows this and uses
+   * this information to optimize encode the
+   * create pixmap message by including the
+   * id of the drawable in the checksum.
+   */
+
+  if (width != 0 && height != 0 && nxagentGCTrap == 0)
+  {
+    pPixmapPriv -> id = XCreatePixmap(nxagentDisplay,
+                                      nxagentDefaultWindows[pScreen -> myNum],
+                                      width, height, depth);
+  }
+  else
+  {
+    pPixmapPriv -> id = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCreatePixmap: Skipping the creation of pixmap at [%p] on real "
+                "X server with nxagentGCTrap [%d].\n", (void *) pPixmap, nxagentGCTrap);
+    #endif
+  }
+
+  pPixmapPriv -> mid = FakeClientID(serverClient -> index);
+
+  AddResource(pPixmapPriv -> mid, RT_NX_PIXMAP, pPixmap);
+
+  pPixmapPriv -> pRealPixmap = pPixmap;
+  pPixmapPriv -> pVirtualPixmap = NULL;
+  pPixmapPriv -> pPicture = NULL;
+
+  /*
+   * Create the pixmap in the virtual framebuffer.
+   */
+
+  pVirtual = fbCreatePixmap(pScreen, width, height, depth);
+
+  if (pVirtual == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCreatePixmap: PANIC! Failed to create virtual pixmap with "
+                "width [%d] height [%d] depth [%d].\n", width, height, depth);
+    #endif
+
+    nxagentDestroyPixmap(pPixmap);
+
+    return NullPixmap;
+  }
+
+  #ifdef TEST
+  fprintf(stderr,"nxagentCreatePixmap: Allocated memory for the Virtual %sPixmap %p of real Pixmap %p (%dx%d)\n",
+              nxagentShmPixmapTrap ? "Shm " : "", (void *) pVirtual, (void *) pPixmap, width, height);
+  #endif
+
+  pPixmapPriv -> pVirtualPixmap = pVirtual;
+
+  /*
+   * Initialize the privates of the virtual picture. We
+   * could avoid to use a flag and just check the pointer
+   * to the virtual pixmap that, if the pixmap is actually
+   * virtual, will be NULL. Unfortunately the flag can be
+   * changed in nxagentValidateGC(). That code should be
+   * removed in future.
+   */
+
+  pVirtualPriv = nxagentPixmapPriv(pVirtual);
+
+  pVirtualPriv -> isVirtual = True;
+  pVirtualPriv -> isShared = nxagentShmPixmapTrap;
+
+  pVirtualPriv -> corruptedRegion = REGION_CREATE(pVirtual -> drawable.pScreen, (BoxRec *) NULL, 1);
+
+  pVirtualPriv -> corruptedBackground = 0;
+
+  pVirtualPriv -> containGlyphs = 0;
+  pVirtualPriv -> containTrapezoids = 0;
+
+  pVirtualPriv -> usageCounter = 0;
+
+  pVirtualPriv -> corruptedBackgroundId = 0;
+  pVirtualPriv -> corruptedId = 0;
+
+  pVirtualPriv -> synchronizationBitmap = NullPixmap;
+
+  pVirtualPriv -> corruptedTimestamp = 0;
+
+  pVirtualPriv -> splitResource = NULL;
+
+  /*
+   * We might distinguish real and virtual pixmaps by
+   * checking the pointers to pVirtualPixmap. We should
+   * also remove the copy of id and use the one of the
+   * real pixmap.
+   */
+   
+  pVirtualPriv -> id = pPixmapPriv -> id;
+  pVirtualPriv -> mid = 0;
+
+  /*
+   * Storing a pointer back to the real pixmap is
+   * silly. Unfortunately this is the way it has
+   * been originally implemented. See also the
+   * comment in destroy of the pixmap.
+   */
+
+  pVirtualPriv -> pRealPixmap = pPixmap;
+  pVirtualPriv -> pVirtualPixmap = NULL;
+  pVirtualPriv -> pPicture = NULL;
+
+  /*
+   * Check that the virtual pixmap is created with
+   * the appropriate bits-per-plane, otherwise free
+   * everything and return.
+   */
+
+  if (pVirtual -> drawable.bitsPerPixel == 0)
+  {
+    #ifdef WARNING
+
+    fprintf(stderr, "nxagentCreatePixmap: WARNING! Virtual pixmap at [%p] has invalid "
+                "bits per pixel.\n", (void *) pVirtual);
+
+    fprintf(stderr, "nxagentCreatePixmap: WARNING! Real pixmap created with width [%d] "
+                "height [%d] depth [%d] bits per pixel [%d].\n", pPixmap -> drawable.width,
+                    pPixmap -> drawable.height = height, pPixmap -> drawable.depth,
+                        pPixmap -> drawable.bitsPerPixel);
+
+    #endif
+
+    if (!nxagentRenderTrap)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "Warning: Disabling render extension due to missing pixmap format.\n");
+      #endif
+
+      nxagentRenderTrap = 1;
+    }
+
+    nxagentDestroyPixmap(pPixmap);
+
+    return NullPixmap;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreatePixmap: Created pixmap at [%p] virtual at [%p] with width [%d] "
+              "height [%d] depth [%d].\n", (void *) pPixmap, (void *) pVirtual,
+                  width, height, depth);
+  #endif
+
+  return pPixmap;
+}
+
+Bool nxagentDestroyPixmap(PixmapPtr pPixmap)
+{
+  PixmapPtr pVirtual;
+
+  nxagentPrivPixmapPtr pPixmapPriv;
+
+  if (!pPixmap)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentDestroyPixmap: PANIC! Invalid attempt to destroy "
+                "a null pixmap pointer.\n");
+    #endif
+
+    return False;
+  }
+
+  pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+  pVirtual = pPixmapPriv -> pVirtualPixmap;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyPixmap: Destroying pixmap at [%p] with virtual at [%p].\n",
+              (void *) pPixmap, (void *) pVirtual);
+  #endif
+
+  if (pPixmapPriv -> isVirtual)
+  {
+    int refcnt;
+
+    /*
+     * For some pixmaps we receive the destroy only for the
+     * virtual. Infact to draw in the framebuffer we can use
+     * the virtual pixmap instead of the pointer to the real
+     * one. As the virtual pixmap can collect references, we
+     * must transfer those references to the real pixmap so
+     * we can continue as the destroy had been requested for
+     * it.
+     */
+
+    pVirtual = pPixmap;
+    pPixmap  = pPixmapPriv -> pRealPixmap;
+
+    pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+    /*
+     * Move the references accumulated by the virtual
+     * pixmap into the references of the real one.
+     */
+
+    refcnt = pVirtual -> refcnt - 1;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentDestroyPixmap: Adding [%d] references to pixmap at [%p].\n",
+                refcnt, (void *) pPixmap);
+    #endif
+
+    pPixmap -> refcnt += refcnt;
+
+    pVirtual -> refcnt -= refcnt;
+  }
+
+  --pPixmap -> refcnt;
+
+  #ifdef TEST
+
+  fprintf(stderr, "nxagentDestroyPixmap: Pixmap has now [%d] references with virtual pixmap [%d].\n",
+              pPixmap -> refcnt, pVirtual -> refcnt);
+
+  if (pVirtual != NULL && pVirtual -> refcnt != 1)
+  {
+    fprintf(stderr, "nxagentDestroyPixmap: PANIC! Virtual pixmap has [%d] references.\n",
+                pVirtual -> refcnt);
+  }
+
+  #endif
+
+  if (pPixmap -> refcnt > 0)
+  {
+    return True;
+  }
+
+  #ifdef TEST
+
+  fprintf(stderr, "nxagentDestroyPixmap: Managing to destroy the pixmap at [%p]\n",
+              (void *) pPixmap);
+  #endif
+
+  nxagentRemoveItemBSPixmapList(nxagentPixmap(pPixmap));
+
+  nxagentDestroyVirtualPixmap(pPixmap);
+
+  if (pPixmapPriv -> corruptedRegion != NullRegion)
+  {
+    REGION_DESTROY(pPixmap -> drawable.pScreen, pPixmapPriv -> corruptedRegion);
+
+    pPixmapPriv -> corruptedRegion = NullRegion;
+  }
+
+  if (nxagentSynchronization.pDrawable == (DrawablePtr) pPixmap)
+  {
+    nxagentSynchronization.pDrawable = NULL;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentDestroyPixmap: Synchronization drawable [%p] removed from resources.\n",
+                (void *) pPixmap);
+    #endif
+  }
+
+  nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_BACKGROUND);
+
+  nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+
+  nxagentDestroyDrawableBitmap((DrawablePtr) pPixmap);
+
+  if (pPixmapPriv -> splitResource != NULL)
+  {
+    nxagentReleaseSplit((DrawablePtr) pPixmap);
+  }
+
+  /*
+   * A pixmap with width and height set to 0 is
+   * created at the beginning. To this pixmap is
+   * not assigned an id. This is likely a scratch
+   * pixmap used by the X server.
+   */
+
+  if (pPixmapPriv -> id)
+  {
+    XFreePixmap(nxagentDisplay, pPixmapPriv -> id);
+  }
+
+  if (pPixmapPriv -> mid)
+  {
+    FreeResource(pPixmapPriv -> mid, RT_NONE);
+  }
+
+  xfree(pPixmap);
+
+  return True;
+}
+
+Bool nxagentDestroyVirtualPixmap(PixmapPtr pPixmap)
+{
+  PixmapPtr pVirtual;
+  nxagentPrivPixmapPtr pVirtualPriv;
+
+  pVirtual = nxagentPixmapPriv(pPixmap) -> pVirtualPixmap;
+
+  /*
+   * Force the routine to get rid of the virtual
+   * pixmap.
+   */
+
+  if (pVirtual != NULL)
+  {
+    pVirtual -> refcnt = 1;
+
+    pVirtualPriv = nxagentPixmapPriv(pVirtual);
+
+    if (pVirtualPriv -> corruptedRegion != NullRegion)
+    {
+      REGION_DESTROY(pVirtual -> drawable.pScreen, pVirtualPriv -> corruptedRegion);
+
+      pVirtualPriv -> corruptedRegion = NullRegion;
+    }
+
+    fbDestroyPixmap(pVirtual);
+  }
+
+  return True;
+}
+
+RegionPtr nxagentPixmapToRegion(PixmapPtr pPixmap)
+{
+  #ifdef TEST
+  fprintf(stderr, "PixmapToRegion: Pixmap = [%p] nxagentVirtualPixmap = [%p]\n",
+              (void *) pPixmap, (void *) nxagentVirtualPixmap(pPixmap));
+  #endif
+
+  return fbPixmapToRegion(nxagentVirtualPixmap(pPixmap));
+}
+
+Bool nxagentModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
+                                   int bitsPerPixel, int devKind, pointer pPixData)
+{
+  PixmapPtr pVirtualPixmap;
+
+  /*
+   * See miModifyPixmapHeader() in miscrinit.c. This
+   * function is used to recycle the scratch pixmap
+   * for this screen. We let it refer to the virtual
+   * pixmap.
+   */
+
+  if (!pPixmap)
+  {
+    return False;
+  }
+
+  if (nxagentPixmapIsVirtual(pPixmap))
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentModifyPixmapHeader: PANIC! Pixmap at [%p] is virtual.\n",
+                (void *) pPixmap);
+    #endif
+
+    FatalError("nxagentModifyPixmapHeader: PANIC! Pixmap is virtual.");
+  }
+
+  pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentModifyPixmapHeader: Pixmap at [%p] Virtual at [%p].\n",
+              (void *) pPixmap, (void *) pVirtualPixmap);
+
+  fprintf(stderr, "nxagentModifyPixmapHeader: Pixmap has width [%d] height [%d] depth [%d] "
+              "bits-per-pixel [%d] devKind [%d] pPixData [%p].\n", pPixmap->drawable.width,
+                  pPixmap->drawable.height, pPixmap->drawable.depth, pPixmap->drawable.bitsPerPixel,
+                      pPixmap->devKind, (void *) pPixmap->devPrivate.ptr);
+
+  fprintf(stderr, "nxagentModifyPixmapHeader: New parameters are width [%d] height [%d] depth [%d] "
+              "bits-per-pixel [%d] devKind [%d] pPixData [%p].\n", width, height, depth,
+                  bitsPerPixel, devKind, (void *) pPixData);
+  #endif
+
+  if ((width > 0) && (height > 0) && (depth > 0) &&
+          (bitsPerPixel > 0) && (devKind > 0) && pPixData)
+  {
+    pPixmap->drawable.depth = depth;
+    pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+    pPixmap->drawable.id = 0;
+    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+    pPixmap->drawable.x = 0;
+    pPixmap->drawable.y = 0;
+    pPixmap->drawable.width = width;
+    pPixmap->drawable.height = height;
+    pPixmap->devKind = devKind;
+    pPixmap->refcnt = 1;
+    pPixmap->devPrivate.ptr = pPixData;
+
+    pVirtualPixmap->drawable.depth = depth;
+    pVirtualPixmap->drawable.bitsPerPixel = bitsPerPixel;
+    pVirtualPixmap->drawable.id = 0;
+    pVirtualPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+    pVirtualPixmap->drawable.x = 0;
+    pVirtualPixmap->drawable.y = 0;
+    pVirtualPixmap->drawable.width = width;
+    pVirtualPixmap->drawable.height = height;
+    pVirtualPixmap->devKind = devKind;
+    pVirtualPixmap->refcnt = 1;
+    pVirtualPixmap->devPrivate.ptr = pPixData;
+  }
+  else
+  {
+    if (width > 0)
+        pPixmap->drawable.width = width;
+
+    if (height > 0)
+        pPixmap->drawable.height = height;
+
+    if (depth > 0)
+        pPixmap->drawable.depth = depth;
+
+    if (bitsPerPixel > 0)
+        pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+    else if ((bitsPerPixel < 0) && (depth > 0))
+        pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
+
+    if (devKind > 0)
+        pPixmap->devKind = devKind;
+    else if ((devKind < 0) && ((width > 0) || (depth > 0)))
+        pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width,
+            pPixmap->drawable.depth);
+
+    if (pPixData)
+       pPixmap->devPrivate.ptr = pPixData; 
+
+     /*
+      * XXX This was the previous assignment:
+      *
+      * pVirtualPixmap->devPrivate.ptr = pPixData;
+      */
+
+    if (width > 0)
+        pVirtualPixmap->drawable.width = width;
+
+    if (height > 0)
+        pVirtualPixmap->drawable.height = height;
+
+    if (depth > 0)
+        pVirtualPixmap->drawable.depth = depth;
+
+    if (bitsPerPixel > 0)
+        pVirtualPixmap->drawable.bitsPerPixel = bitsPerPixel;
+    else if ((bitsPerPixel < 0) && (depth > 0))
+        pVirtualPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
+
+    if (devKind > 0)
+        pVirtualPixmap->devKind = devKind;
+    else if ((devKind < 0) && ((width > 0) || (depth > 0)))
+        pVirtualPixmap->devKind = PixmapBytePad(pVirtualPixmap->drawable.width,
+            pVirtualPixmap->drawable.depth);
+
+    if (pPixData)
+        pVirtualPixmap->devPrivate.ptr = pPixData;
+
+    #ifdef PANIC
+
+    if (pPixmap->drawable.x != 0 || pPixmap->drawable.y != 0)
+    {
+      fprintf(stderr, "nxagentModifyPixmapHeader: PANIC! Pixmap at [%p] has x [%d] and y [%d].\n",
+                  (void *) pPixmap, pPixmap->drawable.x, pPixmap->drawable.y);
+
+      FatalError("nxagentModifyPixmapHeader: PANIC! Pixmap has x or y greater than zero.");
+    }
+
+    #endif
+  }
+
+  return True;
+}
+
+static void nxagentPixmapMatchID(void *p0, XID x1, void *p2)
+{
+  PixmapPtr pPixmap = (PixmapPtr)p0;
+  struct nxagentPixmapPair *pPair = p2;
+
+  if ((pPair -> pMap == NULL) && (nxagentPixmap(pPixmap) == pPair -> pixmap))
+  {
+    pPair -> pMap = pPixmap;
+  }
+}
+
+PixmapPtr nxagentPixmapPtr(Pixmap pixmap)
+{
+  int i;
+  struct nxagentPixmapPair pair;
+
+  if (pixmap == None)
+  {
+    return NULL;
+  }
+
+  pair.pixmap = pixmap;
+  pair.pMap = NULL;
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP,
+                                nxagentPixmapMatchID, &pair);
+
+  for (i = 0; (pair.pMap == NULL) && (i < MAXCLIENTS); i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], RT_PIXMAP,
+                                    nxagentPixmapMatchID, &pair);
+    }
+  }
+
+  #ifdef WARNING
+
+  if (pair.pMap == NULL)
+  {
+    fprintf(stderr, "nxagentFindPixmap: WARNING! Failed to find "
+	    "remote pixmap [%ld].\n", (long int) pair.pixmap);
+  }
+  else if (nxagentDrawableStatus((DrawablePtr) pair.pMap) == NotSynchronized)
+  {
+    fprintf(stderr, "WARNING! Rootless icon at [%p] [%d,%d] is not synchronized.\n",
+                (void *) pair.pMap, pair.pMap -> drawable.width,
+                    pair.pMap -> drawable.height);
+  }
+
+  #endif
+
+  return pair.pMap;
+}
+
+/*
+ * Reconnection stuff.
+ */
+
+int nxagentDestroyNewPixmapResourceType(pointer p, XID id)
+{
+  /*
+   * Address of the destructor is set in Init.c.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyNewPixmapResourceType: Destroying mirror id [%ld] for pixmap at [%p].\n",
+              nxagentPixmapPriv((PixmapPtr) p) -> mid, (void *) p);
+  #endif
+
+  nxagentPixmapPriv((PixmapPtr) p) -> mid = None;
+
+  return True;
+}
+
+void nxagentDisconnectPixmap(void *p0, XID x1, void *p2)
+{
+  PixmapPtr pPixmap = (PixmapPtr) p0;
+
+  Bool *pBool;
+
+  pBool = (Bool*) p2;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectPixmap: Called with bool [%d] and pixmap at [%p].\n",
+              *pBool, (void *) pPixmap);
+
+  fprintf(stderr, "nxagentDisconnectPixmap: Virtual pixmap is [%ld].\n",
+              nxagentPixmap(pPixmap));
+  #endif
+
+  nxagentPixmap(pPixmap) = None;
+
+  if (nxagentDrawableStatus((DrawablePtr) pPixmap) == NotSynchronized)
+  {
+    nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_BACKGROUND);
+
+    nxagentDestroyCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+  }
+}
+
+Bool nxagentDisconnectAllPixmaps()
+{
+  int r = 1;
+  int i;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectAllPixmaps: Going to iterate through pixmap resources.\n");
+  #endif
+
+  /*
+   * The RT_NX_PIXMAP resource type is allocated
+   * only on the server client, so we don't need
+   * to find it through the other clients too.
+   */
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP, nxagentDisconnectPixmap, &r);
+
+  #ifdef WARNING
+
+  if (r == 0)
+  {
+    fprintf(stderr, "nxagentDisconnectAllPixmaps: WARNING! Failed to disconnect "
+                "pixmap for client [%d].\n", serverClient -> index);
+  }
+
+  #endif
+
+  for (i = 0, r = 1; i < MAXCLIENTS; r = 1, i++)
+  {
+    if (clients[i])
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentDisconnectAllPixmaps: Going to disconnect pixmaps of client [%d].\n", i);
+      #endif
+
+      FindClientResourcesByType(clients[i], RT_PIXMAP, nxagentDisconnectPixmap, &r);
+
+      #ifdef WARNING
+
+      if (r == 0)
+      {
+        fprintf(stderr, "nxagentDisconnectAllPixmaps: WARNING! Failed to disconnect "
+                    "pixmap for client [%d].\n", i);
+      }
+
+      #endif
+    }
+  }
+
+  #ifdef WARNING
+
+  if (r == 0)
+  {
+    fprintf(stderr, "nxagentDisconnectAllPixmaps: WARNING! Failed to disconnect "
+                "pixmap for client [%d].\n", i);
+  }
+
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectAllPixmaps: Pixmaps disconnection completed.\n");
+  #endif
+
+  return r;
+}
+
+void nxagentReconnectPixmap(void *p0, XID x1, void *p2)
+{
+  PixmapPtr pPixmap = (PixmapPtr) p0;
+  Bool *pBool = (Bool*) p2;
+  nxagentPrivPixmapPtr pPixmapPriv;
+
+  if (*pBool == 0 || pPixmap == NULL ||
+          NXDisplayError(nxagentDisplay) == 1)
+  {
+    *pBool = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentReconnectPixmap: Ignoring pixmap at [%p] while "
+                "recovering from the error.\n", (void *) pPixmap);
+    #endif
+
+    return;
+  }
+  else if (pPixmap == nxagentDefaultScreen -> pScratchPixmap)
+  {
+    /*
+     * Every time the scratch pixmap is used its
+     * data is changed, so we don't need to recon-
+     * nect it.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentReconnectPixmap: Ignoring scratch pixmap at [%p].\n",
+                (void *) pPixmap);
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectPixmap: Called with result [%d] and pixmap at [%p].\n",
+              *pBool, (void *) pPixmap);
+
+  fprintf(stderr, "nxagentReconnectPixmap: Virtual pixmap is at [%p] picture is at [%p].\n",
+              (void *) nxagentPixmapPriv(pPixmap) -> pVirtualPixmap,
+                  (void *) nxagentPixmapPriv(pPixmap) -> pPicture);
+  #endif
+
+  pPixmapPriv = nxagentPixmapPriv(pPixmap);
+
+  if (pPixmap -> drawable.width && pPixmap -> drawable.height)
+  {
+    pPixmapPriv -> id = XCreatePixmap(nxagentDisplay,
+                                      nxagentDefaultWindows[pPixmap -> drawable.pScreen -> myNum],
+                                      pPixmap -> drawable.width,
+                                      pPixmap -> drawable.height,
+                                      pPixmap -> drawable.depth);
+
+    nxagentPixmap(pPixmapPriv -> pVirtualPixmap) = pPixmapPriv -> id;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentReconnectPixmap: Created virtual pixmap with id [%ld] for pixmap at [%p].\n",
+                nxagentPixmap(pPixmap), (void *) pPixmap);
+    #endif
+
+    if (pPixmap == (PixmapPtr) nxagentDefaultScreen -> devPrivate)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentReconnectPixmap: WARNING! Pixmap is root screen. Returning.\n");
+      #endif
+
+      return;
+    }
+
+    nxagentSplitTrap = 1;
+
+    *pBool = nxagentSynchronizeDrawableData((DrawablePtr) pPixmap, NEVER_BREAK, NULL);
+
+    nxagentSplitTrap = 0;
+
+    if (*pBool == 0)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentReconnectPixmap: PANIC! Failed to synchronize the pixmap.\n");
+      #endif
+    }
+
+     
+    if (nxagentDrawableStatus((DrawablePtr) pPixmap) == NotSynchronized)
+    {
+      if (nxagentIsCorruptedBackground(pPixmap) == 1)
+      {
+        nxagentAllocateCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_BACKGROUND);
+
+        nxagentFillRemoteRegion((DrawablePtr) pPixmap,
+                                    nxagentCorruptedRegion((DrawablePtr) pPixmap));
+      }
+      else
+      {
+        nxagentAllocateCorruptedResource((DrawablePtr) pPixmap, RT_NX_CORR_PIXMAP);
+      }
+    }
+  }
+}
+
+Bool nxagentReconnectAllPixmaps(void *p0)
+{
+  Bool result = 1;
+
+  int i;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectAllPixmaps: Going to recreate all pixmaps.\n");
+  #endif
+
+  /*
+   * Reset the geometry and alpha information
+   * used by proxy to unpack the packed images.
+   */
+
+  nxagentResetVisualCache();
+
+  nxagentResetAlphaCache();
+
+  /*
+   * The RT_NX_PIXMAP resource type is allocated
+   * only on the server client, so we don't need
+   * to find it through the other clients too.
+   */
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP, nxagentReconnectPixmap, &result);
+
+  #ifdef WARNING
+
+  if (result == 0)
+  {
+    fprintf(stderr, "nxagentReconnectAllPixmaps: WARNING! Failed to reconnect "
+                "pixmap for client [%d].\n", serverClient -> index);
+  }
+
+  #endif
+
+  for (i = 0, result = 1; i < MAXCLIENTS; result = 1, i++)
+  {
+    if (clients[i] != NULL)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentReconnectAllPixmaps: Going to reconnect pixmaps of client [%d].\n", i);
+      #endif
+
+      /*
+       * Let the pixmap be reconnected as it was an
+       * image request issued by the client owning
+       * the resource. The client index is used as
+       * a subscript by the image routines to cache
+       * the data per-client.
+       */
+
+      FindClientResourcesByType(clients[i], RT_PIXMAP, nxagentReconnectPixmap, &result);
+
+      #ifdef WARNING
+
+      if (result == 0)
+      {
+        fprintf(stderr, "nxagentReconnectAllPixmaps: WARNING! Failed to reconnect "
+                    "pixmap for client [%d].\n", serverClient -> index);
+      }
+
+      #endif
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectAllPixmaps: Pixmaps reconnection completed.\n");
+  #endif
+
+  return result;
+}
+
+#ifdef TEST
+
+static void nxagentCheckOnePixmapIntegrity(void *p0, XID x1, void *p2)
+{
+  PixmapPtr pPixmap = (PixmapPtr) p0;
+  Bool      *pBool = (Bool*) p2;
+
+  if (*pBool == False)
+  {
+    return;
+  }
+
+  if (pPixmap == nxagentDefaultScreen -> devPrivate)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCheckOnePixmapIntegrity: pixmap %p is screen.\n",
+                (void *) pPixmap);
+    #endif
+
+    return;
+  }
+
+  if (pPixmap == nxagentDefaultScreen -> PixmapPerDepth[0])
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCheckOnePixmapIntegrity: pixmap %p is default stipple of screen.\n",
+                (void *) pPixmap);
+    #endif
+
+    return;
+  }
+
+  *pBool = nxagentCheckPixmapIntegrity(pPixmap);
+}
+
+Bool nxagentCheckPixmapIntegrity(PixmapPtr pPixmap)
+{
+  Bool integrity = 1;
+  XImage *image;
+  char *data;
+  int format;
+  unsigned long plane_mask = AllPlanes;
+  unsigned int width, height, length, depth;
+  PixmapPtr pVirtual = nxagentVirtualPixmap(pPixmap);
+
+  width = pPixmap -> drawable.width;
+  height = pPixmap -> drawable.height;
+  depth = pPixmap -> drawable.depth;
+  format = (depth == 1) ? XYPixmap : ZPixmap;
+
+  if (width && height)
+  {
+    length = nxagentImageLength(width, height, format, 0, depth);
+
+    data = malloc(length);
+
+    if (data == NULL)
+    {
+      FatalError("nxagentCheckPixmapIntegrity: Failed to allocate a buffer of size %d.\n", length);
+    }
+
+    image = XGetImage(nxagentDisplay, nxagentPixmap(pPixmap), 0, 0,
+                          width, height, plane_mask, format);
+    if (image == NULL)
+    {
+      FatalError("XGetImage: Failed.\n");
+
+      free(data);
+
+      return False;
+    }
+
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCheckPixmapIntegrity: Image from X has length [%d] and checksum [0x%s].\n",
+                length, nxagentChecksum(image->data, length));
+    #endif
+
+    NXCleanImage(image);
+
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCheckPixmapIntegrity: Image after clean has checksum [0x%s].\n",
+                nxagentChecksum(image->data, length));
+    #endif
+
+    fbGetImage((DrawablePtr) pVirtual, 0, 0, width, height, format, plane_mask, data);
+
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCheckPixmapIntegrity: Image from FB has length [%d] and checksum [0x%s].\n",
+                length, nxagentChecksum(data, length));
+    #endif
+
+    if (image != NULL && memcmp(image -> data, data, length) != 0)
+    {
+      integrity = 0;
+    }
+    else
+    {
+      integrity = 1;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentCheckPixmapIntegrity: Pixmap at [%p] has been realized. "
+                  "Now remote and frambuffer data are synchronized.\n", (void *) pPixmap);
+      #endif
+    }
+
+    #ifdef WARNING
+
+    if (integrity == 0)
+    {
+
+      int i;
+      char *p, *q;
+
+      for (i = 0, p = image -> data, q = data; i < length; i++)
+      {
+        if (p[i] != q[i])
+        {
+          fprintf(stderr, "nxagentCheckPixmapIntegrity: Byte [%d] image -> data [%d] data [%d]. "
+                      "Buffers differ!\n", i, p[i], q[i]);
+        }
+        else
+        {
+          fprintf(stderr, "nxagentCheckPixmapIntegrity: Byte [%d] image -> data [%d] data [%d].\n",
+                      i, p[i], q[i]);
+        }
+      }
+
+      fprintf(stderr, "nxagentCheckPixmapIntegrity: Pixmap at [%p] width [%d], height [%d], has been realized "
+                  "but the data buffer still differs.\n", (void *) pPixmap, width, height);
+
+      fprintf(stderr, "nxagentCheckPixmapIntegrity: bytes_per_line [%d] byte pad [%d] format [%d].\n",
+                  image -> bytes_per_line, nxagentImagePad(width, height, 0, depth), image -> format);
+
+      FatalError("nxagentCheckPixmapIntegrity: Image is corrupted!!\n");
+
+    }
+
+    #endif
+
+    if (image != NULL)
+    {
+      XDestroyImage(image);
+    }
+
+    if (data != NULL)
+    {
+      free(data);
+    }
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCheckPixmapIntegrity: Ignored pixmap at [%p] with geometry [%d] [%d].\n",
+                (void *) pPixmap, width, height);
+    #endif
+  }
+
+  return integrity;
+}
+
+Bool nxagentCheckAllPixmapIntegrity()
+{
+  int i;
+  Bool imageIsGood = True;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCheckAllPixmapIntegrity\n");
+  #endif
+
+  FindClientResourcesByType(clients[serverClient -> index], RT_NX_PIXMAP,
+                                nxagentCheckOnePixmapIntegrity, &imageIsGood);
+
+  for (i = 0; (i < MAXCLIENTS) && (imageIsGood); i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], RT_PIXMAP,
+                                    nxagentCheckOnePixmapIntegrity, &imageIsGood);
+
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCheckAllPixmapIntegrity: pixmaps integrity = %d.\n", imageIsGood);
+  #endif
+
+  return imageIsGood;
+}
+
+#endif
+
+void nxagentSynchronizeShmPixmap(DrawablePtr pDrawable, int xPict, int yPict,
+                                     int wPict, int hPict)
+{
+  GCPtr pGC;
+  char *data;
+  int width, height;
+  int depth, length, format;
+  CARD32 attributes[3];
+
+  int saveTrap;
+
+  if (pDrawable -> type == DRAWABLE_PIXMAP &&
+         nxagentIsShmPixmap((PixmapPtr) pDrawable) == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSynchronizeShmPixmap: WARNING! Synchronizing shared pixmap at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    pGC = nxagentGetScratchGC(pDrawable -> depth, pDrawable -> pScreen);
+
+    attributes[0] = 0x228b22;
+    attributes[1] = 0xffffff;
+    attributes[2] = FillSolid;
+
+    ChangeGC(pGC, GCForeground | GCBackground | GCFillStyle, attributes);
+
+    ValidateGC(pDrawable, pGC);
+
+    width  = (wPict != 0 && wPict <= pDrawable -> width) ? wPict : pDrawable -> width;
+    height = (hPict != 0 && hPict <= pDrawable -> height) ? hPict : pDrawable -> height;
+
+    depth  = pDrawable -> depth;
+
+    format = (depth == 1) ? XYPixmap : ZPixmap;
+
+    length = nxagentImageLength(width, height, format, 0, depth);
+
+    saveTrap = nxagentGCTrap;
+
+    nxagentGCTrap = 0;
+
+    nxagentSplitTrap = 1;
+
+    nxagentFBTrap = 1;
+
+    if ((data = xalloc(length)) != NULL)
+    {
+      fbGetImage(nxagentVirtualDrawable(pDrawable), xPict, yPict,
+                     width, height, format, 0xffffffff, data);
+
+      nxagentPutImage(pDrawable, pGC, depth, xPict, yPict,
+                          width, height, 0, format, data);
+
+      xfree(data);
+    }
+    #ifdef WARNING
+    else
+    {
+      fprintf(stderr, "nxagentSynchronizeShmPixmap: WARNING! Failed to allocate memory for the operation.\n");
+    }
+    #endif
+
+    nxagentGCTrap = saveTrap;
+
+    nxagentSplitTrap = 0;
+
+    nxagentFBTrap = 0;
+
+    nxagentFreeScratchGC(pGC);
+  }
+}
+
+#ifdef DUMP
+
+/*
+ * This function is useful to visualize a pixmap and check
+ * its data consistency. To avoid the creation of many
+ * windows, one pixmap only can be monitored at a time.
+ */
+
+Bool nxagentPixmapOnShadowDisplay(PixmapPtr pMap)
+{
+  static Display *shadow;
+  static Window win;
+  static int init = True;
+  static int showTime;
+  static PixmapPtr pPixmap;
+  static int depth;
+  static int width;
+  static int height;
+  static int length;
+  static unsigned int format;
+
+  XlibGC gc;
+  XGCValues value;
+  XImage *image;
+  Visual *pVisual;
+  char *data = NULL;
+
+
+  if (init)
+  {
+    if (pMap == NULL)
+    {
+      return False;
+    }
+    else
+    {
+      pPixmap = pMap;
+    }
+
+    depth = pPixmap -> drawable.depth;
+    width = pPixmap -> drawable.width;
+    height = pPixmap -> drawable.height;
+    format = (depth == 1) ? XYPixmap : ZPixmap;
+
+    shadow = XOpenDisplay("localhost:0");
+
+    if (shadow == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentPixmapOnShadowDisplay: WARNING! Shadow display not opened.\n");
+      #endif
+
+      return False;
+    }
+
+    init = False;
+
+    win = XCreateSimpleWindow(shadow, DefaultRootWindow(shadow), 0, 0,
+                                  width, height, 0, 0xFFCC33, 0xFF);
+
+    XMapWindow(shadow, win);
+    XClearWindow(shadow, win);
+  }
+
+/*
+FIXME: If the pixmap has a different depth from the window, the
+       XPutImage returns a BadMatch. For example this may happens if
+       the Render extension is enabled.
+       Can we fix this creating a new pixmap?
+*/
+
+  if (DisplayPlanes(shadow, DefaultScreen(shadow)) != depth)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentPixmapOnShadowDisplay: Pixmap and Window depths [%d - %d] are not equals!\n",
+                depth, DisplayPlanes(shadow, DefaultScreen(shadow)));
+    #endif
+
+    return False;
+  }
+
+  /*
+   * If the framebuffer is updated continuously, the nxagent
+   * visualization become too much slow.
+   */
+
+  if ((GetTimeInMillis() - showTime) < 500)
+  {
+    return False;
+  }
+
+  showTime = GetTimeInMillis();
+
+  length = nxagentImageLength(width, height, format, 0, depth);
+
+  if ((data = xalloc(length)) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentPixmapOnShadowDisplay: WARNING! Failed to allocate memory for the operation.\n");
+    #endif
+
+    return False;
+  }
+
+  fbGetImage((DrawablePtr) nxagentVirtualPixmap(pPixmap), 0, 0,
+                 width, height, format, AllPlanes, data);
+
+  pVisual = nxagentImageVisual((DrawablePtr) pPixmap, depth);
+
+  if (pVisual == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentPixmapOnShadowDisplay: WARNING! Visual not found. Using default visual.\n");
+    #endif
+    
+    pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+  } 
+
+  image = XCreateImage(nxagentDisplay, pVisual,
+                           depth, format, 0, (char *) data,
+                               width, height, BitmapPad(nxagentDisplay),
+                                   nxagentImagePad(width, format, 0, depth));
+
+  if (image == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentPixmapOnShadowDisplay: XCreateImage failed.\n");
+    #endif
+
+    if (data != NULL)
+    {
+      xfree(data);
+    }
+
+    return False;
+  }
+
+  value.foreground = 0xff0000;
+  value.background = 0x000000;
+  value.plane_mask = 0xffffff;
+  value.fill_style = FillSolid;
+
+  gc = XCreateGC(shadow, win, GCBackground |
+                     GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+  NXCleanImage(image);
+
+  XPutImage(shadow, win, gc, image, 0, 0, 0, 0, width, height);
+
+  XFreeGC(shadow, gc);
+
+  if (image != NULL)
+  {
+    XDestroyImage(image);
+  }
+
+  return True;
+}
+
+Bool nxagentFbOnShadowDisplay()
+{
+  static Display *shadow;
+  static Window win;
+  static int init = True;
+  static int showTime;
+  static int prevWidth, prevHeight;
+
+  XlibGC gc;
+  XGCValues value;
+  XImage *image;
+  Visual *pVisual;
+  WindowPtr pWin = WindowTable[0];
+  unsigned int format;
+  int depth, width, height, length;
+  char *data = NULL;
+
+
+  if (pWin == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbOnShadowDisplay: The parent window is NULL.\n");
+    #endif
+
+    return False;
+  }
+
+  depth = pWin -> drawable.depth;
+  width = pWin -> drawable.width;
+  height = pWin -> drawable.height;
+  format = (depth == 1) ? XYPixmap : ZPixmap;
+
+  if (init)
+  {
+    shadow = XOpenDisplay("localhost:0");
+
+    if (shadow == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentFbOnShadowDisplay: WARNING! Shadow display not opened.\n");
+      #endif
+
+      return False;
+    }
+
+    init = False;
+
+    prevWidth = width;
+    prevHeight = height;
+
+    win = XCreateSimpleWindow(shadow, DefaultRootWindow(shadow), 0, 0,
+                                  width, height, 0, 0xFFCC33, 0xFF);
+
+    XMapWindow(shadow, win);
+    XClearWindow(shadow, win);
+  }
+
+  if (DisplayPlanes(shadow, DefaultScreen(shadow)) != depth)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbOnShadowDisplay: Depths [%d - %d] are not equals!\n",
+                depth, DisplayPlanes(shadow, DefaultScreen(shadow)));
+    #endif
+
+    return False;
+  }
+
+  /*
+   * If the framebuffer is updated continuously, the nxagent
+   * visualization becomes too much slow.
+   */
+
+  if ((GetTimeInMillis() - showTime) < 500)
+  {
+    return False;
+  }
+
+  showTime = GetTimeInMillis();
+
+  /*
+   * If the root window is resized, also the window on shadow
+   * display must be resized.
+   */
+
+  if (prevWidth != width || prevHeight != height)
+  {
+    XWindowChanges values;
+
+    prevWidth = width;
+    prevHeight = height;
+
+    values.width = width;
+    values.height = height;
+    XConfigureWindow(shadow, win, CWWidth | CWHeight, &values);
+  }
+
+  length = nxagentImageLength(width, height, format, 0, depth);
+
+  if ((data = xalloc(length)) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbOnShadowDisplay: WARNING! Failed to allocate memory for the operation.\n");
+    #endif
+
+    return False;
+  }
+
+  fbGetImage((DrawablePtr)pWin, 0, 0,
+                 width, height, format, AllPlanes, data);
+
+  pVisual = nxagentImageVisual((DrawablePtr) pWin, depth);
+
+  if (pVisual == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbOnShadowDisplay: WARNING! Visual not found. Using default visual.\n");
+    #endif
+    
+    pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+  } 
+
+  image = XCreateImage(nxagentDisplay, pVisual,
+                           depth, format, 0, (char *) data,
+                               width, height, BitmapPad(nxagentDisplay),
+                                   nxagentImagePad(width, format, 0, depth));
+
+  if (image == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbOnShadowDisplay: XCreateImage failed.\n");
+    #endif
+
+    if (data)
+    {
+      xfree(data);
+    }
+
+    return False;
+  }
+
+  value.foreground = 0xff0000;
+  value.background = 0x000000;
+  value.plane_mask = 0xffffff;
+  value.fill_style = FillSolid;
+
+  gc = XCreateGC(shadow, win, GCBackground |
+                     GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+  NXCleanImage(image);
+
+  XPutImage(shadow, win, gc, image, 0, 0, 0, 0, width, height);
+
+  XFreeGC(shadow, gc);
+
+  if (image != NULL)
+  {
+    XDestroyImage(image);
+  }
+
+  return True;
+}
+
+#endif
+
+#ifdef DEBUG
+
+void nxagentPrintResourceTypes()
+{
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_PIXMAP [%lu].\n", (unsigned long) RT_PIXMAP);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_NX_PIXMAP [%lu].\n", (unsigned long) RT_NX_PIXMAP);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_GC [%lu].\n", (unsigned long) RT_GC);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_NX_GC [%lu].\n", (unsigned long) RT_NX_GC);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_FONT [%lu].\n", (unsigned long) RT_FONT);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_NX_FONT [%lu].\n", (unsigned long) RT_NX_FONT);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_CURSOR [%lu].\n", (unsigned long) RT_CURSOR);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_WINDOW [%lu].\n", (unsigned long) RT_WINDOW);
+  fprintf(stderr, "nxagentPrintResourceTypes: RT_COLORMAP [%lu].\n", (unsigned long) RT_COLORMAP);
+}
+
+void nxagentPrintResourcePredicate(void *value, XID id, XID type, void *cdata)
+{
+  fprintf(stderr, "nxagentPrintResourcePredicate: Resource [%p] id [%lu] type [%lu].\n",
+              (void *) value, (unsigned long) id, (unsigned long) type);
+}
+
+void nxagentPrintResources()
+{
+  Bool result;
+  int i;
+
+  nxagentPrintResourceTypes();
+
+  for (i = 0; i < MAXCLIENTS; i++)
+  {
+    if (clients[i])
+    {
+      fprintf(stderr, "nxagentPrintResources: Printing resources for client [%d]:\n",
+                  i);
+
+      FindAllClientResources(clients[i], nxagentPrintResourcePredicate, &result);
+    }
+  }
+}
+
+#endif
+
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
new file mode 100644
index 000000000..5cf340d36
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
@@ -0,0 +1,136 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Pixmap_H__
+#define __Pixmap_H__
+
+#include "Split.h"
+
+extern RESTYPE RT_NX_PIXMAP;
+
+/*
+ * Pixmap privates structure.
+ */
+
+typedef struct
+{
+  Pixmap id;
+  XID    mid;
+
+  Bool isVirtual;
+  Bool isShared;
+
+  PixmapPtr pVirtualPixmap;
+  PixmapPtr pRealPixmap;
+
+  void *pPicture;
+
+  RegionPtr corruptedRegion;
+
+  int corruptedBackground;
+
+  int containGlyphs;
+  int containTrapezoids;
+
+  int usageCounter;
+
+  XID corruptedBackgroundId;
+  XID corruptedId;
+
+  PixmapPtr synchronizationBitmap;
+
+  Time corruptedTimestamp;
+
+  SplitResourcePtr splitResource;
+
+  int isBackingPixmap;
+
+} nxagentPrivPixmapRec;
+
+typedef nxagentPrivPixmapRec *nxagentPrivPixmapPtr;
+
+extern int nxagentPixmapPrivateIndex;
+
+/*
+ * Pixmap privates macro.
+ */
+
+#define nxagentPixmapPriv(pPixmap) \
+    ((nxagentPrivPixmapPtr)((pPixmap) -> devPrivates[nxagentPixmapPrivateIndex].ptr))
+
+#define nxagentPixmap(pPixmap) (nxagentPixmapPriv(pPixmap) -> id)
+
+#define nxagentPixmapIsVirtual(pPixmap) \
+    (nxagentPixmapPriv(pPixmap) -> isVirtual)
+
+#define nxagentIsShmPixmap(pPixmap) \
+    (nxagentPixmapPriv(pPixmap) -> isShared)
+
+#define nxagentRealPixmap(pPixmap) \
+    (nxagentPixmapPriv(pPixmap) -> pRealPixmap)
+
+#define nxagentVirtualPixmap(pPixmap) \
+    (nxagentPixmapPriv(pPixmap) -> isVirtual ? pPixmap : \
+         nxagentPixmapPriv(pPixmap) -> pVirtualPixmap)
+
+#define nxagentPixmapCorruptedRegion(pPixmap) \
+    (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> corruptedRegion)
+
+#define nxagentPixmapContainGlyphs(pPixmap) \
+    (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> containGlyphs)
+
+#define nxagentPixmapContainTrapezoids(pPixmap) \
+    (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> containTrapezoids)
+
+#define nxagentIsCorruptedBackground(pPixmap) \
+    (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> corruptedBackground)
+
+#define nxagentPixmapUsageCounter(pPixmap) \
+    (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> usageCounter)
+
+#define nxagentPixmapTimestamp(pPixmap) \
+    (nxagentPixmapPriv(nxagentRealPixmap(pPixmap)) -> corruptedTimestamp)
+
+PixmapPtr nxagentPixmapPtr(Pixmap pixmap);
+
+PixmapPtr nxagentCreatePixmap(ScreenPtr pScreen, int width,
+                                  int height, int depth);
+
+Bool nxagentDestroyPixmap(PixmapPtr pPixmap);
+
+RegionPtr nxagentPixmapToRegion(PixmapPtr pPixmap);
+
+Bool nxagentModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
+                                   int bitsPerPixel, int devKind, pointer pPixData);
+
+RegionPtr nxagentCreateRegion(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+                                  int width, int height);
+
+void nxagentReconnectPixmap(void *p0, XID x1, void *p2);
+Bool nxagentReconnectAllPixmaps(void *p0);
+void nxagentDisconnectPixmap(void *p0, XID x1, void* p2);
+Bool nxagentDisconnectAllPixmaps(void);
+
+int nxagentDestroyNewPixmapResourceType(pointer p, XID id);
+
+void nxagentSynchronizeShmPixmap(DrawablePtr pDrawable, int xPict, int yPict,
+                                     int wPict, int hPict);
+
+Bool nxagentPixmapOnShadowDisplay(PixmapPtr pMap);
+Bool nxagentFbOnShadowDisplay();
+
+#endif /* __Pixmap_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
new file mode 100644
index 000000000..f53dfbe52
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -0,0 +1,157 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "mipointer.h"
+
+#include "Agent.h"
+#include "Args.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Pointer.h"
+#include "Events.h"
+#include "Options.h"
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl)
+{
+  /*
+   * The original behaviour was to reset the pointer settings
+   * (acceleration and alas) to the default values. What the
+   * average user expects, on the contrary, is to have agent
+   * inheriting whatever value is set on the real X display.
+   * Having to reflect changes made inside the agent session,
+   * the correct behavior would be saving the original values
+   * and restoring them as soon as focus leaves the agent's
+   * window.
+   */
+
+  if (nxagentOption(DeviceControl) == True)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentChangePointerControl: WARNING! Propagating changes to pointer settings.\n");
+    #endif
+
+    XChangePointerControl(nxagentDisplay, True, True, 
+                              ctrl->num, ctrl->den, ctrl->threshold);
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentChangePointerControl: WARNING! Not propagating changes to pointer settings.\n");
+  #endif
+}
+
+int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
+{
+  CARD8 map[MAXBUTTONS];
+  int nmap;
+  int i;
+
+  switch (onoff)
+  {
+    case DEVICE_INIT:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_INIT].\n");
+      #endif
+
+      if (NXDisplayError(nxagentDisplay) == 1)
+      {
+        return Success;
+      }
+
+      nmap = XGetPointerMapping(nxagentDisplay, map, MAXBUTTONS);
+      for (i = 0; i <= nmap; i++)
+	map[i] = i; /* buttons are already mapped */
+      InitPointerDeviceStruct((DevicePtr) pDev, map, nmap,
+			      miPointerGetMotionEvents,
+			      nxagentChangePointerControl,
+			      miPointerGetMotionBufferSize());
+      break;
+    case DEVICE_ON:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_ON].\n");
+      #endif
+
+      if (NXDisplayError(nxagentDisplay) == 1)
+      {
+        return Success;
+      }
+
+      nxagentEnablePointerEvents();
+
+      break;
+
+    case DEVICE_OFF:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_OFF].\n");
+      #endif
+
+      if (NXDisplayError(nxagentDisplay) == 1)
+      {
+        return Success;
+      }
+
+      nxagentDisablePointerEvents();
+
+      break;
+
+    case DEVICE_CLOSE:
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentPointerProc: Called for [DEVICE_CLOSE].\n");
+      #endif
+
+      break;
+    }
+
+  return Success;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
new file mode 100644
index 000000000..2adee6cb3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -0,0 +1,45 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Pointer_H__
+#define __Pointer_H__
+
+#define MAXBUTTONS 256
+
+#define NXAGENT_POINTER_EVENT_MASK \
+  (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
+       EnterWindowMask | LeaveWindowMask)
+
+void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl);
+
+int nxagentPointerProc(DeviceIntPtr pDev, int onoff);
+
+#endif /* __Pointer_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
new file mode 100644
index 000000000..de5f78fad
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -0,0 +1,788 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <signal.h>
+
+#include "X.h"
+#include "Xproto.h"
+#include "Xpoll.h"
+#include "mi.h"
+#include "fb.h"
+#include "inputstr.h"
+
+#include "Agent.h"
+#include "Atoms.h"
+#include "Drawable.h"
+#include "Client.h"
+#include "Reconnect.h"
+#include "Display.h"
+#include "Dialog.h"
+#include "Screen.h"
+#include "Windows.h"
+#include "Events.h"
+#include "Dialog.h"
+#include "Args.h"
+#include "Font.h"
+#include "GCs.h"
+#include "Trap.h"
+#include "Keyboard.h"
+#include "Composite.h"
+#include "Millis.h"
+#include "Splash.h"
+#include "Error.h"
+
+#ifdef XKB
+#include "XKBsrv.h"
+#endif
+
+#include "NX.h"
+#include "NXlib.h"
+#include "NXalert.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#define NXAGENT_RECONNECT_DEFAULT_MESSAGE_SIZE  32
+
+extern Bool nxagentReconnectAllCursor(void*);
+extern Bool nxagentReconnectAllColormap(void*);
+extern Bool nxagentReconnectAllWindows(void*);
+extern Bool nxagentReconnectAllGlyphSet(void*);
+extern Bool nxagentReconnectAllPictFormat(void*);
+extern Bool nxagentReconnectAllPicture(void*);
+
+extern Bool nxagentDisconnectAllPicture(void);
+extern Bool nxagentDisconnectAllWindows(void);
+extern Bool nxagentDisconnectAllCursor(void);
+
+extern Bool nxagentReconnectFailedFonts(void*);
+extern Bool nxagentInstallFontServerPath(void);
+extern Bool nxagentUninstallFontServerPath(void);
+
+extern void nxagentRemoveXConnection(void);
+
+static char *nxagentGetReconnectError(void);
+
+void nxagentInitializeRecLossyLevel(void);
+
+static char *nxagentReconnectErrorMessage = NULL;
+static int  nxagentReconnectErrorId;
+
+extern Bool nxagentRenderEnable;
+
+extern char *nxagentKeyboard;
+
+enum SESSION_STATE nxagentSessionState = SESSION_STARTING;
+
+struct nxagentExceptionStruct nxagentException = {0, 0};
+
+enum RECONNECTION_STEP
+{
+  DISPLAY_STEP = 0,
+  SCREEN_STEP,
+  FONT_STEP,
+  PIXMAP_STEP,
+  GC_STEP,
+  CURSOR_STEP,
+  COLORMAP_STEP,
+  WINDOW_STEP,
+  GLYPHSET_STEP,
+  PICTFORMAT_STEP,
+  PICTURE_STEP,
+  STEP_NONE
+};
+
+void *reconnectLossyLevel[STEP_NONE];
+
+static enum RECONNECTION_STEP failedStep;
+
+int nxagentHandleConnectionStates(void)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleConnectionStates: Handling Exception with "
+              "state [%s] and transport [%d] and generation [%ld].\n",
+                  DECODE_SESSION_STATE(nxagentSessionState), NXTransRunning(NX_FD_ANY), serverGeneration);
+  fprintf(stderr, "nxagentHandleConnectionStates: Entering with nxagentException.sigHup = [%d], "
+              "nxagentException.ioError = [%d]\n",
+                  nxagentException.sigHup, nxagentException.ioError);
+  #endif
+
+  if (nxagentException.sigHup > 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleConnectionStates: Got SIGHUP in the exception flags.\n");
+    #endif
+
+    nxagentException.sigHup = 0;
+
+    if (nxagentSessionState == SESSION_UP)
+    {
+      if (nxagentOption(Persistent))
+      {
+        nxagentSessionState = SESSION_GOING_DOWN;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleConnectionStates: Handling "
+                    "signal [SIGHUP] by disconnecting the agent.\n");
+
+        #endif
+
+      }
+      else
+      {
+        nxagentTerminateSession();
+      }
+    }
+    else if (nxagentSessionState == SESSION_STARTING)
+    {
+      nxagentTerminateSession();
+
+      #ifdef WARNING
+      fprintf(stderr, "nxagentHandleConnectionStates: Handling signal [SIGHUP] by terminating the agent.\n");
+      #endif
+    }
+    else if (nxagentSessionState == SESSION_DOWN &&
+                 NXTransRunning(NX_FD_ANY) == 0)
+    {
+      nxagentSessionState = SESSION_GOING_UP;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleConnectionStates: Handling signal [SIGHUP] by reconnecting the agent.\n");
+      #endif
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleConnectionStates: Handling signal with state [%s] and exception [%d].\n",
+                  DECODE_SESSION_STATE(nxagentSessionState), dispatchException);
+      #endif
+    }
+  }
+
+  if (nxagentNeedConnectionChange() == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleConnectionStates: Calling nxagentHandleConnectionChanges "
+                "with ioError [%d] sigHup [%d].\n", nxagentException.ioError, nxagentException.sigHup);
+    #endif
+
+    nxagentHandleConnectionChanges();
+  }
+
+  if (nxagentException.ioError > 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error in the exception flags.\n");
+    #endif
+/*
+TODO: This should be reset only when
+      the state became SESSION_DOWN.
+*/
+    nxagentException.ioError = 0;
+
+    if (nxagentOption(Persistent) == 1 && nxagentSessionState != SESSION_STARTING)
+    {
+      if (nxagentSessionState == SESSION_UP)
+      {
+        if ((dispatchException & DE_TERMINATE) == 0)
+        {
+          fprintf(stderr, "Session: Display failure detected at '%s'.\n", GetTimeAsString());
+
+          fprintf(stderr, "Session: Suspending session at '%s'.\n", GetTimeAsString());
+        }
+
+        nxagentDisconnectSession();
+      }
+      else if (nxagentSessionState == SESSION_GOING_DOWN)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+                    "[SESSION_GOING_DOWN].\n");
+        #endif
+      }
+      else if (nxagentSessionState == SESSION_GOING_UP)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+                    "[SESSION_GOING_UP].\n");
+        #endif
+
+        nxagentSessionState = SESSION_GOING_DOWN;
+
+        nxagentSetReconnectError(FAILED_RESUME_DISPLAY_BROKEN_ALERT,
+                                     "Got I/O error during reconnect.");
+
+        nxagentChangeOption(Fullscreen, False);
+
+        return 1;
+      }
+      else if (nxagentSessionState == SESSION_DOWN)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+                    "[SESSION_DOWN]. Ignoring.\n");
+        #endif
+
+        return 1;
+      }
+      else
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleConnectionStates: Got I/O error with session "
+                    "[%d].\n", nxagentSessionState);
+        #endif
+      }
+
+      nxagentSessionState = SESSION_DOWN;
+
+      if ((dispatchException & DE_TERMINATE) == 0)
+      {
+        fprintf(stderr, "Session: Session suspended at '%s'.\n", GetTimeAsString());
+      }
+
+      nxagentResetDisplayHandlers();
+
+      return 1;
+    }
+
+    fprintf(stderr, "Info: Disconnected from display '%s'.\n", nxagentDisplayName);
+
+    nxagentTerminateSession();
+
+    return -1;
+  }
+
+  return 0;
+}
+
+void nxagentInitializeRecLossyLevel()
+{
+  *(int *)reconnectLossyLevel[DISPLAY_STEP]    = 0;
+  *(int *)reconnectLossyLevel[SCREEN_STEP]     = 0;
+  *(int *)reconnectLossyLevel[FONT_STEP]       = 0;
+  *(int *)reconnectLossyLevel[PIXMAP_STEP]     = 0;
+  *(int *)reconnectLossyLevel[GC_STEP]         = 0;
+  *(int *)reconnectLossyLevel[CURSOR_STEP]     = 0;
+  *(int *)reconnectLossyLevel[COLORMAP_STEP]   = 0;
+  *(int *)reconnectLossyLevel[WINDOW_STEP]     = 0;
+  *(int *)reconnectLossyLevel[GLYPHSET_STEP]   = 0;
+  *(int *)reconnectLossyLevel[PICTFORMAT_STEP] = 0;
+  *(int *)reconnectLossyLevel[PICTURE_STEP]    = 0;
+}
+
+void nxagentInitReconnector(void)
+{
+  nxagentReconnectTrap = 0;
+
+  reconnectLossyLevel[DISPLAY_STEP]    = xalloc(sizeof(int));
+  reconnectLossyLevel[SCREEN_STEP]     = xalloc(sizeof(int));
+  reconnectLossyLevel[FONT_STEP]       = xalloc(sizeof(int));
+  reconnectLossyLevel[PIXMAP_STEP]     = xalloc(sizeof(int));
+  reconnectLossyLevel[GC_STEP]         = xalloc(sizeof(int));
+  reconnectLossyLevel[CURSOR_STEP]     = xalloc(sizeof(int));
+  reconnectLossyLevel[COLORMAP_STEP]   = xalloc(sizeof(int));
+  reconnectLossyLevel[WINDOW_STEP]     = xalloc(sizeof(int));
+  reconnectLossyLevel[GLYPHSET_STEP]   = xalloc(sizeof(int));
+  reconnectLossyLevel[PICTFORMAT_STEP] = xalloc(sizeof(int));
+  reconnectLossyLevel[PICTURE_STEP]    = xalloc(sizeof(int));
+}
+
+void nxagentDisconnectSession(void)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectSession: Disconnecting session with state [%s].\n",
+              DECODE_SESSION_STATE(nxagentSessionState));
+  #endif
+
+  /*
+   * Force an I/O error on the display
+   * and wait until the NX transport
+   * is gone.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectSession: Disconnecting the X display.\n");
+  #endif
+
+  nxagentWaitDisplay();
+
+  /*
+   * Prepare for the next reconnection.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectSession: Disconnecting all X resources.\n");
+  #endif
+
+  nxagentInitializeRecLossyLevel();
+
+  nxagentBackupDisplayInfo();
+
+  if (nxagentOption(Rootless))
+  {
+    nxagentFreePropertyList();
+  }
+
+  if (nxagentRenderEnable)
+  {
+    nxagentDisconnectAllPicture();
+  }
+
+  nxagentEmptyAllBackingStoreRegions();
+
+  nxagentDisconnectAllWindows();
+  nxagentDisconnectAllCursor();
+  nxagentDisconnectAllPixmaps();
+  nxagentDisconnectAllGCs();
+  nxagentDisconnectDisplay();
+
+  nxagentWMIsRunning = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectSession: Disconnection completed. SigHup is [%d]. IoError is [%d].\n",
+              nxagentException.sigHup, nxagentException.ioError);
+  #endif
+}
+
+Bool nxagentReconnectSession(void)
+{
+  char *nxagentOldKeyboard = NULL;
+
+  nxagentResizeDesktopAtStartup = False;
+
+  /*
+   * The default is device settings have
+   * not to be propagated to the X server.
+   */
+
+  nxagentChangeOption(DeviceControl, False);
+
+  /*
+   * We need to zero out every new XID
+   * created by the disconnected display.
+   */
+
+  nxagentDisconnectSession();
+
+  /*
+   * Set this in order to let the screen
+   * function to behave differently at
+   * reconnection time.
+   */
+
+  nxagentReconnectTrap = True;
+
+  nxagentSetReconnectError(0, NULL);
+
+  if (nxagentKeyboard != NULL)
+  {
+    int size;
+
+    size = strlen(nxagentKeyboard);
+
+    if ((nxagentOldKeyboard = xalloc(size + 1)) != NULL)
+    {
+      strncpy(nxagentOldKeyboard, nxagentKeyboard, size);
+
+      nxagentOldKeyboard[size] = '\0';
+    }
+  }
+
+  if (nxagentKeyboard)
+  {
+    xfree(nxagentKeyboard);
+
+    nxagentKeyboard = NULL;
+  }
+
+  nxagentSaveOptions();
+
+  nxagentResetOptions();
+
+  nxagentProcessOptionsFile();
+
+  if (nxagentReconnectDisplay(reconnectLossyLevel[DISPLAY_STEP]) == 0)
+  {
+    failedStep = DISPLAY_STEP;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentReconnect: WARNING! Failed display reconnection.\n");
+    #endif
+
+    goto nxagentReconnectError;
+  }
+
+  if (nxagentReconnectScreen(reconnectLossyLevel[SCREEN_STEP]) == 0)
+  {
+    failedStep = SCREEN_STEP;
+
+    goto nxagentReconnectError;
+  }
+
+  nxagentDisconnectAllFonts();
+
+  nxagentListRemoteFonts("*", nxagentMaxFontNames);
+
+  if (nxagentReconnectAllFonts(reconnectLossyLevel[FONT_STEP]) == 0)
+  {
+    if (nxagentReconnectFailedFonts(reconnectLossyLevel[FONT_STEP]) == 0)
+    {
+      failedStep = FONT_STEP;
+
+      goto nxagentReconnectError;
+    }
+    else
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentReconnect: WARNING! Unable to retrieve all the fonts currently in use. "
+                  "Missing fonts have been replaced.\n");
+      #endif
+
+      nxagentLaunchDialog(DIALOG_FONT_REPLACEMENT);
+    }
+  }
+
+  /*
+   * Map the main window and send a
+   * SetSelectionOwner request to
+   * notify of the agent start.
+   */
+
+  nxagentMapDefaultWindows();
+
+  /*
+   * Ensure that the SetSelectionOwner
+   * request is sent through the link.
+   */
+
+  XFlush(nxagentDisplay);
+
+  NXTransContinue(NULL);
+
+  nxagentEmptyBSPixmapList();
+
+  if (nxagentReconnectAllPixmaps(reconnectLossyLevel[PIXMAP_STEP]) == 0)
+  {
+    failedStep = PIXMAP_STEP;
+
+    goto nxagentReconnectError;
+  }
+
+  if (nxagentReconnectAllGCs(reconnectLossyLevel[GC_STEP]) == 0)
+  {
+    failedStep = GC_STEP;
+
+    goto nxagentReconnectError;
+  }
+
+  if (nxagentReconnectAllColormap(reconnectLossyLevel[COLORMAP_STEP]) == 0)
+  {
+    failedStep = COLORMAP_STEP;
+
+    goto nxagentReconnectError;
+  }
+
+  if (nxagentReconnectAllWindows(reconnectLossyLevel[WINDOW_STEP]) == 0)
+  {
+    failedStep = WINDOW_STEP;
+
+    goto nxagentReconnectError;
+  }
+
+  if (nxagentRenderEnable)
+  {
+    if (nxagentReconnectAllGlyphSet(reconnectLossyLevel[GLYPHSET_STEP]) == 0)
+    {
+      failedStep = GLYPHSET_STEP;
+
+      goto nxagentReconnectError;
+    }
+
+    if (nxagentReconnectAllPictFormat(reconnectLossyLevel[PICTFORMAT_STEP]) == 0)
+    {
+      failedStep = PICTFORMAT_STEP;
+
+      goto nxagentReconnectError;
+    }
+
+    if (nxagentReconnectAllPicture(reconnectLossyLevel[PICTURE_STEP]) == 0)
+    {
+      failedStep = PICTURE_STEP;
+
+      goto nxagentReconnectError;
+    }
+  }
+
+  if (nxagentReconnectAllCursor(reconnectLossyLevel[CURSOR_STEP]) == 0)
+  {
+    failedStep = CURSOR_STEP;
+
+    goto nxagentReconnectError;
+  }
+
+  if (nxagentSetWindowCursors(reconnectLossyLevel[WINDOW_STEP]) == 0)
+  {
+    failedStep = WINDOW_STEP;
+
+    goto nxagentReconnectError;
+  }
+
+  if (nxagentOption(ResetKeyboardAtResume))
+  {
+    if (nxagentKeyboard  == NULL || nxagentOldKeyboard == NULL ||
+           strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
+               strcmp(nxagentKeyboard, "query") == 0)
+    {
+      if (nxagentOldKeyboard != NULL)
+      {
+        xfree(nxagentOldKeyboard);
+
+        nxagentOldKeyboard = NULL;
+      }
+
+      if (nxagentResetKeyboard() == 0)
+      {
+        #ifdef WARNING
+        if (nxagentVerbose == 1)
+        {
+          fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
+        }
+        #endif
+
+        failedStep = WINDOW_STEP;
+
+        goto nxagentReconnectError;
+      }
+    }
+  }
+
+  nxagentDeactivatePointerGrab();
+
+  nxagentWakeupByReconnect();
+
+  nxagentFreeGCList();
+
+  nxagentRedirectDefaultWindows();
+
+  if (nxagentResizeDesktopAtStartup || nxagentOption(Rootless) == True)
+  {
+    nxagentRRSetScreenConfig(nxagentDefaultScreen, nxagentOption(RootWidth), nxagentOption(RootHeight));
+
+    nxagentResizeDesktopAtStartup = False;
+  }
+
+  nxagentReconnectTrap = False;
+
+  nxagentExposeArrayIsInitialized = False;
+
+  if (nxagentSessionState != SESSION_GOING_UP)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentReconnect: WARNING! Unexpected session state [%s] while reconnecting.\n",
+                DECODE_SESSION_STATE(nxagentSessionState));
+    #endif
+
+    goto nxagentReconnectError;
+  }
+
+  fprintf(stderr, "Session: Session resumed at '%s'.\n", GetTimeAsString());
+
+  nxagentRemoveSplashWindow(NULL);
+
+  /*
+   * We let the proxy flush the link on our behalf
+   * after having opened the display. We are now
+   * entering again the dispatcher so can flush
+   * the link explicitly.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnect: Setting the NX flush policy to deferred.\n");
+  #endif
+
+  NXSetDisplayPolicy(nxagentDisplay, NXPolicyDeferred);
+
+  nxagentCleanupBackupDisplayInfo();
+
+  return 1;
+
+nxagentReconnectError:
+
+  if (failedStep == DISPLAY_STEP)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentReconnect: Reconnection failed in display step. Restoring options.\n");
+    #endif
+
+    nxagentRestoreOptions();
+  }
+  else
+  {
+    nxagentCleanupBackupDisplayInfo();
+  }
+
+  if (*nxagentGetReconnectError() == '\0')
+  {
+    #ifdef WARNING
+    if (nxagentVerbose == 1)
+    {
+      fprintf(stderr, "nxagentReconnect: WARNING! The reconnect error message is not set. Failed step is [%d].\n",
+                  failedStep);
+    }
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentReconnect: Reconnection failed due to a display error.\n");
+    #endif
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentReconnect: Reconnection failed with reason '%s'\n",
+                nxagentGetReconnectError());
+    #endif
+  }
+
+  if (NXDisplayError(nxagentDisplay) == 0)
+  {
+    nxagentUnmapWindows();
+
+    nxagentFailedReconnectionDialog(nxagentReconnectErrorId, nxagentGetReconnectError());
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentReconnect: Cannot launch the dialog without a valid display.\n");
+  }
+  #endif
+
+  if (failedStep == FONT_STEP)
+  {
+    *((int *) reconnectLossyLevel[FONT_STEP]) = 1;
+  }
+
+  if (nxagentDisplay == NULL)
+  {
+    nxagentDisconnectDisplay();
+  }
+
+  return 0;
+}
+
+void nxagentSetReconnectError(int id, char *format, ...)
+{
+  static int size = 0;
+
+  va_list ap;
+  int n;
+
+  if (format == NULL)
+  {
+    nxagentSetReconnectError(id, "");
+
+    return;
+  }
+
+  nxagentReconnectErrorId = id;
+
+  while (1)
+  {
+    va_start (ap, format);
+
+    n = vsnprintf(nxagentReconnectErrorMessage, size, format, ap);
+
+    va_end(ap);
+
+    if (n > -1 && n < size)
+    {
+      break;
+    }
+    if (n > -1)
+    {
+      size = n + 1;
+    }
+    else
+    {
+      /*
+       * The vsnprintf() in glibc 2.0.6 would return
+       * -1 when the output was truncated. See section
+       * NOTES on printf(3).
+       */
+
+      size = (size ? size * 2 : NXAGENT_RECONNECT_DEFAULT_MESSAGE_SIZE);
+    }
+
+    nxagentReconnectErrorMessage = realloc(nxagentReconnectErrorMessage, size);
+
+    if (nxagentReconnectErrorMessage == NULL)
+    {
+      FatalError("realloc failed");
+    }
+  }
+
+  return;
+}
+
+static char* nxagentGetReconnectError()
+{
+  if (nxagentReconnectErrorMessage == NULL)
+  {
+    nxagentSetReconnectError(nxagentReconnectErrorId, "");
+  }
+
+  return nxagentReconnectErrorMessage;
+}
+
+void nxagentHandleConnectionChanges()
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleConnectionChanges: Called.\n");
+  #endif
+
+  if (nxagentSessionState == SESSION_GOING_DOWN)
+  {
+    fprintf(stderr, "Session: Suspending session at '%s'.\n", GetTimeAsString());
+
+    nxagentDisconnectSession();
+  }
+  else if (nxagentSessionState == SESSION_GOING_UP)
+  {
+    fprintf(stderr, "Session: Resuming session at '%s'.\n", GetTimeAsString());
+
+    if (nxagentReconnectSession())
+    {
+      nxagentSessionState = SESSION_UP;
+    }
+    else
+    {
+      nxagentSessionState = SESSION_GOING_DOWN;
+
+      fprintf(stderr, "Session: Display failure detected at '%s'.\n", GetTimeAsString());
+
+      fprintf(stderr, "Session: Suspending session at '%s'.\n", GetTimeAsString());
+
+      nxagentDisconnectSession();
+    }
+  }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
new file mode 100644
index 000000000..0a2a8a6a7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
@@ -0,0 +1,68 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Reconnect_H__
+#define __Reconnect_H__
+
+extern Display *nxagentDisplayState;
+
+struct nxagentExceptionStruct
+{
+  int sigHup;
+  int ioError;
+};
+
+extern struct nxagentExceptionStruct nxagentException;
+
+void nxagentSetReconnectError(int id, char *format, ...);
+
+void nxagentInitReconnector(void);
+Bool nxagentReconnectSession(void);
+int nxagentHandleConnectionStates(void);
+void nxagentHandleConnectionChanges(void);
+
+enum SESSION_STATE
+{
+  SESSION_STARTING,
+  SESSION_UP,
+  SESSION_DOWN,
+  SESSION_GOING_DOWN,
+  SESSION_GOING_UP
+};
+
+extern enum SESSION_STATE nxagentSessionState;
+
+#define DECODE_SESSION_STATE(state) \
+    ((state) == SESSION_STARTING ? "SESSION_STARTING" : \
+        (state) == SESSION_UP ? "SESSION_UP" : \
+            (state) == SESSION_GOING_UP? "SESSION_GOING_UP" : \
+                (state) == SESSION_DOWN ? "SESSION_DOWN" : \
+                    (state) == SESSION_GOING_DOWN? "SESSION_GOING_DOWN" : \
+                        "UNKNOWN")
+
+/*
+ * Use this macro in the block and wakeup
+ * handlers to save a function call.
+ */
+
+#define nxagentNeedConnectionChange() \
+    (nxagentSessionState == SESSION_GOING_DOWN || \
+         nxagentSessionState == SESSION_GOING_UP)
+
+void nxagentDisconnectSession(void);
+
+#endif /* __Reconnect_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
new file mode 100644
index 000000000..b1ff219e7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -0,0 +1,2810 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Render.h"
+
+#include "X.h"
+#include "Xproto.h"
+
+#include "render.h"
+#include "renderproto.h"
+
+#include "mi.h"
+#include "fb.h"
+#include "mipict.h"
+#include "fbpict.h"
+#include "dixstruct.h"
+
+#include "Agent.h"
+#include "Drawable.h"
+#include "Trap.h"
+#include "Args.h"
+
+#define Atom   XlibAtom
+#define Pixmap XlibPixmap
+#include "../../../../lib/Xrender/Xrenderint.h"
+#undef  Atom
+#undef  Pixmap
+
+#include "region.h"
+#include "extutil.h"
+
+#include "Display.h"
+#include "Pixmaps.h"
+#include "Cursor.h"
+#include "Client.h"
+#include "Image.h"
+#include "Pixels.h"
+#include "Handlers.h"
+
+#include "NXproto.h"
+
+#define MAX_FORMATS 255
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+/*
+ * Define if you want split multiple glyph lists
+ * into multiple RenderCompositeGlyphs requests.
+ */
+
+#undef  SPLIT_GLYPH_LISTS
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+FIXME: Most operations don't seem to produce any visible result
+       but still generate tons of traffic.
+*/
+#undef  SKIP_LOUSY_RENDER_OPERATIONS
+#undef  SKIP_REALLY_ALL_LOUSY_RENDER_OPERATIONS
+
+/*
+ * Do we split the big trapezoid requests?
+ */
+
+#define TRAPEZOIDS_PER_REQUEST  256
+
+/*
+ * Margin added around the glyphs extent (in pixels).
+ */
+
+#define GLYPH_BOX_MARGIN 2
+
+int nxagentRenderEnable = UNDEFINED;
+int nxagentRenderVersionMajor;
+int nxagentRenderVersionMinor;
+
+int nxagentPicturePrivateIndex = 0;
+
+#ifndef NXAGENT_UPGRADE
+static int picturePrivateCount = 0;
+#endif
+
+static int nxagentNumFormats = 0;
+
+static XRenderPictFormat nxagentArrayFormats[MAX_FORMATS];
+
+XRenderPictFormat *nxagentMatchingFormats(PictFormatPtr pForm);
+
+BoxPtr nxagentGlyphsExtents;
+BoxPtr nxagentTrapezoidExtents;
+
+#ifdef DEBUG
+
+static void nxagentPrintFormat(XRenderPictFormat *pFormat);
+
+#endif
+
+/*
+ * From NXglyph.c.
+ */
+
+extern const CARD8 glyphDepths[];
+
+/*
+ * From NXdispatch.c.
+ */
+
+extern void BitOrderInvert(unsigned char *data, int nbytes);
+
+/*
+ * Other functions defined here.
+ */
+
+void nxagentQueryFormats(void);
+
+void nxagentCreateGlyphSet(GlyphSetPtr pGly);
+
+int nxagentCursorSaveRenderInfo(ScreenPtr pScreen, CursorPtr pCursor);
+
+void nxagentCursorPostSaveRenderInfo(CursorPtr pCursor, ScreenPtr pScreen,
+                                         PicturePtr pPicture, int x, int y);
+
+int nxagentCreatePicture(PicturePtr pPicture, Mask mask);
+
+void nxagentDestroyPicture(PicturePtr pPicture);
+
+int nxagentChangePictureClip(PicturePtr pPicture, int clipType, int nRects,
+                                 xRectangle *rects, int xOrigin, int yOrigin);
+
+void nxagentDestroyPictureClip(PicturePtr pPicture);
+
+void nxagentValidatePicture(PicturePtr pPicture, Mask mask);
+
+void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+                          INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+                              INT16 yDst, CARD16 width, CARD16 height);
+
+void nxagentGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                       PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlists,
+                           XGlyphElt8 *elts, int sizeID, GlyphPtr *glyphsBase);
+
+void nxagentCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color,
+                               int nRect, xRectangle *rects);
+
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                           PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+                               int ntrap, xTrapezoid *traps);
+
+void nxagentRasterizeTrapezoid(PicturePtr pMask, xTrapezoid *trap,
+                                   int x_off, int y_off);
+
+void nxagentTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                          PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+                              int ntri, xTriangle *tris);
+
+void nxagentTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                         PictFormatPtr  maskFormat, INT16 xSrc, INT16 ySrc,
+                             int npoint, xPointFixed *points);
+
+void nxagentChangePicture(PicturePtr pPicture, Mask mask);
+
+void nxagentTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                       PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+                           int npoint, xPointFixed *points);
+
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
+
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+                                 pointer params, int nparams);
+
+Bool nxagentReconnectAllGlyphSet(void *p);
+
+Bool nxagentReconnectAllPicture(void *);
+
+Bool nxagentDisconnectAllPicture(void);
+
+void nxagentRenderExtensionInit()
+{
+  int first_event, first_error;
+  int major_version, minor_version;
+
+  if (XRenderQueryExtension(nxagentDisplay, &first_event, &first_error))
+  {
+    XRenderQueryVersion(nxagentDisplay, &major_version, &minor_version);
+
+    /*
+     * As the RENDER requests are passed directly to
+     * the remote X server this can cause problems if 
+     * our RENDER version is different from the version
+     * supported by the remote. For this reasos let's
+     * advertise to our clients the lowest between the
+     + two versions.
+     */
+
+    if (major_version > RENDER_MAJOR || 
+            (major_version == RENDER_MAJOR &&
+                 minor_version > RENDER_MINOR))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentRenderExtensionInit: Using render version [%d.%d] with "
+                  "remote version [%d.%d].\n", RENDER_MAJOR, RENDER_MINOR,
+                      major_version, minor_version);
+      #endif
+
+      nxagentRenderVersionMajor = RENDER_MAJOR;
+      nxagentRenderVersionMinor = RENDER_MINOR;
+    }
+    else if (major_version < RENDER_MAJOR ||
+                 (major_version == RENDER_MAJOR &&
+                      minor_version < RENDER_MINOR))
+    {
+      #ifdef TEST
+      fprintf(stderr, "Info: Local render version %d.%d is higher "
+                  "than remote version %d.%d.\n", RENDER_MAJOR, RENDER_MINOR,
+                      major_version, minor_version);
+
+      fprintf(stderr, "Info: Lowering the render version reported to clients.\n");
+      #endif
+
+      nxagentRenderVersionMajor = major_version;
+      nxagentRenderVersionMinor = minor_version;
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentRenderExtensionInit: Local render version %d.%d "
+                  "matches remote version %d.%d.\n", RENDER_MAJOR, RENDER_MINOR,
+                      major_version, minor_version);
+      #endif
+
+      nxagentRenderVersionMajor = major_version;
+      nxagentRenderVersionMinor = minor_version;
+    }
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "Warning: Render not available on the remote display.\n");
+    #endif
+
+    nxagentRenderEnable = False;
+  }
+}
+
+int nxagentCursorSaveRenderInfo(ScreenPtr pScreen, CursorPtr pCursor)
+{
+  pCursor -> devPriv[pScreen -> myNum] = xalloc(sizeof(nxagentPrivCursor));
+
+  if (nxagentCursorPriv(pCursor, pScreen) == NULL)
+  {
+    FatalError("xalloc failed");
+  }
+
+  nxagentCursorUsesRender(pCursor, pScreen) = 1;
+  nxagentCursorPicture(pCursor, pScreen) = NULL;
+
+  return 1;
+}
+
+void nxagentCursorPostSaveRenderInfo(CursorPtr pCursor, ScreenPtr pScreen,
+                                         PicturePtr pPicture, int x, int y)
+{
+  nxagentCursorPicture(pCursor, pScreen) = pPicture;
+  nxagentCursorXOffset(pCursor, pScreen) = x;
+  nxagentCursorYOffset(pCursor, pScreen) = y;
+}
+
+int nxagentRenderRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+  int cid;
+  int x, y;
+
+  PicturePtr pPicture;
+
+  pPicture = nxagentCursorPicture(pCursor, pScreen);
+
+  pPicture -> refcnt++;
+
+  x = nxagentCursorXOffset(pCursor, pScreen);
+  y = nxagentCursorYOffset(pCursor, pScreen);
+
+  /*
+   * Set the lossless trap so that the image functions
+   * will not try to encode the image using a lossy
+   * compression. Drawables should have a quality flag,
+   * telling if they were originally encoded with a
+   * lossy algorithm. This would allow us to skip the
+   * synchronization if the cursor was already encoded
+   * with the best quality.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderRealizeCursor: Forcing the synchronization "
+              "of the cursor.\n");
+  #endif
+
+  nxagentMarkCorruptedRegion(pPicture -> pDrawable, NULL);
+
+  nxagentLosslessTrap = 1;
+
+  nxagentSynchronizeDrawable(pPicture -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+
+  nxagentLosslessTrap = 0;
+
+  cid = XRenderCreateCursor(nxagentDisplay, nxagentPicture(pPicture), x, y);
+
+  nxagentCursor(pCursor, pScreen) = cid;
+
+  return 1;
+}
+
+int nxagentCreatePicture(PicturePtr pPicture, Mask mask)
+{
+  XRenderPictureAttributes attributes;
+  unsigned long            valuemask=0;
+  XRenderPictFormat        *pForm;
+
+  Picture id;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentCreatePicture: Function called with picture at [%p] and mask [%ld].\n",
+              (void *) pPicture, mask);
+  #endif
+
+  if (pPicture == NULL)
+  {
+    return 0;
+  }
+
+  #ifdef DEBUG
+
+  if (pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+     if (nxagentIsShmPixmap((PixmapPtr)pPicture -> pDrawable))
+     {
+       fprintf (stderr, "nxagentCreatePicture: Picture uses a shared pixmap.\n");
+     }
+     else
+     {
+       fprintf (stderr, "nxagentCreatePicture: Picture uses a plain pixmap.\n");
+     }
+  }
+  else
+  {
+     fprintf (stderr, "nxagentCreatePicture: Picture uses a window.\n");
+  }
+
+  #endif
+
+  /*
+   * All the picture default values are 0.
+   */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0, sizeof(XRenderPictureAttributes));
+
+  if (mask & CPRepeat)
+  {
+    attributes.repeat = (Bool)pPicture -> repeat;
+
+    valuemask |= CPRepeat;
+
+    nxagentSetPictureRemoteValue(pPicture, repeat, attributes.repeat);
+  }
+
+  if (mask & CPAlphaMap)
+  {
+    attributes.alpha_map = nxagentPicturePriv(pPicture -> alphaMap) -> picture;
+
+    valuemask |= CPAlphaMap;
+
+    nxagentSetPictureRemoteValue(pPicture, alpha_map, attributes.alpha_map);
+  }
+
+  if (mask & CPAlphaXOrigin)
+  {
+    attributes.alpha_x_origin = pPicture -> alphaOrigin.x;
+
+    valuemask |= CPAlphaXOrigin;
+
+    nxagentSetPictureRemoteValue(pPicture, alpha_x_origin, attributes.alpha_x_origin);
+  }
+
+  if (mask & CPAlphaYOrigin)
+  {
+    attributes.alpha_y_origin = pPicture -> alphaOrigin.y;
+
+    valuemask |= CPAlphaYOrigin;
+
+    nxagentSetPictureRemoteValue(pPicture, alpha_y_origin, attributes.alpha_y_origin);
+  }
+
+  if (mask & CPClipXOrigin)
+  {
+    attributes.clip_x_origin = pPicture -> clipOrigin.x;
+
+    valuemask |= CPClipXOrigin;
+
+    nxagentSetPictureRemoteValue(pPicture, clip_x_origin, attributes.clip_x_origin);
+  }
+
+  if (mask & CPClipYOrigin)
+  {
+    attributes.clip_y_origin = pPicture -> clipOrigin.y;
+
+    valuemask |= CPClipYOrigin;
+
+    nxagentSetPictureRemoteValue(pPicture, clip_y_origin, attributes.clip_y_origin);
+  }
+
+  if (mask & CPGraphicsExposure)
+  {
+    attributes.graphics_exposures = (Bool)pPicture -> graphicsExposures;
+
+    valuemask |= CPGraphicsExposure;
+
+    nxagentSetPictureRemoteValue(pPicture, graphics_exposures, attributes.graphics_exposures);
+  }
+
+  if (mask & CPSubwindowMode)
+  {
+    attributes.subwindow_mode = pPicture -> subWindowMode;
+
+    valuemask |= CPSubwindowMode;
+
+    nxagentSetPictureRemoteValue(pPicture, subwindow_mode, attributes.subwindow_mode);
+  }
+
+  if (mask & CPClipMask)
+  {
+    attributes.clip_mask = None;
+
+    valuemask |= CPClipMask;
+
+    nxagentSetPictureRemoteValue(pPicture, clip_mask, attributes.clip_mask);
+  }
+
+  if (mask & CPPolyEdge)
+  {
+    attributes.poly_edge = pPicture -> polyEdge;
+
+    valuemask |= CPPolyEdge;
+
+    nxagentSetPictureRemoteValue(pPicture, poly_edge, attributes.poly_edge);
+  }
+
+  if (mask & CPPolyMode)
+  {
+    attributes.poly_mode = pPicture -> polyMode;
+
+    valuemask |= CPPolyMode;
+
+    nxagentSetPictureRemoteValue(pPicture, poly_mode, attributes.poly_mode);
+  }
+
+  if (mask & CPDither)
+  {
+    attributes.dither = pPicture -> dither;
+
+    valuemask |= CPDither;
+
+    nxagentSetPictureRemoteValue(pPicture, dither, attributes.dither);
+  }
+
+  if (mask & CPComponentAlpha)
+  {
+    attributes.component_alpha = pPicture -> componentAlpha;
+
+    valuemask |= CPComponentAlpha;
+
+    nxagentSetPictureRemoteValue(pPicture, component_alpha, attributes.component_alpha);
+  }
+
+  pForm = NULL;
+
+  if (pPicture -> pFormat != NULL)
+  {
+    pForm = nxagentMatchingFormats(pPicture -> pFormat);
+
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+  }
+
+  if (pForm == NULL)
+  {
+    fprintf(stderr, "nxagentCreatePicture: WARNING! The requested format was not found.\n");
+
+    return 0;
+  }
+
+  id = XRenderCreatePicture(nxagentDisplay,
+                            nxagentDrawable(pPicture -> pDrawable),
+                            pForm,
+                            valuemask,
+                            &attributes);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreatePicture: Created picture at [%p] with drawable at [%p].\n",
+              (void *) pPicture, (void *) pPicture -> pDrawable);
+  #endif
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+
+  if (nxagentAlphaEnabled == 1 && pPicture -> pDrawable->depth == 32 &&
+          pPicture -> pFormat -> direct.alpha != 0)
+  {
+    if (pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pPicture -> pDrawable)) -> pPicture = pPicture;
+    }
+    else if (pPicture -> pDrawable -> type == DRAWABLE_WINDOW)
+    {
+      nxagentWindowPriv((WindowPtr) pPicture -> pDrawable) -> pPicture = pPicture;
+    }
+  }
+
+  return 1;
+}
+
+XRenderPictFormat *nxagentMatchingFormats(PictFormatPtr pFormat)
+{
+  int i;
+
+  for (i = 0; i < nxagentNumFormats; i++)
+  {
+    if (pFormat -> type == nxagentArrayFormats[i].type &&
+        pFormat -> depth == nxagentArrayFormats[i].depth &&
+        pFormat -> direct.red == nxagentArrayFormats[i].direct.red &&
+        pFormat -> direct.green == nxagentArrayFormats[i].direct.green &&
+        pFormat -> direct.blue == nxagentArrayFormats[i].direct.blue &&
+        pFormat -> direct.redMask == nxagentArrayFormats[i].direct.redMask &&
+        pFormat -> direct.greenMask == nxagentArrayFormats[i].direct.greenMask &&
+        pFormat -> direct.blueMask == nxagentArrayFormats[i].direct.blueMask &&
+        pFormat -> direct.alpha == nxagentArrayFormats[i].direct.alpha &&
+        pFormat -> direct.alphaMask == nxagentArrayFormats[i].direct.alphaMask)
+    {
+      return &nxagentArrayFormats[i];
+    }
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentMatchingFormats: The requested format was not found.\n");
+  #endif
+
+  return NULL;
+}
+
+void nxagentDestroyPicture(PicturePtr pPicture)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentDestroyPicture: Going to destroy picture at [%p].\n",
+              (void *) pPicture);
+  #endif
+
+  if (pPicture == NULL)
+  {
+    return;
+  }
+
+  XRenderFreePicture(nxagentDisplay,
+                     nxagentPicturePriv(pPicture) -> picture);
+  
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+int nxagentChangePictureClip(PicturePtr pPicture, int clipType, int nRects,
+                                 xRectangle *rects, int xOrigin, int yOrigin)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentChangePictureClip: Going to change clip of picture at [%p].\n",
+              (void *) pPicture);
+  #endif
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentChangePictureClip: clipType [%d] nRects [%d] xRectangle [%p] "
+              "xOrigin [%d] yOrigin [%d].\n", clipType, nRects, (void *) rects, xOrigin, yOrigin);
+  #endif
+
+  if (pPicture == NULL)
+  {
+    return 0;
+  }
+
+  switch (clipType)
+  {
+    case CT_PIXMAP:
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentChangePictureClip: Clip type is [CT_PIXMAP].\n");
+      #endif      
+  
+      /*
+       * if(!nRects)
+       * {
+       *   return 0;
+       * }
+       */
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+       Apparently useless with QT.
+*/
+      #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+      XRenderSetPictureClipRectangles(nxagentDisplay,
+                                      nxagentPicturePriv(pPicture) -> picture,
+                                      xOrigin,
+                                      yOrigin,
+                                      (XRectangle*)rects,
+                                      nRects);
+
+      nxagentSetPictureRemoteValue(pPicture, clip_x_origin, xOrigin);
+      nxagentSetPictureRemoteValue(pPicture, clip_y_origin, yOrigin);
+      nxagentSetPictureRemoteValue(pPicture, clip_mask, 1);
+
+      #endif
+
+      #ifdef DEBUG
+
+      XSync(nxagentDisplay, 0);
+
+      #endif
+
+      break;
+    }   
+    case CT_NONE:
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentChangePictureClip: Clip type is [CT_NONE].\n");
+      #endif
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+       Apparently useless with QT.
+*/
+      #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+      XRenderSetPictureClipRectangles(nxagentDisplay,
+                                      nxagentPicturePriv(pPicture) -> picture,
+                                      xOrigin,
+                                      yOrigin,
+                                      (XRectangle*)rects,
+                                      nRects);
+
+      nxagentSetPictureRemoteValue(pPicture, clip_x_origin, xOrigin);
+      nxagentSetPictureRemoteValue(pPicture, clip_y_origin, yOrigin);
+      nxagentSetPictureRemoteValue(pPicture, clip_mask, 1);
+
+      #endif
+
+      #ifdef DEBUG
+
+      XSync(nxagentDisplay, 0);
+
+      #endif
+
+      break;
+    }
+    case CT_REGION:
+    {
+      Region     reg;
+      XRectangle rectangle;
+      int        index;
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentChangePictureClip: Clip type is [CT_REGION].\n");
+      #endif
+    
+      reg = XCreateRegion();
+
+      for (index = 0; index <= nRects; index++, rects++)
+      {
+        rectangle.x = rects -> x;
+        rectangle.y = rects -> y;
+        rectangle.width = rects -> width;
+        rectangle.height = rects -> height;
+
+        XUnionRectWithRegion(&rectangle, reg, reg);
+      }
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+       Apparently useless with QT.
+*/
+      #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+      XRenderSetPictureClipRegion(nxagentDisplay,
+                                  nxagentPicturePriv(pPicture) -> picture,
+                                  reg);
+
+      nxagentSetPictureRemoteValue(pPicture, clip_x_origin, xOrigin);
+      nxagentSetPictureRemoteValue(pPicture, clip_y_origin, yOrigin);
+      nxagentSetPictureRemoteValue(pPicture, clip_mask, 1);
+
+      #endif
+
+      #ifdef DEBUG
+
+      XSync(nxagentDisplay, 0);
+
+      #endif
+  
+      XDestroyRegion(reg);
+
+      break;
+    }
+    default:
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentChangePictureClip: clipType not found\n");
+      #endif
+
+      break;
+    }
+  }
+
+  return 1;
+}
+
+void nxagentDestroyPictureClip(PicturePtr pPicture)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentDestroyPictureClip: Nothing to do.\n");
+  #endif
+}
+
+void nxagentChangePicture(PicturePtr pPicture, Mask mask)
+{
+  XRenderPictureAttributes  attributes;
+  unsigned long             valuemask = 0;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentChangePicture: Going to change picture at [%p] with mask [%ld].\n",
+              (void *) pPicture, mask);
+  #endif
+
+  if (pPicture == NULL)
+  {
+    return;
+  }
+
+  if (mask & CPRepeat)
+  {
+    attributes.repeat = (Bool)pPicture -> repeat;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, repeat, attributes.repeat) == 0)
+    {
+      valuemask |= CPRepeat;
+
+      nxagentSetPictureRemoteValue(pPicture, repeat, attributes.repeat);
+    }
+  }
+
+  if (mask & CPAlphaMap)
+  {
+    attributes.alpha_map = nxagentPicturePriv(pPicture -> alphaMap) -> picture;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, alpha_map, attributes.alpha_map) == 0)
+    {
+      valuemask |= CPAlphaMap;
+
+      nxagentSetPictureRemoteValue(pPicture, alpha_map, attributes.alpha_map);
+    }
+  }
+
+  if (mask & CPAlphaXOrigin)
+  {
+    attributes.alpha_x_origin = pPicture -> alphaOrigin.x;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, alpha_x_origin, attributes.alpha_x_origin) == 0)
+    {
+      valuemask |= CPAlphaXOrigin;
+
+      nxagentSetPictureRemoteValue(pPicture, alpha_x_origin, attributes.alpha_x_origin);
+    }
+  }
+
+  if (mask & CPAlphaYOrigin)
+  {
+    attributes.alpha_y_origin = pPicture -> alphaOrigin.y;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, alpha_y_origin, attributes.alpha_y_origin) == 0)
+    {
+      valuemask |= CPAlphaYOrigin;
+
+      nxagentSetPictureRemoteValue(pPicture, alpha_y_origin, attributes.alpha_y_origin);
+    }
+  }
+
+  if (mask & CPClipXOrigin)
+  {
+    attributes.clip_x_origin = pPicture -> clipOrigin.x;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, clip_x_origin, attributes.clip_x_origin) == 0)
+    {
+      valuemask |= CPClipXOrigin;
+
+      nxagentSetPictureRemoteValue(pPicture, clip_x_origin, attributes.clip_x_origin);
+    }
+  }
+
+  if (mask & CPClipYOrigin)
+  {
+    attributes.clip_y_origin = pPicture -> clipOrigin.y;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, clip_y_origin, attributes.clip_y_origin) == 0)
+    {
+      valuemask |= CPClipYOrigin;
+
+      nxagentSetPictureRemoteValue(pPicture, clip_y_origin, attributes.clip_y_origin);
+    }
+  }
+
+  if (mask & CPGraphicsExposure)
+  {
+    attributes.graphics_exposures = (Bool)pPicture -> graphicsExposures;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, graphics_exposures, attributes.graphics_exposures) == 0)
+    {
+      valuemask |= CPGraphicsExposure;
+
+      nxagentSetPictureRemoteValue(pPicture, graphics_exposures, attributes.graphics_exposures);
+    }
+  }
+
+  if (mask & CPSubwindowMode)
+  {
+    attributes.subwindow_mode = pPicture -> subWindowMode;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, subwindow_mode, attributes.subwindow_mode) == 0)
+    {
+      valuemask |= CPSubwindowMode;
+
+      nxagentSetPictureRemoteValue(pPicture, subwindow_mode, attributes.subwindow_mode);
+    }
+  }
+
+  if (mask & CPClipMask)
+  {
+    attributes.clip_mask = None;
+
+    /*
+     * The nxagent doesn't know the remote id of
+     * the picture's clip mask, so the clip_mask
+     * value is used as a boolean: it is set to 0
+     * when the clip_mask is None, otherwise it is
+     * 1.
+     */
+
+    if (nxagentPicturePriv(pPicture) -> lastServerValues.clip_mask != 0)
+    {
+      valuemask |= CPClipMask;
+
+      nxagentSetPictureRemoteValue(pPicture, clip_mask, 0);
+    }
+  }
+
+  if (mask & CPPolyEdge)
+  {
+    attributes.poly_edge = pPicture -> polyEdge;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, poly_edge, attributes.poly_edge) == 0)
+    {
+      valuemask |= CPPolyEdge;
+
+      nxagentSetPictureRemoteValue(pPicture, poly_edge, attributes.poly_edge);
+    } 
+  }
+
+  if (mask & CPPolyMode)
+  {
+    attributes.poly_mode = pPicture -> polyMode;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, poly_mode, attributes.poly_mode) == 0)
+    {
+      valuemask |= CPPolyMode;
+
+      nxagentSetPictureRemoteValue(pPicture, poly_mode, attributes.poly_mode);
+    }
+  }
+
+  if (mask & CPDither)
+  {
+    attributes.dither = pPicture -> dither;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, dither, attributes.dither) == 0)
+    {
+      valuemask |= CPDither;
+
+      nxagentSetPictureRemoteValue(pPicture, dither, attributes.dither);
+    }
+  }
+
+  if (mask & CPComponentAlpha)
+  {
+    attributes.component_alpha = pPicture -> componentAlpha;
+
+    if (nxagentCheckPictureRemoteValue(pPicture, component_alpha, attributes.component_alpha) == 0)
+    {
+      valuemask |= CPComponentAlpha;
+
+      nxagentSetPictureRemoteValue(pPicture, component_alpha, attributes.component_alpha);
+    }
+  }
+
+  #ifdef TEST
+
+  if (pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    fprintf(stderr, "nxagentChangePicture: %sPixmap [%p] Picture [%p][%p].\n",
+                nxagentIsShmPixmap((PixmapPtr)pPicture -> pDrawable) ? "Shared " : "",
+                    (void *) pPicture -> pDrawable, (void *) nxagentPicturePriv(pPicture) -> picture,
+                        (void *) pPicture);
+  }
+
+  #endif
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+       Apparently useless with QT.
+
+       Without this the text is not rendered on GTK/Cairo.
+*/
+  #ifndef SKIP_REALLY_ALL_LOUSY_RENDER_OPERATIONS
+
+  if (valuemask != 0)
+  {
+    XRenderChangePicture(nxagentDisplay,
+                         nxagentPicturePriv(pPicture) -> picture,
+                         valuemask,
+                         &attributes);
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentChangePicture: Skipping change of picture [%p] on remote X server.\n",
+                (void *) pPicture);
+  }
+  #endif
+
+  #endif
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentValidatePicture(PicturePtr pPicture, Mask mask)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentValidatePicture: Nothing to do.\n");
+  #endif
+}
+
+void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+                          INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
+                              INT16 yDst, CARD16 width, CARD16 height)
+{
+  RegionPtr pDstRegion;
+
+  if (pSrc == NULL || pDst == NULL)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
+              nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
+              (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                   nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
+                       pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+                           (void *) pSrc -> pDrawable);
+
+  fprintf(stderr, "nxagentComposite: Destination Picture [%lu][%p] with drawable [%s%s][%p].\n",
+              nxagentPicturePriv(pDst) -> picture, (void *) pDst,
+              (pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                  nxagentIsShmPixmap((PixmapPtr) pDst -> pDrawable)) ? "Shared " : "",
+                       pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+                           (void *) pDst -> pDrawable);
+
+  if (pMask)
+  {
+    fprintf(stderr, "nxagentComposite: Mask Picture [%lu][%p] with drawable [%s%s][%p].\n",
+                nxagentPicturePriv(pMask) -> picture, (void *) pMask,
+                (pMask -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                    nxagentIsShmPixmap((PixmapPtr) pMask -> pDrawable)) ? "Shared " : "",
+                       pMask -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+                           (void *) pMask -> pDrawable);
+  }
+
+  #endif
+
+  if (NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst))
+  {
+    pDstRegion = nxagentCreateRegion(pDst -> pDrawable, NULL, xDst, yDst, width, height);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentComposite: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+                "for drawable at [%p] with type [%s].\n", pDstRegion -> extents.x1,
+                    pDstRegion -> extents.y1, pDstRegion -> extents.x2, pDstRegion -> extents.y2,
+                        (void *) pDst -> pDrawable,
+                            pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window");
+
+    #endif
+
+    nxagentMarkCorruptedRegion(pDst -> pDrawable, pDstRegion);
+
+    nxagentFreeRegion(pDst -> pDrawable, pDstRegion);
+
+    return;
+  }
+
+  /*
+   * Synchronize the content of the shared memory pixmap
+   * but pay attention at not doing this more than once.
+   * We need to wait until the image data has been recom-
+   * posed at the X server side or the operation will use
+   * the wrong data.
+   */
+
+  nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
+
+  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
+                (void *) pSrc -> pDrawable);
+    #endif
+
+    nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+  }
+
+  if (pDst -> pDrawable != pSrc -> pDrawable)
+  {
+    nxagentSynchronizeShmPixmap(pDst -> pDrawable, xDst, yDst, width, height);
+
+    if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentComposite: Synchronizing the destination drawable [%p].\n",
+                  (void *) pDst -> pDrawable);
+      #endif
+
+      nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+    }
+  }
+
+  if (pMask != NULL && pMask -> pDrawable != pSrc -> pDrawable &&
+          pMask -> pDrawable != pDst -> pDrawable)
+  {
+    nxagentSynchronizeShmPixmap(pMask -> pDrawable, xMask, yMask, width, height);
+
+    if (nxagentDrawableStatus(pMask -> pDrawable) == NotSynchronized)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentComposite: Synchronizing the mask drawable [%p].\n",
+                  (void *) pMask -> pDrawable);
+      #endif
+
+      nxagentSynchronizeDrawable(pMask -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+    }
+  }
+
+  /*
+   * The glyphs flag have to be propagated between
+   * drawables, in order to avoid to encode the
+   * text with lossy algorithms (like JPEG). Unlu-
+   * ckily we have verified that if the render com-
+   * posite propagates the flag, the deferring of
+   * render trapezoids doesn't work well. Moreover,
+   * by commenting out this code we have not noticed
+   * any visual problems.
+   *
+   *  if (nxagentDrawableContainGlyphs(pSrc -> pDrawable) == 1)
+   *  {
+   *    nxagentSetDrawableContainGlyphs(pDst -> pDrawable, 1);
+   *  }
+   */
+
+  XRenderComposite(nxagentDisplay,
+                   op,
+                   nxagentPicturePriv(pSrc) -> picture,
+                   pMask ? nxagentPicturePriv(pMask) -> picture : 0,
+                   nxagentPicturePriv(pDst) -> picture,
+                   xSrc,
+                   ySrc,
+                   xMask,
+                   yMask,
+                   xDst,
+                   yDst,
+                   width,
+                   height);
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                       PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlists,
+                           XGlyphElt8 *elts, int sizeID, GlyphPtr *glyphsBase)
+{
+  XRenderPictFormat *pForm;
+
+  BoxRec glyphBox;
+
+  XGlyphElt8 *elements;
+
+  #ifdef SPLIT_GLYPH_LISTS
+
+  GlyphPtr glyph;
+
+  int x;
+  int y;
+  int i;
+  int j;
+
+  #endif /* #ifdef SPLIT_GLYPH_LISTS */
+
+  if (pSrc == NULL || pDst == NULL)
+  {
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentGlyphs: Called with source [%s][%p] destination [%s][%p] and size id [%d].\n",
+              (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"), (void *) pSrc, 
+                  (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"), (void *) pDst, 
+                      sizeID);
+  #endif
+
+  pForm = NULL;
+
+  if (maskFormat != NULL)
+  {
+    pForm = nxagentMatchingFormats(maskFormat);
+    
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+
+    if (pForm == NULL)
+    {
+      return;
+    }
+  }
+
+  if (nxagentGlyphsExtents != NullBox)
+  {
+    glyphBox.x1 = nxagentGlyphsExtents -> x1;
+    glyphBox.y1 = nxagentGlyphsExtents -> y1;
+    glyphBox.x2 = nxagentGlyphsExtents -> x2;
+    glyphBox.y2 = nxagentGlyphsExtents -> y2;
+
+    /*
+     * By extending the glyph extents the
+     * visual aspect looks nicer because
+     * the synchronized region is not glued
+     * to the fonts.
+     */
+
+    if (glyphBox.x2 != glyphBox.x1)
+    {
+      glyphBox.x1 -= GLYPH_BOX_MARGIN;
+      glyphBox.x2 += GLYPH_BOX_MARGIN;
+    }
+
+    if (glyphBox.y2 != glyphBox.y1)
+    {
+      glyphBox.y1 -= GLYPH_BOX_MARGIN;
+      glyphBox.y2 += GLYPH_BOX_MARGIN;
+    }
+  }
+
+  /*
+   * If the destination window is hidden, the
+   * operation can be prevented.
+   */
+
+  if (pDst -> pDrawable -> type == DRAWABLE_WINDOW)
+  {
+    RegionPtr pRegion;
+
+    pRegion = nxagentCreateRegion(pDst -> pDrawable, NULL, glyphBox.x1, glyphBox.y1,
+                                      glyphBox.x2 - glyphBox.x1, glyphBox.y2 - glyphBox.y1);
+    
+    if (REGION_NIL(pRegion) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentGlyphs: WARNING! Glyphs prevented on hidden window at [%p].\n",
+                  (void *) pDst -> pDrawable);
+      #endif
+
+      nxagentFreeRegion(pDst -> pDrawable, pRegion);
+
+      return;
+    }
+
+    nxagentFreeRegion(pDst -> pDrawable, pRegion);
+  }
+
+  /*
+   * Need to synchronize the pixmaps involved in
+   * the operation before rendering the glyphs
+   * on the real X server.
+   */
+
+  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentGlyphs: Synchronizing source [%s] at [%p].\n",
+                pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+                    (void *) pSrc -> pDrawable);
+    #endif
+
+    /*
+     * If the source drawable is going to be
+     * repeated over the destination drawable
+     * during the composite operation, we need
+     * to synchronize the whole drawable to
+     * avoid graphical problems.
+     */
+
+    if (pSrc -> repeat == 1 || nxagentGlyphsExtents == NullBox)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentGlyphs: Synchronizing source [%s] at [%p] "
+                  "with geometry [%d,%d,%d,%d].\n", 
+                      (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+                          (void *) pSrc -> pDrawable, pSrc -> pDrawable -> x, pSrc -> pDrawable -> y,
+                              pSrc -> pDrawable -> x + pSrc -> pDrawable -> width,
+                                  pSrc -> pDrawable -> y + pSrc -> pDrawable -> height);
+      #endif
+
+      nxagentSynchronizeBox(pSrc -> pDrawable, NullBox, NEVER_BREAK);
+    }
+    else
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentGlyphs: Synchronizing region [%d,%d,%d,%d] of source [%s] at [%p] "
+                  "with geometry [%d,%d,%d,%d].\n", glyphBox.x1, glyphBox.y1, glyphBox.x2, glyphBox.y2,
+                          (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+                              (void *) pSrc -> pDrawable, pSrc -> pDrawable -> x, pSrc -> pDrawable -> y,
+                                  pSrc -> pDrawable -> x + pSrc -> pDrawable -> width,
+                                      pSrc -> pDrawable -> y + pSrc -> pDrawable -> height);
+      #endif
+
+      nxagentSynchronizeBox(pSrc -> pDrawable, &glyphBox, NEVER_BREAK);
+    }
+
+    if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentIncreasePixmapUsageCounter((PixmapPtr) pSrc -> pDrawable);
+    }
+  }
+
+  if (pSrc -> pDrawable != pDst -> pDrawable &&
+          nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentGlyphs: Synchronizing destination [%s] at [%p].\n",
+                pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+                    (void *) pDst -> pDrawable);
+    #endif
+
+    if (nxagentGlyphsExtents == NullBox)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentGlyphs: Synchronizing destination [%s] at [%p] "
+                  "with geometry [%d,%d,%d,%d].\n", 
+                      (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+                          (void *) pDst -> pDrawable, pDst -> pDrawable -> x, pDst -> pDrawable -> y,
+                              pDst -> pDrawable -> x + pDst -> pDrawable -> width,
+                                  pDst -> pDrawable -> y + pDst -> pDrawable -> height);
+      #endif
+
+      nxagentSynchronizeBox(pDst -> pDrawable, NullBox, NEVER_BREAK);
+    }
+    else
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentGlyphs: Synchronizing region [%d,%d,%d,%d] of destination [%s] at [%p] "
+                  "with geometry [%d,%d,%d,%d].\n", glyphBox.x1, glyphBox.y1, glyphBox.x2, glyphBox.y2,
+                          (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+                              (void *) pDst -> pDrawable, pDst -> pDrawable -> x, pDst -> pDrawable -> y,
+                                  pDst -> pDrawable -> x + pDst -> pDrawable -> width,
+                                      pDst -> pDrawable -> y + pDst -> pDrawable -> height);
+      #endif
+
+      nxagentSynchronizeBox(pDst -> pDrawable, &glyphBox, NEVER_BREAK);
+    }
+
+    if (pDst -> pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentIncreasePixmapUsageCounter((PixmapPtr) pDst -> pDrawable);
+    }
+  }
+
+  nxagentSetDrawableContainGlyphs(pDst -> pDrawable, 1);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentGlyphs: Glyph flag set on drawable [%s][%p].\n",
+              pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+                  (void *) pDst -> pDrawable);
+  #endif
+
+  #ifdef SPLIT_GLYPH_LISTS
+
+  /*
+   * We split glyphs lists here and recalculate
+   * the offsets of each list to make them ab-
+   * solute and not relatives to the prior list.
+   * This way each time we call XRenderComposi-
+   * teText it has to deal only with a list of
+   * glyphs. This is done to further improve
+   * caching.
+   */
+
+  elements = elts;
+
+  if (nlists > 1)
+  {
+    for (j = 1; j < nlists; j++)
+    {
+      x = elements -> xOff;
+      y = elements -> yOff;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentGlyphs: Element [%d] of [%d] has offset [%d,%d].\n",
+                  j, nlists, elements -> xOff, elements -> yOff);
+      #endif
+
+      for (i = 0; i < elements -> nchars; i++)
+      {
+        glyph = *glyphsBase++;
+
+        x += glyph -> info.xOff;
+        y += glyph -> info.yOff;
+        
+        #ifdef TEST
+        fprintf(stderr, "nxagentGlyphs: Glyph at index [%d] has offset [%d,%d] and "
+                    "position [%d,%d].\n", i, elements -> nchars, glyph -> info.xOff,
+                        glyph -> info.yOff, x, y);
+        #endif
+      }
+
+      elements++;
+
+      elements -> xOff += x;
+      elements -> yOff += y;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentGlyphs: New offset for list at [%p] is [%d,%d].\n",
+                  elements, elements -> xOff, elements -> yOff);
+      #endif
+    }
+
+    elements = elts;
+  }
+
+  switch (sizeID)
+  {
+    case 1:
+    {
+      for (j = 0; j < nlists; j++)
+      {
+        XRenderCompositeText8(nxagentDisplay,
+                              op,
+                              nxagentPicturePriv(pSrc)->picture,
+                              nxagentPicturePriv(pDst)->picture,
+                              pForm,
+                              xSrc,
+                              ySrc,
+                              elements -> xOff,
+                              elements -> yOff,
+                              (XGlyphElt8*) elements,
+                              1);
+
+        elements++;
+      }
+
+      break;
+    }
+    case 2:
+    {
+      for (j = 0; j < nlists; j++)
+      {
+        XRenderCompositeText16(nxagentDisplay,
+                               op,
+                               nxagentPicturePriv(pSrc) -> picture,
+                               nxagentPicturePriv(pDst) -> picture,
+                               pForm,
+                               xSrc,
+                               ySrc,
+                               elements -> xOff,
+                               elements -> yOff,
+                               (XGlyphElt16*) elements,
+                               1);
+
+        elements++;
+      }
+
+      break;
+    }
+    case 4:
+    {
+      for (j = 0; j < nlists; j++)
+      {
+        XRenderCompositeText32(nxagentDisplay,
+                               op,
+                               nxagentPicturePriv(pSrc) -> picture,
+                               nxagentPicturePriv(pDst) -> picture,
+                               pForm,
+                               xSrc,
+                               ySrc,
+                               elements -> xOff,
+                               elements -> yOff,
+                               (XGlyphElt32*) elements,
+                               1);
+
+        elements++;
+      }
+
+      break;
+    }
+    default:
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentGlyphs: WARNING! Invalid size id [%d].\n",
+                  sizeID);
+      #endif
+
+      break;
+    }
+  }
+
+  #else /* #ifdef SPLIT_GLYPH_LISTS */
+
+  elements = elts;
+
+  switch (sizeID)
+  {
+    case 1:
+    {
+      XRenderCompositeText8(nxagentDisplay,
+                            op,
+                            nxagentPicturePriv(pSrc)->picture,
+                            nxagentPicturePriv(pDst)->picture,
+                            pForm,
+                            xSrc,
+                            ySrc,
+                            elements -> xOff,
+                            elements -> yOff,
+                            (XGlyphElt8*) elements,
+                            nlists);
+
+      break;
+    }
+    case 2:
+    {
+      XRenderCompositeText16(nxagentDisplay,
+                             op,
+                             nxagentPicturePriv(pSrc) -> picture,
+                             nxagentPicturePriv(pDst) -> picture,
+                             pForm,
+                             xSrc,
+                             ySrc,
+                             elements -> xOff,
+                             elements -> yOff,
+                             (XGlyphElt16*) elements,
+                             nlists);
+
+      break;
+    }
+    case 4:
+    {
+      XRenderCompositeText32(nxagentDisplay,
+                             op,
+                             nxagentPicturePriv(pSrc) -> picture,
+                             nxagentPicturePriv(pDst) -> picture,
+                             pForm,
+                             xSrc,
+                             ySrc,
+                             elements -> xOff,
+                             elements -> yOff,
+                             (XGlyphElt32*) elements,
+                             nlists);
+
+      break;
+    }
+    default:
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentGlyphs: WARNING! Invalid size id [%d].\n",
+                  sizeID);
+      #endif
+
+      break;
+    }
+  }
+
+  #endif /* #ifdef SPLIT_GLYPH_LISTS */
+}
+
+void nxagentCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color,
+                               int nRect, xRectangle *rects)
+{
+  RegionPtr rectRegion;
+
+  if (pDst == NULL)
+  {
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCompositeRects: Called for picture at [%p] with [%s] at [%p].\n",
+              (void *) pDst, (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+                  (void *) pDst -> pDrawable);
+  #endif
+
+  /*
+   * The CompositeRects() clears the destination's
+   * corrupted region like the PolyFillRects() does.
+   * As this case is harder to handle, at the moment
+   * we only check for two ops.
+   */
+
+  if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized &&
+          (op == PictOpSrc ||
+               (op == PictOpOver && color -> alpha == 0xffff)))
+  {
+    rectRegion = RECTS_TO_REGION(pDst -> pDrawable -> pScreen, nRect, rects, CT_REGION);
+
+    if (pDst -> clientClipType != CT_NONE)
+    {
+      RegionRec tmpRegion;
+
+      REGION_INIT(pDst -> pDrawable -> pScreen, &tmpRegion, NullBox, 1);
+
+      REGION_COPY(pDst -> pDrawable -> pScreen, &tmpRegion, (RegionPtr) pDst -> clientClip);
+
+      if (pDst -> clipOrigin.x != 0 || pDst -> clipOrigin.y != 0)
+      {
+        REGION_TRANSLATE(pDst -> pDrawable -> pScreen, &tmpRegion, pDst -> clipOrigin.x, pDst -> clipOrigin.y);
+      }
+
+      REGION_INTERSECT(pDst -> pDrawable -> pScreen, rectRegion, rectRegion, &tmpRegion);
+
+      REGION_UNINIT(pDst -> pDrawable -> pScreen, &tmpRegion);      
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositeRects: Going to clean the drawable with extents [%d,%d,%d,%d].\n",
+                rectRegion -> extents.x1, rectRegion -> extents.y1, rectRegion -> extents.x2, rectRegion -> extents.y2);
+    #endif
+
+    nxagentUnmarkCorruptedRegion(pDst -> pDrawable, rectRegion);
+
+    REGION_DESTROY(pDrawable -> pScreen, rectRegion);
+  }
+
+  XRenderFillRectangles(nxagentDisplay,
+                        op,
+                        (Picture)nxagentPicturePriv(pDst) -> picture,
+                        (XRenderColor *) color,
+                        (XRectangle *) rects,
+                        nRect);
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                           PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+                               int ntrap, xTrapezoid *traps)
+{
+  XRenderPictFormat *pForm;
+
+  XTrapezoid *current = (XTrapezoid *) traps;
+
+  RegionPtr pDstRegion;
+
+  int remaining = ntrap;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentTrapezoids: Source [%p] destination [%p] coordinates "
+              "[%d,%d] elements [%d].\n", (void *) pSrc, (void *) pDst,
+                  xSrc, ySrc, ntrap);
+  #endif
+
+  if (pSrc == NULL || pDst == NULL)
+  {
+    return;
+  }
+
+  pForm = NULL;
+
+  if (maskFormat != NULL)
+  {
+    pForm = nxagentMatchingFormats(maskFormat);
+    
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+
+    if (pForm == NULL)
+    {
+      return;
+    }
+  }
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+       Apparently useless with QT.
+*/
+  #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+  #ifdef TEST
+
+  fprintf(stderr, "nxagentTrapezoids: Source is a [%s] of geometry [%d,%d].\n",
+              (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+                  pSrc -> pDrawable -> width, pSrc -> pDrawable -> height);
+
+  if (pSrc ->pDrawable != pDst -> pDrawable)
+  {
+    fprintf(stderr, "nxagentTrapezoids: Destination is a [%s] of geometry [%d,%d].\n",
+                (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window"),
+                    pDst -> pDrawable -> width, pDst -> pDrawable -> height);
+  }
+
+  #endif
+
+  /*
+   * If the destination drawable is not synchronized
+   * but the trapezoids extents are included in the
+   * dirty region, we can defer the operation.
+   */
+
+  if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized &&
+          RECT_IN_REGION(pDst -> pDrawable -> pScreen, nxagentCorruptedRegion(pDst -> pDrawable),
+                             nxagentTrapezoidExtents) == rgnIN)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTrapezoids: WARNING! Prevented operation on region [%d,%d,%d,%d] already dirty "
+                "for drawable [%s][%p].\n", nxagentTrapezoidExtents -> x1, nxagentTrapezoidExtents -> y1,
+                    nxagentTrapezoidExtents -> x2, nxagentTrapezoidExtents -> y2,
+                        pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+                            (void *) pDst -> pDrawable);
+    #endif
+
+    if (pDst -> pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentPixmapContainTrapezoids((PixmapPtr) pDst -> pDrawable) = 1;
+    }
+
+    return;
+  }
+
+  /*
+   * If the destination doesn't contain any glyphs,
+   * we can defer the trapezoids drawing by marking
+   * the destination as dirty.
+   */
+
+  if (NXAGENT_SHOULD_DEFER_TRAPEZOIDS(pDst -> pDrawable))
+  {
+    pDstRegion = nxagentCreateRegion(pDst -> pDrawable, NULL,
+                                     nxagentTrapezoidExtents -> x1,
+                                     nxagentTrapezoidExtents -> y1,
+                                     nxagentTrapezoidExtents -> x2 - nxagentTrapezoidExtents -> x1,
+                                     nxagentTrapezoidExtents -> y2 - nxagentTrapezoidExtents -> y1);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentTrapezoids: WARNING! Prevented operation on region [%d,%d,%d,%d] "
+                "for drawable [%s][%p].\n", pDstRegion -> extents.x1, pDstRegion -> extents.y1,
+                    pDstRegion -> extents.x2, pDstRegion -> extents.y2,
+                        pDst -> pDrawable -> type == DRAWABLE_PIXMAP ? "pixmap" : "window",
+                            (void *) pDst -> pDrawable);
+    #endif
+
+    nxagentMarkCorruptedRegion(pDst -> pDrawable, pDstRegion);
+
+    nxagentFreeRegion(pDst -> pDrawable, pDstRegion);
+
+    if (pDst -> pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentPixmapContainTrapezoids((PixmapPtr) pDst -> pDrawable) = 1;
+    }
+
+    return;
+  }
+
+  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTrapezoids: Going to synchronize the source drawable at [%p].\n",
+                (void *) pSrc -> pDrawable);
+    #endif
+
+    nxagentSynchronizeBox(pSrc -> pDrawable, NullBox, NEVER_BREAK);
+  }
+
+  if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTrapezoids: Going to synchronize the destination drawable at [%p].\n",
+                (void *) pDst -> pDrawable);
+    #endif
+
+    nxagentSynchronizeBox(pDst -> pDrawable, nxagentTrapezoidExtents, NEVER_BREAK);
+  }
+
+  while (remaining > 0)
+  {
+    XRenderCompositeTrapezoids(nxagentDisplay,
+                               op,
+                               nxagentPicturePriv(pSrc) -> picture,
+                               nxagentPicturePriv(pDst) -> picture,
+                               pForm,
+                               xSrc,
+                               ySrc,
+                               (XTrapezoid *) current,
+                               (remaining > TRAPEZOIDS_PER_REQUEST ?
+                                   TRAPEZOIDS_PER_REQUEST : remaining));
+
+    remaining -= TRAPEZOIDS_PER_REQUEST;
+    current   += TRAPEZOIDS_PER_REQUEST;
+  }
+
+  #endif
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentRasterizeTrapezoid(PicturePtr pMask, xTrapezoid *trap,
+                                   int x_off, int y_off)
+{
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentRasterizeTrapezoids: Nothing to do.\n");
+  #endif
+}
+
+void nxagentTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                          PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+                              int ntri, xTriangle *tris)
+{
+  XRenderPictFormat *pForm;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentTriangles: Source [%p] Destination [%p] Coordinates [%d,%d] Elements [%d].\n",
+              (void *) pSrc, (void *) pDst, xSrc, ySrc, ntri);
+  #endif
+
+  if (pSrc == NULL || pDst == NULL)
+  {
+    return;
+  }
+
+  pForm = NULL;
+
+  if (maskFormat != NULL)
+  {
+    pForm = nxagentMatchingFormats(maskFormat);
+
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+
+    if (pForm == NULL)
+    {
+      return;
+    }
+  }
+
+  /*
+   * If the X_RenderCompositeTriangles requests
+   * increment the traffic, we can defer the
+   * operation like nxagentTrapezoids() does.
+   */
+
+  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTriangles: Going to synchronize the source drawable at [%p].\n",
+                (void *) pSrc -> pDrawable);
+    #endif
+
+    nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+  }
+
+  if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTriangles: Going to synchronize the destination drawable at [%p].\n",
+                (void *) pDst -> pDrawable);
+    #endif
+
+    nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+  }
+
+  XRenderCompositeTriangles(nxagentDisplay,
+                            op,
+                            nxagentPicturePriv(pSrc) -> picture,
+                            nxagentPicturePriv(pDst) -> picture,
+                            pForm,
+                            xSrc,
+                            ySrc,
+                            (XTriangle*)tris,
+                            ntri);
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                         PictFormatPtr  maskFormat, INT16 xSrc, INT16 ySrc,
+                             int npoint, xPointFixed *points)
+{
+  XRenderPictFormat *pForm;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentTriStrip: Source [%p] Destination [%p] Coordinates [%d,%d] Elements [%d].\n",
+              (void *) pSrc, (void *) pDst, xSrc, ySrc, npoint);
+  #endif
+
+  if (pSrc == NULL || pDst == NULL)
+  {
+    return;
+  }
+
+  pForm = NULL;
+
+  if (maskFormat != NULL)
+  {
+    pForm = nxagentMatchingFormats(maskFormat);
+
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+
+    if (pForm == NULL)
+    {
+      return;
+    }
+  }
+
+  /*
+   * If the X_RenderCompositeTriStrip requests
+   * increment the traffic, we can defer the
+   * operation like nxagentTrapezoids() does.
+   */
+
+  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTriStrip: Going to synchronize the source drawable at [%p].\n",
+                (void *) pSrc -> pDrawable);
+    #endif
+
+    nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+  }
+
+  if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTriStrip: Going to synchronize the destination drawable at [%p].\n",
+                (void *) pDst -> pDrawable);
+    #endif
+
+    nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+  }
+
+  XRenderCompositeTriStrip(nxagentDisplay,
+                           op,
+                           nxagentPicturePriv(pSrc) -> picture,
+                           nxagentPicturePriv(pDst) -> picture,
+                           pForm,
+                           xSrc,
+                           ySrc,
+                           (XPointFixed*)points,
+                           npoint);
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+                       PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+                           int npoint, xPointFixed *points)
+{
+  XRenderPictFormat *pForm;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentTriFan: Source [%p] Destination [%p] Coordinates [%d,%d] Elements [%d].\n",
+              (void *) pSrc, (void *) pDst, xSrc, ySrc, npoint);
+  #endif
+
+  if (pSrc == NULL || pDst == NULL)
+  {
+    return;
+  }
+
+  pForm = NULL;
+
+  if (maskFormat != NULL)
+  {
+    pForm = nxagentMatchingFormats(maskFormat);
+
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+
+    if (pForm == NULL)
+    {
+      return;
+    }
+  }
+
+  /*
+   * If the X_RenderCompositeTriFan requests
+   * increment the traffic, we can defer the
+   * operation like nxagentTrapezoids() does.
+   */
+
+  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTriFan: Going to synchronize the source drawable at [%p].\n",
+                (void *) pSrc -> pDrawable);
+    #endif
+
+    nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+  }
+
+  if (nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentTriFan: Going to synchronize the destination drawable at [%p].\n",
+                (void *) pDst -> pDrawable);
+    #endif
+
+    nxagentSynchronizeDrawable(pDst -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+  }
+
+  XRenderCompositeTriFan(nxagentDisplay,
+                         op,
+                         nxagentPicturePriv(pSrc) -> picture,
+                         nxagentPicturePriv(pDst) -> picture,
+                         pForm,
+                         xSrc,
+                         ySrc,
+                         (XPointFixed*)points,
+                         npoint);
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+#ifndef NXAGENT_UPGRADE
+
+/*
+FIXME: In the 3.0.0 port these functions have been moved
+       to Picture.c. We can remove them when the port is
+       is complete.
+*/
+int AllocatePicturePrivateIndex()
+{
+  return picturePrivateCount++;
+}
+
+Bool AllocatePicturePrivate(register ScreenPtr pScreen, int index2, unsigned amount)
+{
+  unsigned oldamount;
+
+  PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+  /*
+   * Round up the size for proper alignment.
+   */
+
+  amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+  if (index2 >= ps -> PicturePrivateLen)
+  {
+    unsigned *nsizes = (unsigned *) xrealloc(ps -> PicturePrivateSizes,
+                           (index2 + 1) * sizeof(unsigned));
+    if (nsizes == 0)
+    {
+      return 0;
+    }
+
+    while (ps -> PicturePrivateLen <= index2)
+    {
+      nsizes[ps -> PicturePrivateLen++] = 0;
+
+      ps -> totalPictureSize += sizeof(DevUnion);
+    }
+
+    ps -> PicturePrivateSizes = nsizes;
+  }
+
+  oldamount = ps -> PicturePrivateSizes[index2];
+
+  if (amount > oldamount)
+  {
+    ps -> PicturePrivateSizes[index2] = amount;
+
+    ps -> totalPictureSize += (amount - oldamount);
+  }
+
+  return 1;
+}
+#endif
+
+void nxagentQueryFormats()
+{
+  XRenderInfo *xri;
+  XExtDisplayInfo *info = NULL;
+  XRenderPictFormat *pformat=NULL;
+
+  int i;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentQueryFormats.\n");
+  #endif
+
+  if (XRenderQueryFormats(nxagentDisplay))
+  {
+    #ifdef DEBUG
+
+    XSync(nxagentDisplay, 0);
+
+    #endif
+
+    info = (XExtDisplayInfo *) XRenderFindDisplay(nxagentDisplay);
+
+    #ifdef DEBUG
+
+    XSync(nxagentDisplay, 0);
+
+    #endif
+
+    xri = (XRenderInfo *) info -> data;
+
+    pformat = xri -> format;
+
+    for (i = 0; i < xri -> nformat; i++)
+    {
+      nxagentArrayFormats[i] = *pformat;
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentQueryFormats: Added format type [%d] depth [%d] rgb [%d,%d,%d] "
+                  "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d].\n",
+                      nxagentArrayFormats[i].type, nxagentArrayFormats[i].depth, nxagentArrayFormats[i].direct.red,
+                          nxagentArrayFormats[i].direct.green, nxagentArrayFormats[i].direct.blue,
+                              nxagentArrayFormats[i].direct.redMask, nxagentArrayFormats[i].direct.greenMask,
+                                  nxagentArrayFormats[i].direct.blueMask, nxagentArrayFormats[i].direct.alpha,
+                                      nxagentArrayFormats[i].direct.alphaMask);
+      #endif
+
+      pformat++;
+    }
+
+    #ifdef DEBUG
+
+    if (nxagentNumFormats == 0)
+    {
+      fprintf(stderr, "nxagentQueryFormats: Number of formats is [%d].\n",
+                  i);
+    }
+    else
+    {
+      fprintf(stderr, "nxagentQueryFormats: Old number of formats is [%d]. New number of formats is [%d].\n",
+                  nxagentNumFormats, i);
+    }
+
+    #endif
+
+    nxagentNumFormats = i;
+  }
+}
+
+void nxagentCreateGlyphSet(GlyphSetPtr pGly)
+{
+  XRenderPictFormat *pForm;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentCreateGlyphSet: Glyphset at [%p].\n", (void *) pGly);
+  #endif
+
+  pForm = NULL;
+
+  if (pGly -> format != NULL)
+  {
+    pForm = nxagentMatchingFormats(pGly -> format);
+
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+
+    if (pForm == NULL)
+    {
+      return;
+    }
+  }
+
+  pGly -> remoteID = XRenderCreateGlyphSet(nxagentDisplay, pForm);
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet)
+{
+  if (glyphSet -> remoteID == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentReferenceGlyphSet: Operation deferred because glyphset at [%p] is corrupted.\n",
+                (void *) glyphSet);
+    #endif
+
+    return;
+  }
+
+  XRenderReferenceGlyphSet (nxagentDisplay, glyphSet -> remoteID);
+}
+
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet)
+{
+  if (glyphSet -> remoteID == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentFreeGlyphs: Operation ignored because glyphset at [%p] is corrupted.\n",
+                (void *) glyphSet);
+    #endif
+
+    return;
+  }
+
+  XRenderFreeGlyphSet(nxagentDisplay, glyphSet -> remoteID);
+}
+
+void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
+                          int nglyphs, CARD8 *images, int sizeImages)
+{
+  GlyphRefPtr gr;
+  Glyph *tempGids;
+
+  int i;
+
+  CARD8 *normalizedImages;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentAddGlyphs: Glyphset at [%p]. Number of glyphs [%d].\n",
+              (void *) glyphSet, nglyphs);
+  #endif
+
+  if (glyphSet -> remoteID == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentAddGlyphs: Going to reconnect the glyhpset at [%p] before adding glyphs.\n",
+                (void *) glyphSet);
+    #endif
+
+    nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
+  }
+
+  /*
+   * By adding a glyph to a glyphset on
+   * remote X server we mark its reference
+   * as synchronized.
+   */
+
+  tempGids = gids;
+
+  for (i = 0; i < nglyphs; i++)
+  {
+    if ((gr = FindGlyphRef(&glyphSet -> hash, *tempGids, 0, 0)) &&
+            gr -> glyph != DeletedGlyph)
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentAddGlyphs: Added Glyph [%p][%ld] to glyphset [%p].\n",
+                  (void *) gr -> glyph, *tempGids, (void *) glyphSet);
+      #endif
+
+      gr -> corruptedGlyph = 0;
+    }
+
+    tempGids++;
+  }
+
+  normalizedImages = NULL;
+
+  if (glyphDepths[glyphSet -> fdepth] == 1 &&
+          nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
+  {
+    normalizedImages = xalloc(sizeImages);
+
+    if (normalizedImages != NULL)
+    {
+      memcpy(normalizedImages, images, sizeImages);
+
+      BitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
+    }
+    else
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentAddGlyphs: PANIC! Allocation of normalized glyph images failed.\n");
+      #endif
+    }
+  }
+
+  if (normalizedImages == NULL)
+  {
+    normalizedImages = images;
+  }
+
+  XRenderCleanGlyphs(gi, nglyphs, normalizedImages, glyphDepths[glyphSet -> fdepth], nxagentDisplay);
+
+  XRenderAddGlyphs(nxagentDisplay,
+                   glyphSet -> remoteID,
+                   gids,
+                   (XGlyphInfo*)(gi),
+                   nglyphs,
+                   (char*) normalizedImages,
+                   sizeImages);
+
+  if (normalizedImages != images)
+  {
+    xfree(normalizedImages);
+  }
+
+  #ifdef DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+}
+
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph)
+{
+  GlyphRefPtr gr;
+  CARD32 *tempGids;
+  Glyph  gid;
+
+  int i;
+
+  if (glyphSet -> remoteID == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentFreeGlyphs: Operation ignored because glyphset at [%p] is corrupted.\n",
+                (void *) glyphSet);
+    #endif
+
+    return;
+  }
+
+  /*
+   * We loop across the list of glyphs id
+   * to establish if they have been added
+   * to glyphset on remote X server, so
+   * they can be freed.
+   */
+
+  tempGids = gids;
+
+  for (i = 0; i < nglyph; i++)
+  {
+    gid = (Glyph)*tempGids;
+
+    if ((gr = FindGlyphRef(&glyphSet -> hash, *tempGids, 0, 0)) &&
+            gr -> glyph != DeletedGlyph &&
+                gr -> corruptedGlyph == 0)
+    {
+      XRenderFreeGlyphs(nxagentDisplay, glyphSet -> remoteID, &gid, 1);
+    }
+
+    tempGids++;
+  }
+}
+
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetPictureTransform: Going to set transform [%p] to picture at [%p].\n",
+              (void *) transform, (void *) pPicture);
+  #endif
+
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+       Apparently useless with QT.
+*/
+  #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+  XRenderSetPictureTransform(nxagentDisplay,
+                                 nxagentPicturePriv(pPicture) -> picture,
+                                     (XTransform *) transform);
+  #endif
+}
+
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+                                 pointer params, int nparams)
+{
+  char *szFilter = Xmalloc(name_size + 1);
+
+  if (szFilter == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentSetPictureFilter: error allocating memory for filter name.\n");
+    #endif
+
+    return;
+  }
+
+  strncpy(szFilter, filter, name_size);
+
+  szFilter[name_size] = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetPictureFilter: Going to set filter [%s] to picture at [%p].\n",
+              szFilter, (void *) pPicture);
+  #endif
+/*
+FIXME: Is this useful or just a waste of bandwidth?
+
+       Apparently useless with QT.
+*/
+  #ifndef SKIP_LOUSY_RENDER_OPERATIONS
+
+  XRenderSetPictureFilter(nxagentDisplay,
+                          nxagentPicturePriv(pPicture) -> picture,
+                          szFilter,
+                          (XFixed *) params,
+                          nparams);
+  #endif
+
+  Xfree(szFilter);
+}
+
+
+Bool nxagentPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+  #ifdef RENDER
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentPictureInit: Screen [%p].\n", (void *) pScreen);
+  #endif
+
+  nxagentQueryFormats();
+
+  if (fbPictureInit(pScreen, formats, nformats) == 0)
+  {
+    return FALSE;
+  }
+
+  nxagentPicturePrivateIndex = AllocatePicturePrivateIndex();
+
+  AllocatePicturePrivate(pScreen, nxagentPicturePrivateIndex, sizeof(nxagentPrivPictureRec));
+
+  #endif
+
+  return TRUE;
+}
+
+#ifdef DEBUG
+
+static void nxagentPrintFormat(XRenderPictFormat *pFormat)
+{
+  if (pFormat == NULL)
+  {
+    fprintf(stderr, "nxagentPrintFormat: WARNING! null pointer passed to function.\n");
+
+    return;
+  }
+
+  fprintf(stderr, "nxagentPrintFormat: Dumping information for format at [%p]:\n\
+                   type=%d\n\
+                   depth=%d\n\
+                   red=%d\n\
+                   redMask=%d\n\
+                   green=%d\n\
+                   greenMask=%d\n\
+                   blue=%d\n\
+                   blueMask=%d\n\
+                   alpha=%d\n\
+                   alphaMask=%d\n",
+                   (void *) pFormat,
+                   pFormat -> type,
+                   pFormat -> depth,
+                   pFormat -> direct.red,
+                   pFormat -> direct.redMask,
+                   pFormat -> direct.green,
+                   pFormat -> direct.greenMask,
+                   pFormat -> direct.blue,
+                   pFormat -> direct.blueMask,
+                   pFormat -> direct.alpha,
+                   pFormat -> direct.alphaMask);
+}
+
+#endif
+
+Bool nxagentFillGlyphSet(GlyphSetPtr pGly)
+{
+  GlyphPtr    glyph;
+
+  int i;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentFillGlyphSet: GlyphSet at [%p] Refcount [%ld] Glyphs [%ld] "
+              "Format [%p] FDepth [%d] RemoteID [%ld].\n", (void *) pGly, pGly -> refcnt,
+                  pGly -> hash.hashSet -> size, (void *) pGly -> format, pGly -> fdepth, pGly -> remoteID);
+  #endif
+
+  /*
+   * The glyphs are synchronized when they
+   * are used in a composite text. During
+   * the reconnection we have only to mark
+   * corrupted the glyphs for each glyphset.
+   */
+
+  for (i = 0; i < pGly -> hash.hashSet -> size; i++)
+  {
+    glyph = pGly -> hash.table[i].glyph;
+
+    if (glyph && (glyph != DeletedGlyph))
+    {
+      pGly -> hash.table[i].corruptedGlyph = 1;
+    }
+  }
+
+  return TRUE;
+}
+
+void nxagentReconnectGlyphSet(void* p0, XID x1, void *p2)
+{
+  GlyphSetPtr pGly = (GlyphSetPtr) p0;
+
+  XRenderPictFormat *pForm = NULL;
+
+  int i;
+
+  if (nxagentReconnectTrap == 0)
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentReconnectGlyphSet: GlyphSet at [%p].\n", (void *) pGly);
+    #endif
+
+    if (pGly -> format)
+    {
+      pForm = nxagentMatchingFormats(pGly -> format);
+    }
+
+    pGly -> remoteID = XRenderCreateGlyphSet(nxagentDisplay, pForm);
+
+    /*
+     * If we have deferred the operation, we
+     * have to check the number of references
+     * to the glyphset to update the X server.
+     */
+
+    if ((i = pGly -> refcnt) > 1)
+    {
+      while (i-- > 1)
+      {
+        nxagentReferenceGlyphSet(pGly);
+      }
+    }
+
+    #ifdef DEBUG
+
+    XSync(nxagentDisplay, 0);
+
+    #endif
+
+    nxagentFillGlyphSet(pGly);
+  }
+  else
+  {
+    pGly -> remoteID = 0;
+  }
+}
+
+Bool nxagentReconnectAllGlyphSet(void *p)
+{
+  Bool success = TRUE;
+  int i;
+
+  nxagentQueryFormats();
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconnectAllGlyphSet\n");
+  #endif
+
+  for (i = 0; (i < MAXCLIENTS) && (success); i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], GlyphSetType, nxagentReconnectGlyphSet, &success);
+    }
+  }
+
+  return success;
+}
+
+void nxagentReconnectPicture(pointer p0, XID x1, void *p2)
+{
+  PicturePtr pPicture = (PicturePtr) p0;
+  Bool *pBool = (Bool *) p2;
+  unsigned long mask = 0;
+
+  XRenderPictureAttributes attributes;
+  XRenderPictFormat        *pForm;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectPicture: Called with bool [%d] and picture at [%p].\n",
+              *pBool, (void *) pPicture);
+
+  fprintf(stderr, "nxagentReconnectPicture: Virtual picture is [%ld].\n",
+              nxagentPicture(pPicture));
+  #endif
+
+  /*
+   * Check if a previous operation has failed
+   * and that the involved objects are valid.
+   */
+
+  if (*pBool == 0 || pPicture == NULL ||
+          nxagentPicture(pPicture) != 0)
+  {
+    return;
+  }
+
+  if (pPicture -> repeat)
+  {
+    mask |= CPRepeat;
+
+    attributes.repeat = (Bool) pPicture -> repeat;
+  }
+
+  if (pPicture -> alphaMap)
+  {
+    if (!nxagentPicture(pPicture -> alphaMap))
+    {
+      nxagentReconnectPicture(pPicture -> alphaMap, 0, pBool);
+
+      if (!*pBool || !nxagentPicture(pPicture -> alphaMap))
+      {
+        return;
+      }
+    }
+
+    attributes.alpha_map = nxagentPicture(pPicture -> alphaMap);
+    attributes.alpha_x_origin = pPicture -> alphaOrigin.x;
+    attributes.alpha_y_origin = pPicture -> alphaOrigin.y;
+
+    mask |= (CPAlphaMap | CPAlphaXOrigin | CPAlphaYOrigin);
+  }
+
+  if (pPicture -> graphicsExposures)
+  {
+    attributes.graphics_exposures = pPicture -> graphicsExposures;
+
+    mask |= CPGraphicsExposure;
+  }
+
+  attributes.subwindow_mode = pPicture -> subWindowMode;
+
+  mask |= CPSubwindowMode;
+
+  attributes.poly_edge = pPicture -> polyEdge;
+
+  mask |= CPPolyEdge;
+
+  attributes.poly_mode = pPicture -> polyMode;
+
+  mask |= CPPolyMode;
+
+  attributes.dither = pPicture -> dither;
+
+  mask |= CPDither;
+
+  attributes.component_alpha = pPicture -> componentAlpha;
+
+  mask |= CPComponentAlpha;
+
+  pForm = NULL;
+
+  if (pPicture -> pFormat)
+  {
+    pForm = nxagentMatchingFormats(pPicture -> pFormat);
+
+    #ifdef DEBUG
+
+    nxagentPrintFormat(pForm);
+
+    #endif
+  }
+
+  if (!pForm)
+  {
+    *pBool = False;
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectPicture: Creating picture at [%p] with drawable [%ld] at [%p].\n",
+              (void *) pPicture, nxagentDrawable(pPicture -> pDrawable), (void *) pPicture -> pDrawable);
+
+  fprintf(stderr, "nxagentReconnectPicture: Format is at [%p] mask is [%ld] attributes are at [%p].\n",
+              (void *) pForm, mask, (void *) &attributes);
+  #endif
+
+  nxagentPicture(pPicture) = XRenderCreatePicture(nxagentDisplay,
+                                                  nxagentDrawable(pPicture -> pDrawable),
+                                                  pForm,
+                                                  mask,
+                                                  &attributes);
+
+  #ifdef TEST
+
+  XSync(nxagentDisplay, 0);
+
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectPicture: Reconnected picture at [%p] with value [%ld].\n",
+              (void *) pPicture, nxagentPicture(pPicture));
+  #endif
+
+  if (nxagentAlphaEnabled == 1 && pPicture -> pDrawable -> depth == 32 &&
+          pPicture -> pFormat -> direct.alpha != 0)
+  {
+    if (pPicture -> pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      nxagentPixmapPriv((PixmapPtr) pPicture -> pDrawable) -> pPicture = pPicture;
+    }
+    else if (pPicture -> pDrawable -> type == DRAWABLE_WINDOW)
+    {
+      nxagentWindowPriv((WindowPtr) pPicture -> pDrawable) -> pPicture = pPicture;
+    }
+  }
+}
+
+Bool nxagentReconnectAllPicture(void *p)
+{
+  int i;
+  Bool r;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectAllPicture: Going to recreate all pictures.\n");
+  #endif
+
+  for (i = 0, r = 1; i < MAXCLIENTS; i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], PictureType, nxagentReconnectPicture, &r);
+
+      #ifdef WARNING
+
+      if (r == False)
+      {
+        fprintf(stderr, "nxagentReconnectAllPicture: WARNING! Failed to recreate "
+                    "picture for client [%d].\n", i);
+      }
+
+      #endif
+    }
+  }
+
+  return True;
+}
+
+void nxagentDisconnectPicture(pointer p0, XID x1, void* p2)
+{
+  PicturePtr pPicture = (PicturePtr) p0;
+  Bool *pBool = (Bool *) p2;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentDisconnectPicture: Called with bool [%d] and picture at [%p].\n",
+              *pBool, (void *) pPicture);
+
+  fprintf(stderr, "nxagentDisconnectPicture: Virtual picture is [%ld].\n",
+              nxagentPicture(pPicture));
+  #endif
+
+  if (!*pBool || !pPicture)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentDisconnectPicture: %p - XID %lx\n",
+              (void *) pPicture, nxagentPicture(pPicture));
+  #endif
+
+  nxagentPicture(pPicture) = None;
+}
+
+Bool nxagentDisconnectAllPicture()
+{
+  int i;
+  Bool r;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentDisconnectAllPicture.\n");
+  #endif
+
+  for (i = 0, r = 1; i < MAXCLIENTS; i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], PictureType, nxagentDisconnectPicture, &r);
+
+      #ifdef WARNING
+
+      if (r == False)
+      {
+        fprintf(stderr, "nxagentDisconnectAllPicture: WARNING! Failed to disconnect "
+                    "picture for client [%d].\n", i);
+      }
+
+      #endif
+    }
+  }
+
+  return True;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
new file mode 100644
index 000000000..240dc3901
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -0,0 +1,108 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Render_H__
+#define __Render_H__
+
+#include "screenint.h"
+#include "picture.h"
+#include "renderproto.h"
+
+#include "NXglyphstr.h"
+
+#include "Agent.h"
+
+extern int nxagentRenderEnable;
+extern int nxagentRenderVersionMajor;
+extern int nxagentRenderVersionMinor;
+
+extern int nxagentPicturePrivateIndex;
+
+extern BoxPtr nxagentGlyphsExtents;
+extern BoxPtr nxagentTrapezoidExtents;
+
+/*
+ * Structure imported from Xrender.h. We don't
+ * include Xrender.h at this point because of
+ * clashes of definition.
+ */
+
+/*
+ * Xlib Pixmap and Atom types are 8 bytes long
+ * on 64-bit archs, whilst they are 4 bytes long
+ * on 32-bit ones. At this point, Pixmap and Atom
+ * are not Xlib types but Xserver ones: here they
+ * are always 4 bytes long. So that we use XlibID
+ * symbols defined below to fill the structure with
+ * fields having the right size.
+ */
+
+typedef struct {
+    int                 repeat;
+    Picture             alpha_map;
+    int                 alpha_x_origin;
+    int                 alpha_y_origin;
+    int                 clip_x_origin;
+    int                 clip_y_origin;
+    XlibPixmap          clip_mask;
+    Bool                graphics_exposures;
+    int                 subwindow_mode;
+    int                 poly_edge;
+    int                 poly_mode;
+    XlibAtom            dither;
+    Bool                component_alpha;
+} XRenderPictureAttributes_;
+
+typedef struct
+{
+  Picture picture;
+
+  XRenderPictureAttributes_ lastServerValues;
+
+} nxagentPrivPictureRec;
+
+typedef nxagentPrivPictureRec *nxagentPrivPicturePtr;
+
+#define nxagentPicturePriv(pPicture) \
+  ((nxagentPrivPicturePtr) ((pPicture) -> devPrivates[nxagentPicturePrivateIndex].ptr))
+
+#define nxagentPicture(pPicture) (nxagentPicturePriv(pPicture) -> picture)
+
+#define nxagentSetPictureRemoteValue(pPicture, pvalue, value) \
+do \
+{ \
+  nxagentPicturePriv(pPicture) -> lastServerValues.pvalue = value; \
+} \
+while (0)
+
+#define nxagentCheckPictureRemoteValue(pPicture, pvalue, value) \
+  (nxagentPicturePriv(pPicture) -> lastServerValues.pvalue == value)
+
+void nxagentRenderExtensionInit(void);
+Bool nxagentPictureInit(ScreenPtr, PictFormatPtr, int);
+
+int nxagentRenderRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor);
+
+void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
+                                  int nglyphs, CARD8 *images, int sizeImages);
+
+void nxagentReconnectPicture(pointer p0, XID x1, void *p2);
+void nxagentDisconnectPicture(pointer p0, XID x1, void* p2);
+
+void nxagentReconnectGlyphSet(void* p0, XID x1, void *p2);
+
+#endif /* __Render_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
new file mode 100644
index 000000000..cd69af665
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -0,0 +1,1112 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "X.h"
+
+#include "../../include/window.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "propertyst.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Drawable.h"
+#include "Windows.h"
+#include "Pixmaps.h"
+#include "Atoms.h"
+#include "Trap.h"
+
+#include "NXlib.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Assigned at the time the root window is
+ * initialized.
+ */
+
+WindowPtr nxagentRootlessWindow = NULL;
+
+#define TOP_LEVEL_TABLE_UNIT 100
+
+typedef struct {
+  Window xid;
+  WindowPtr pWin;
+} TopLevelParentRec;
+
+typedef struct {
+  TopLevelParentRec *elt;
+  int next;
+  int size;
+} TopLevelParentMap;
+
+static TopLevelParentMap topLevelParentMap = { NULL, 0, 0 };
+
+static void nxagentRemovePropertyFromList(void);
+
+/*
+ * This is currently unused.
+ */
+
+#ifdef TEST
+
+static void nxagentPrintRootlessTopLevelWindowMap(void);
+
+void nxagentPrintRootlessTopLevelWindowMap()
+{
+  int i;
+
+  fprintf(stderr, "nxagentPrintRootlessTopLevelWindowMap: Map size is [%d] num of entry [%d].\n",
+              topLevelParentMap.size, topLevelParentMap.next);
+
+  for (i = 0; i < topLevelParentMap.next; i++)
+  {
+    fprintf(stderr, "nxagentPrintRootlessTopLevelWindowMap: [%d] pWin at [%p] XID at [%ld].\n",
+                i, (void *) topLevelParentMap.elt[i].pWin, (long int) topLevelParentMap.elt[i].xid);
+  }
+}
+
+#endif
+
+void nxagentRootlessAddTopLevelWindow(WindowPtr pWin, Window w)
+{
+  int i;
+
+  for (i = 0; i < topLevelParentMap.next; i++)
+  {
+    if (topLevelParentMap.elt[i].pWin == pWin)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentRootlessAddTopLevelWindow: WARNING! "
+                  "Trying to add duplicated entry window at [%p] xid [%ld].\n",
+                      (void *) pWin, w);
+      #endif
+
+      topLevelParentMap.elt[i].xid = w;
+
+      return;
+    }
+  }
+
+  if (topLevelParentMap.next == topLevelParentMap.size)
+  {
+    TopLevelParentRec *ptr = topLevelParentMap.elt;
+    size_t size = (topLevelParentMap.size += TOP_LEVEL_TABLE_UNIT);
+
+    ptr = realloc(ptr, size * sizeof(TopLevelParentRec));
+
+    if (ptr == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentRootlessAddTopLevelWindow: Warning failed to allocate memory.\n");
+      #endif
+
+      return;
+    }
+
+    topLevelParentMap.elt = ptr;
+    topLevelParentMap.size = size;
+  }
+
+  topLevelParentMap.elt[topLevelParentMap.next].xid = w;
+  topLevelParentMap.elt[topLevelParentMap.next].pWin = pWin;
+  topLevelParentMap.next++;
+}
+
+WindowPtr nxagentRootlessTopLevelWindow(Window w)
+{
+  int i;
+
+  for (i = 0; i < topLevelParentMap.next; i++)
+  {
+    if (w == topLevelParentMap.elt[i].xid)
+    {
+      return topLevelParentMap.elt[i].pWin;
+    }
+  }
+
+  return NULL;
+}
+
+void nxagentRootlessDelTopLevelWindow(WindowPtr pWin)
+{
+  int i;
+
+  for (i = 0; i < topLevelParentMap.next; i++)
+  {
+    if (pWin == topLevelParentMap.elt[i].pWin)
+    {
+      topLevelParentMap.elt[i] = topLevelParentMap.elt[topLevelParentMap.next - 1];
+      topLevelParentMap.next--;
+
+      return;
+    }
+  }
+}
+
+Window nxagentRootlessWMTopLevelWindow(WindowPtr pWin);
+
+void nxagentConfigureRootlessWindow(WindowPtr pWin, int x, int y, int w, int h, int bw,
+                                        WindowPtr pSib, int stack_mode, Mask mask)
+{
+  XWindowChanges changes;
+  Window sibw = 0;
+
+  changes.x = x;
+  changes.y = y;
+  changes.width = w;
+  changes.height = h;
+  changes.border_width = bw;
+  changes.stack_mode = stack_mode;
+
+  if (pSib)
+  {
+    sibw = nxagentWindow(pSib);
+  }
+
+  if (sibw)
+  {
+    changes.sibling = sibw;
+  }
+
+  XConfigureWindow(nxagentDisplay, nxagentWindow(pWin), mask, &changes);
+}
+
+void nxagentCirculateRootlessWindows(int direction)
+{
+  XCirculateSubwindows(nxagentDisplay, DefaultRootWindow(nxagentDisplay), direction);
+}
+
+#ifdef DEBUG
+
+Bool nxagentRootlessTreesMatch()
+{
+  Window root_return;
+  Window parent_return;
+  Window *children_return;
+  unsigned int nChildrenReturn;
+  WindowPtr pW;
+  WindowPtr pTestWin = WindowTable[0] -> firstChild;
+  Bool treesMatch = True;
+  Status result;
+
+  result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                          &root_return, &parent_return, &children_return, &nChildrenReturn);
+
+  if (!result)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentRootlessTreesMatch: WARNING! Failed QueryTree request.\n");
+    #endif
+
+    return False;
+  }
+
+  while (nChildrenReturn > 0)
+  {
+    pW = nxagentWindowPtr(children_return[--nChildrenReturn]);
+
+    if (!pW)
+    {
+      pW = nxagentRootlessTopLevelWindow(children_return[nChildrenReturn]);
+    }
+
+    if (pW && pW != WindowTable[0])
+    {
+      if (treesMatch && pTestWin && pTestWin == pW)
+      {
+        pTestWin = pTestWin -> nextSib;
+      }
+      else
+      {
+        treesMatch = False;
+      }
+    }
+  }
+
+  if (children_return)
+  {
+    XFree(children_return);
+  }
+
+  return treesMatch;
+}
+
+#endif
+
+#ifndef _XSERVER64
+void nxagentRootlessRestack(Window children[], unsigned int nchildren)
+#else
+void nxagentRootlessRestack(unsigned long children[], unsigned int nchildren)
+#endif
+{
+  WindowPtr *toplevel;
+  unsigned int ntoplevel;
+  int i;
+  WindowPtr pWin;
+  ClientPtr pClient;
+  XID values[2];
+  Mask mask;
+
+  toplevel = xalloc(sizeof(WindowPtr) * nchildren);
+  ntoplevel = 0;
+
+  for(i = 0; i < nchildren; i++)
+  {
+    pWin = nxagentWindowPtr(children[i]);
+
+    if (!pWin)
+    {
+      pWin = nxagentRootlessTopLevelWindow(children[i]);
+    }
+
+    if (pWin && pWin != WindowTable[0])
+    {
+      toplevel[ntoplevel++] = pWin;
+    }
+  }
+
+  if (!ntoplevel)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRootlessRestack: External top level windows before restack:");
+
+  for (i = 0; i < ntoplevel; i++)
+  {
+    fprintf(stderr, "[%p]\n", toplevel[i]);
+  }
+
+  fprintf(stderr, "nxagentRootlessRestack: Internal top level windows before restack:");
+
+  for (pWin = WindowTable[0] -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
+  {
+    fprintf(stderr, "[%p]\n", pWin);
+  }
+
+  #endif
+
+  pWin = WindowTable[0] -> firstChild;
+
+  values[1] = (XID) Above;
+
+  while(ntoplevel-- > 0 && pWin != NULL)
+  {
+    if (toplevel[ntoplevel] != pWin)
+    {
+      mask = CWSibling | CWStackMode;
+      values[0] = pWin -> drawable.id;
+      pClient = wClient(toplevel[ntoplevel]);
+      nxagentScreenTrap = 1;
+      ConfigureWindow(toplevel[ntoplevel], mask, (XID *) values, pClient);
+      nxagentScreenTrap = 0;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentRootlessRestack: Restacked window [%p].\n", (void*) toplevel[ntoplevel]);
+      #endif
+    }
+
+    pWin = toplevel[ntoplevel] -> nextSib;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRootlessRestack: External top level windows after restack:");
+
+  ntoplevel = i;
+
+  for (i = 0; i < ntoplevel; i++)
+  {
+    fprintf(stderr, "[%p]\n", toplevel[i]);
+  }
+
+  fprintf(stderr, "nxagentRootlessRestack: Internal top level windows after restack:");
+
+  for (pWin = WindowTable[0] -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
+  {
+    fprintf(stderr, "[%p]\n", pWin);
+  }
+
+  #endif
+
+  xfree(toplevel);
+
+  return;
+}
+
+/*
+ * Determine if window is a top-level window.
+ */
+
+Window nxagentRootlessWindowParent(WindowPtr pWin)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentRootlessWindowParent: Called for window at [%p][%ld] with parent [%p][%ld].\n",
+              (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin->parent,
+                  (pWin->parent ? nxagentWindowPriv(pWin->parent)->window : 0));
+  #endif
+
+  if (pWin -> parent == NULL)
+  {
+    return DefaultRootWindow(nxagentDisplay);
+  }
+  else if (pWin -> parent == nxagentRootlessWindow)
+  {
+    return DefaultRootWindow(nxagentDisplay);
+  }
+  else
+  {
+    return nxagentWindow(pWin -> parent);
+  }
+}
+
+int nxagentExportAllProperty(pWin)
+  WindowPtr pWin;
+{
+  PropertyPtr pProp;
+  int total = 0;
+
+  for (pProp = wUserProps(pWin); pProp; pProp = pProp->next)
+  {
+    total += nxagentExportProperty(pWin,
+                                       pProp->propertyName,
+                                           pProp->type,
+                                               pProp->format,
+                                                   PropModeReplace,
+                                                       pProp->size,
+                                                           pProp->data);
+  }
+
+  return total;
+}
+
+int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
+    WindowPtr   pWin;
+    Atom        property, type;
+    int         format, mode;
+    unsigned long nUnits;
+    pointer     value;
+{
+  char *propertyS, *typeS;
+  Atom propertyX, typeX;
+  char *output = NULL;
+  XWMHints wmHints;
+  Bool export = False;
+  Bool freeMem = False;
+
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    return 0;
+  }
+
+  propertyS = NameForAtom(property);
+  typeS = NameForAtom(type);
+
+  if (strncmp(propertyS, "WM_", 3) != 0 &&
+          strncmp(propertyS, "_NET_", 5) != 0 &&
+              strcmp(propertyS, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR") != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentExportProperty: WARNING! Ignored ChangeProperty "
+                "on %swindow %lx property %s type %s nUnits %ld format %d\n",
+                    nxagentWindowTopLevel(pWin) ? "toplevel " : "", nxagentWindow(pWin),
+                        validateString(propertyS), validateString(typeS), nUnits, format);
+    #endif
+  }
+  else if (strcmp(typeS, "STRING") == 0 ||
+               #ifndef _XSERVER64
+               strcmp(typeS, "CARDINAL") == 0 ||
+                   strcmp(typeS, "WM_SIZE_HINTS") == 0 ||
+               #endif
+                       strcmp(typeS, "UTF8_STRING") == 0)
+  {
+    output = value;
+    export = True;
+  }
+  #ifdef _XSERVER64
+  else if (strcmp(typeS, "CARDINAL") == 0 || strcmp(typeS, "WM_SIZE_HINTS") == 0)
+  {
+    unsigned long *buffer = malloc(nUnits * sizeof(*buffer));
+    int *input = value;
+    int i;
+
+    if (buffer)
+    {
+      freeMem = True;
+      export = True;
+      output = (char*) buffer;
+
+      for (i = 0; i < nUnits; i++)
+      {
+        buffer[i] = input[i];
+      }
+    }
+  }
+  #endif
+  else if (strcmp(typeS, "WM_HINTS") == 0)
+  {
+    ClientPtr pClient = wClient(pWin);
+    wmHints = *(XWMHints*)value;
+
+    wmHints.flags |= InputHint;
+    wmHints.input = True;
+
+    output = (char*) &wmHints;
+    export  = True;
+
+    if ((wmHints.flags & IconPixmapHint) && (wmHints.icon_pixmap != None))
+    {
+      PixmapPtr icon = (PixmapPtr)SecurityLookupIDByType(pClient, wmHints.icon_pixmap,
+                                                             RT_PIXMAP, SecurityDestroyAccess);
+
+      if (icon)
+      {
+        if (nxagentDrawableStatus((DrawablePtr) icon) == NotSynchronized)
+        {
+          nxagentSynchronizeRegion((DrawablePtr) icon, NullRegion, NEVER_BREAK, NULL);
+        }
+
+        wmHints.icon_pixmap = nxagentPixmap(icon);
+      }
+      else
+      {
+        wmHints.flags &= ~IconPixmapHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon pixmap %lx from hint "
+                    "exporting property %s type %s on window %p.\n",
+                        wmHints.icon_pixmap, propertyS, typeS, (void*)pWin);
+        #endif
+      }
+    }
+
+    if ((wmHints.flags & IconWindowHint) && (wmHints.icon_window != None))
+    {
+      WindowPtr icon = (WindowPtr)SecurityLookupWindow(wmHints.icon_window, pClient,
+                                                  SecurityDestroyAccess);
+
+      if (icon)
+      {
+        wmHints.icon_window = nxagentWindow(icon);
+      }
+      else
+      {
+        wmHints.flags &= ~IconWindowHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon window %lx from hint "
+                    "exporting property %s type %s on window %p.\n",
+                        wmHints.icon_window, propertyS, typeS, (void*)pWin);
+        #endif
+      }
+    }
+
+    if ((wmHints.flags & IconMaskHint) && (wmHints.icon_mask != None))
+    {
+      PixmapPtr icon = (PixmapPtr)SecurityLookupIDByType(pClient, wmHints.icon_mask,
+                                                             RT_PIXMAP, SecurityDestroyAccess);
+
+      if (icon)
+      {
+        wmHints.icon_mask = nxagentPixmap(icon);
+      }
+      else
+      {
+        wmHints.flags &= ~IconMaskHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon mask %lx from hint "
+                    "exporting property %s type %s on window %p.\n",
+                        wmHints.icon_mask, propertyS, typeS, (void*)pWin);
+        #endif
+      }
+    }
+
+    if ((wmHints.flags & WindowGroupHint) && (wmHints.window_group != None))
+    {
+      WindowPtr window = (WindowPtr)SecurityLookupWindow(wmHints.window_group, pClient,
+                                                  SecurityDestroyAccess);
+
+      if (window)
+      {
+        wmHints.window_group = nxagentWindow(window);
+      }
+      else
+      {
+        wmHints.flags &= ~WindowGroupHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window group %lx from hint "
+                    "exporting property %s type %s on window %p.\n",
+                        wmHints.window_group, propertyS, typeS, (void*)pWin);
+        #endif
+      }
+    }
+  }
+  else if (strcmp(typeS, "ATOM") == 0)
+  {
+    XlibAtom *atoms = malloc(nUnits * sizeof(*atoms));
+    Atom *input = value;
+    int i;
+
+    freeMem = True;
+    export = True;
+    output = (char *) atoms;
+
+    for (i = 0; i < nUnits; i++)
+    {
+       atoms[i] = nxagentLocalToRemoteAtom(input[i]);
+
+       if (atoms[i] == None)
+       {
+         #ifdef WARNING
+         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
+                     (long int) input[i], validateString(NameForAtom(input[i])));
+         #endif
+       }
+    }
+  }
+  else if (strcmp(typeS, "WINDOW") == 0)
+  {
+    Window *input = value;
+    XlibWindow *wind = malloc(nUnits * sizeof(*wind));
+    ClientPtr pClient = wClient(pWin);
+    WindowPtr pWindow;
+    int i;
+
+    freeMem = True;
+    export = True;
+    output = (char*) wind;
+
+    for (i = 0; i < nUnits; i++)
+    {
+      pWindow = (WindowPtr)SecurityLookupWindow(input[i], pClient,
+                                                    SecurityDestroyAccess);
+      if ((input[i] != None) && pWindow)
+      {
+        wind[i] = nxagentWindow(pWindow);
+      }
+      else
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window %ld "
+                    "exporting property %s type %s on window %p.\n",
+                        (long int) input[i], propertyS, typeS, (void *) pWin);
+        #endif
+
+        /*
+         * It seems that clients specifie
+         * strange windows, perhaps are
+         * not real windows so we can try
+         * to let them pass anyway.
+         *
+         * wind[i] = None;
+         *
+         */
+      }
+    }
+  }
+
+  if (export)
+  {
+    propertyX = nxagentLocalToRemoteAtom(property);
+    typeX = nxagentLocalToRemoteAtom(type);
+
+    if (propertyX == None || typeX == None)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom.\n");
+      #endif
+
+      export = 0;
+    }
+    else
+    {
+      XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX, format, mode, (void*)output, nUnits);
+      nxagentAddPropertyToList(propertyX, pWin);
+    }
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentExportProperty: WARNING! Ignored ChangeProperty "
+                "on %swindow %lx property %s type %s nUnits %ld format %d\n",
+                    nxagentWindowTopLevel(pWin) ? "toplevel " : "",
+                        nxagentWindow(pWin), validateString(propertyS), validateString(typeS),
+                            nUnits, format);
+    #endif
+  }
+
+  if (freeMem)
+  {
+    xfree(output);
+  }
+
+  return export;
+}
+
+void nxagentImportProperty(Window window,
+                           Atom property,
+                           Atom type,
+                           int format,
+                           unsigned long nitems,
+                           unsigned long bytes_after,
+                           unsigned char *buffer)
+{
+  Atom propertyL;
+  Atom typeL;
+
+  WindowPtr pWin;
+  Bool import = False;
+  Bool freeMem = False;
+  XWMHints wmHints;
+
+  typedef struct {
+      CARD32 state;
+      Window icon;
+    } WMState;
+  WMState wmState;
+
+  char *output = NULL;
+  char *typeS;
+
+  pWin = nxagentWindowPtr(window);
+
+  if (pWin == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentImportProperty: Failed to look up remote window %lx  property [%ld] exiting.\n",
+                window, property);
+    #endif
+
+    return;
+  }
+
+  propertyL = nxagentRemoteToLocalAtom(property);
+
+  if (!ValidAtom(propertyL))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentImportProperty: Failed to convert remote property atom.\n");
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentImportProperty: Window %lx property [%ld]: %s\n",
+              window, property, validateString(NameForAtom(propertyL)));
+  #endif
+
+  /*
+   * We settle a property size limit of
+   * 256K beyond which we simply ignore them.
+   */
+
+  typeL = nxagentRemoteToLocalAtom(type);
+  typeS = NameForAtom(typeL);
+
+  if (buffer == NULL && (nitems > 0))
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentImportProperty: Failed to retrieve remote property [%ld] %s on Window %ld\n",
+                (long int) property, validateString(NameForAtom(propertyL)), (long int) window);
+    #endif
+  }
+  else if (bytes_after != 0)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentImportProperty: Remote property bigger than maximum limits.\n");
+    #endif
+  }
+  else if (!ValidAtom(typeL))
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentImportProperty: Failed to convert remote atoms [%ld].\n",
+                (long int) type);
+    #endif
+  }
+  else if (nitems == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentImportProperty: Importing void property.\n");
+    #endif
+
+    import = True;
+  }
+  else if (strcmp(typeS, "STRING") == 0 ||
+               strcmp(typeS, "UTF8_STRING") == 0 ||
+                   strcmp(typeS, "CARDINAL") == 0 ||
+                       strcmp(typeS, "WM_SIZE_HINTS") == 0)
+  {
+    output = (char*)buffer;
+    import = True;
+  }
+  else if (strcmp(typeS, "WM_STATE") == 0)
+  {
+    /*
+     * Contents of property of type WM_STATE
+     * are {CARD32 state, WINDOW icon}. Only
+     * the icon field has to be modified before
+     * importing the property.
+     */
+
+    WindowPtr pIcon;
+
+    wmState = *(WMState*)buffer;
+    pIcon = nxagentWindowPtr(wmState.icon);
+
+    if (pIcon || wmState.icon == None)
+    {
+      import = True;
+      output = (char*) &wmState;
+      wmState.icon = pIcon ? nxagentWindow(pIcon) : None;
+    }
+    else if (wmState.icon)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentImportProperty: WARNING! Failed to convert remote window %ld"
+                  " importing property %ld of type WM_STATE", (long int) wmState.icon,
+                      (long int) property);
+      #endif
+    }
+  }
+  else if (strcmp(typeS, "WM_HINTS") == 0)
+  {
+    wmHints = *(XWMHints*)buffer;
+    output = (char*) &wmHints;
+    import = True;
+
+    if ((wmHints.flags & IconPixmapHint) && (wmHints.icon_pixmap != None))
+    {
+      PixmapPtr icon = nxagentPixmapPtr(wmHints.icon_pixmap);
+
+      if (icon)
+      {
+        wmHints.icon_pixmap = icon -> drawable.id;
+      }
+      else
+      {
+        wmHints.flags &= ~IconPixmapHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote icon "
+                    "pixmap %ld from hint importing property [%ld] type %s on window %p.\n",
+                        wmHints.icon_pixmap, (long int) property, typeS, (void *) pWin);
+        #endif
+      }
+    }
+
+    if ((wmHints.flags & IconWindowHint) && (wmHints.icon_window =! None))
+    {
+      WindowPtr icon = nxagentWindowPtr(wmHints.icon_window);
+
+      if (icon)
+      {
+        wmHints.icon_window = icon -> drawable.id;
+      }
+      else
+      {
+        wmHints.flags &= ~IconWindowHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagenImportProperty: WARNING! Failed to look up remote icon "
+                    "window %lx from hint importing property [%ld] type %s on window %p.\n",
+                         wmHints.icon_window, (long int) property, typeS, (void *) pWin);
+        #endif
+      }
+    }
+
+    if ((wmHints.flags & IconMaskHint) && (wmHints.icon_mask =! None))
+    {
+      PixmapPtr icon = nxagentPixmapPtr(wmHints.icon_mask);
+
+      if (icon)
+      {
+        wmHints.icon_mask = icon -> drawable.id;
+      }
+      else
+      {
+        wmHints.flags &= ~IconMaskHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote icon "
+                    "mask %lx from hint importing property [%ld] type %s on window %p.\n",
+                          wmHints.icon_mask, (long int) property, typeS, (void *) pWin);
+        #endif
+      }
+    }
+
+    if ((wmHints.flags & WindowGroupHint) && (wmHints.window_group != None))
+    {
+      WindowPtr group = nxagentWindowPtr(wmHints.window_group);
+
+      if (group)
+      {
+        wmHints.window_group = group -> drawable.id;
+      }
+      else
+      {
+        wmHints.flags &= ~WindowGroupHint;
+
+        #ifdef WARNING
+        fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote window "
+                    "group %lx from hint importing property [%ld] type %s on window %p.\n",
+                          wmHints.window_group, (long int) property, typeS, (void *) pWin);
+        #endif
+      }
+    }
+  }
+  else if (strcmp(typeS, "ATOM") == 0)
+  {
+    Atom *atoms = malloc(nitems * sizeof(Atom));
+    Atom *input = (Atom*) buffer;
+    int i;
+
+    if (atoms == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentImportProperty: WARNING! Malloc failed bailing out.\n");
+      #endif
+
+      return;
+    }
+
+    freeMem = True;
+    import = True;
+    output = (char *) atoms;
+
+    for (i = 0; i < nitems; i++)
+    {
+      atoms[i] = nxagentRemoteToLocalAtom(input[i]);
+
+      if (atoms[i] == None)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentImportProperty: WARNING! Failed to convert remote atom %ld.\n",
+                    (long int) input[i]);
+        #endif
+      }
+    }
+  }
+  else if (strcmp(typeS, "WINDOW") == 0)
+  {
+    Window *input = (Window*) buffer;
+    Window *wind = malloc(nitems * sizeof(Window));
+    WindowPtr pWindow;
+    int i;
+
+    freeMem = True;
+    import = True;
+    output = (char*) wind;
+
+    for (i = 0; i < nitems; i++)
+    {
+      pWindow = nxagentWindowPtr(input[i]);
+
+      if (pWindow)
+      {
+        wind[i] = pWindow -> drawable.id;
+      }
+      else
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote window %lx "
+                    "importing property [%ld] type %s on window %p.\n",
+                        (long int) input[i], (long int) property, typeS, (void*)pWin);
+        #endif
+
+        wind[i] = None;
+      }
+    }
+  }
+
+  if (import)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentImportProperty: ChangeProperty "
+                "on window %lx property [%ld] type %s nitems %ld format %d\n",
+                    window, property, typeS, nitems, format);
+    #endif
+
+    ChangeWindowProperty(pWin, propertyL, typeL, format,
+                             PropModeReplace, nitems, output, 1);
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentImportProperty: WARNING! Ignored ChangeProperty "
+                "on window %lx property [%ld] type %s ntems %ld format %d\n",
+                       window, property, validateString(typeS), nitems, format);
+    #endif
+  }
+
+  if (freeMem)
+  {
+    xfree(output);
+  }
+
+  return;
+}
+
+/*
+ * We want to import all properties changed by external clients to
+ * reflect properties of our internal windows but we must ignore
+ * all the property notify events generated by our own requests.
+ * For this purpose we implement a FIFO to record every change pro-
+ * perty request that we dispatch. In this way, when processing a
+ * property notify, we can distinguish between the notifications
+ * generated by our requests from those generated by other clients
+ * connected to the real X server.
+ */
+
+struct nxagentPropertyRec{
+  Window window;
+  Atom property;
+  struct nxagentPropertyRec *next;
+};
+
+static struct{
+  struct nxagentPropertyRec *first;
+  struct nxagentPropertyRec *last;
+  int size;
+} nxagentPropertyList = {NULL, NULL, 0};
+
+/*
+ * Removing first element from list.
+ */
+
+void nxagentRemovePropertyFromList()
+{
+  struct nxagentPropertyRec *tmp = nxagentPropertyList.first;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRemovePropertyFromList: Property %ld on Window %lx to list, list size is %d.\n\n",
+              nxagentPropertyList.first -> property, nxagentPropertyList.first -> window,
+                 nxagentPropertyList.size);
+  #endif
+
+  if (nxagentPropertyList.first)
+  {
+    nxagentPropertyList.first = nxagentPropertyList.first -> next;
+
+    if (--nxagentPropertyList.size == 0)
+    {
+      nxagentPropertyList.last = NULL;
+    }
+
+    xfree(tmp);
+  }
+}
+
+/*
+ * Add the record to the list.
+ */
+
+void nxagentAddPropertyToList(Atom property, WindowPtr pWin)
+{
+  struct nxagentPropertyRec *tmp;
+
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    return;
+  }
+
+  if ((tmp = malloc(sizeof(struct nxagentPropertyRec))) == NULL)
+  {
+    FatalError("nxagentAddPropertyToList: malloc failed.");
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentAddPropertyToList: Adding record Property %ld - Window %lx[%p]"
+             "to list, list size is %d.\n", property, nxagentWindow(pWin), (void*) pWin,
+                 nxagentPropertyList.size);
+  #endif
+
+  tmp -> property = property;
+  tmp -> window = nxagentWindow(pWin);
+  tmp -> next = NULL;
+
+  if (nxagentPropertyList.size == 0)
+  {
+    nxagentPropertyList.first = tmp;
+  }
+  else
+  {
+    nxagentPropertyList.last -> next = tmp;
+  }
+
+  nxagentPropertyList.last = tmp;
+  nxagentPropertyList.size++;
+}
+
+void nxagentFreePropertyList()
+{
+  while (nxagentPropertyList.size != 0)
+  {
+    nxagentRemovePropertyFromList();
+  }
+}
+
+/*
+ * We are trying to distinguish notify generated by
+ * an external client from those genarated by our
+ * own requests.
+ */
+
+Bool nxagentNotifyMatchChangeProperty(void *p)
+{
+  struct nxagentPropertyRec *first = nxagentPropertyList.first;
+  XPropertyEvent *X = p;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentNotifyMatchChangeProperty: Property notify on window %lx property %ld.\n",
+              X -> window, X -> atom);
+
+  if (first)
+  {
+    fprintf(stderr, "nxagentNotifyMatchChangeProperty: First element on list is window %lx property %ld list size is %d.\n",
+                first -> window, first -> property, nxagentPropertyList.size);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentNotifyMatchChangeProperty: List is empty.\n");
+  }
+  #endif
+
+  if (first == NULL ||
+          X -> window != first -> window ||
+              X -> atom != first -> property)
+  {
+    return False;
+  }
+
+  nxagentRemovePropertyFromList();
+
+  return True;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
new file mode 100644
index 000000000..90d25d0c1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
@@ -0,0 +1,93 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Rootless_H__
+#define __Rootless_H__
+
+#include "window.h"
+
+/*
+ * The real X server's root window if we
+ * are in rootless mode.
+ */
+
+extern WindowPtr nxagentRootlessWindow;
+
+/*
+ * We want to import all properties changed by external clients to
+ * reflect properties of our internal windows but we must ignore
+ * all the property notify events generated by our own requests.
+ * For this purpose we implement a FIFO to record every change pro-
+ * perty request that we dispatch. In this way, when processing a
+ * property notify, we can distinguish between the notifications
+ * generated by our requests from those generated by other clients
+ * connected to the real X server.
+ */
+
+typedef struct
+{
+  Window window;
+  Atom property;
+} PropertyRequestRec;
+
+extern PropertyRequestRec nxagentPropertyRequests[256];
+
+Window nxagentRootlessWindowParent(WindowPtr pWin);
+
+void nxagentRootlessAddTopLevelWindow(WindowPtr pWin, Window w);
+void nxagentRootlessDelTopLevelWindow(WindowPtr pWin);
+
+WindowPtr nxagentRootlessTopLevelWindow(Window w);
+
+#ifndef _XSERVER64
+void nxagentRootlessRestack(Window *toplevel, unsigned int ntoplevel);
+#else
+void nxagentRootlessRestack(unsigned long *toplevel, unsigned int ntoplevel);
+#endif
+
+
+int nxagentExportAllProperty(WindowPtr pWin);
+
+int nxagentExportProperty(WindowPtr pWin, Atom property, Atom type, int format,
+                              int mode, unsigned long nUnits, pointer value);
+
+#define MAX_RETRIEVED_PROPERTY_SIZE 256 * 1024
+
+void nxagentImportProperty(Window window, Atom property, Atom type, int format,
+                               unsigned long nitems, unsigned long bytes_after, unsigned char *buffer);
+
+/*
+ * Push last ChangeProperty to the list.
+ */
+
+void nxagentAddPropertyToList(Atom property, WindowPtr pWin);
+
+/*
+ * Check if a PropertyNotify match the top
+ * of the list.
+ */
+
+Bool nxagentNotifyMatchChangeProperty(void *X);
+
+void nxagentConfigureRootlessWindow(WindowPtr pWin, int x, int y, int w, int h, int bw,
+                                        WindowPtr pSib, int stack_mode, Mask mask);
+
+void nxagentCirculateRootlessWindows(int direction);
+
+void nxagentFreePropertyList(void);
+
+#endif /* __Rootless_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
new file mode 100644
index 000000000..255da3362
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -0,0 +1,3984 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+/*
+ * Used by the auto-disconnect feature.
+ */
+
+#include <signal.h>
+
+#include "scrnintstr.h"
+#include "dix.h"
+#include "dixstruct.h"
+#include "mi.h"
+#include "micmap.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "mipointer.h"
+#include "../../fb/fb.h"
+#include "../../randr/randrstr.h"
+#include "inputstr.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "Extensions.h"
+#include "Atoms.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Image.h"
+#include "Drawable.h"
+#include "Font.h"
+#include "Colormap.h"
+#include "Cursor.h"
+#include "Visual.h"
+#include "Events.h"
+#include "Init.h"
+#include "Args.h"
+#include "Client.h"
+#include "Options.h"
+#include "Splash.h"
+#include "Holder.h"
+#include "Render.h"
+#include "Trap.h"
+#include "Keyboard.h"
+#include "Pointer.h"
+#include "Reconnect.h"
+#include "Composite.h"
+#include "Shadow.h"
+#include "Utils.h"
+
+#include "Xrandr.h"
+#include <X11/Xlibint.h>
+
+#include "Xatom.h"
+#include "Xproto.h"
+
+#include "NXlib.h"
+
+#include "mibstorest.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+#undef  WATCH
+#undef  DUMP
+
+/*
+ * Display a pixmap on an shadow
+ * display used for debug.
+ */
+
+#ifdef DUMP
+
+void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height);
+
+void nxagentFbRestoreArea(PixmapPtr pPixmap, WindowPtr pWin, int xSrc, int ySrc, int width,
+                              int height, int xDst, int yDst)
+#endif
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+extern Bool nxagentIpaq;
+extern Pixmap nxagentIconPixmap;
+extern Pixmap nxagentIconShape;
+extern Bool useXpmIcon;
+
+/*
+ * From randr/randr.c.
+ */
+
+extern Bool RRGetInfo(ScreenPtr pScreen);
+extern void RRSendConfigNotify(ScreenPtr pScreen);
+extern void RREditConnectionInfo(ScreenPtr pScreen);
+
+Window nxagentDefaultWindows[MAXSCREENS];
+Window nxagentInputWindows[MAXSCREENS];
+Window nxagentScreenSaverWindows[MAXSCREENS];
+
+#ifdef NXAGENT_ONSTART
+Atom nxagentWMStart;
+Window nxagentSplashWindow = None;
+Pixmap nxagentPixmapLogo;
+#endif
+
+ScreenPtr nxagentDefaultScreen = NULL;
+int nxagentArgc = 0;
+char **nxagentArgv = NULL;
+
+#ifdef NXAGENT_ARTSD
+
+char mcop_atom[] = "MCOPGLOBALS";
+Atom mcop_local_atom = None;
+unsigned char fromHexNibble(char c);
+void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+
+#endif
+
+Window nxagentIconWindow = None;
+Window nxagentFullscreenWindow = None;
+
+#ifdef VIEWPORT_FRAME
+
+WindowPtr nxagentViewportFrameLeft;
+WindowPtr nxagentViewportFrameRight;
+WindowPtr nxagentViewportFrameAbove;
+WindowPtr nxagentViewportFrameBelow;
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+Bool nxagentCreateScreenResources(ScreenPtr pScreen);
+void nxagentPrintAgentGeometry(char *hdrMessage, char *prefix);
+
+/*
+ * These variables are for shadowing feature.
+ */
+
+int nxagentShadowResize = 0;
+ 
+WindowPtr nxagentShadowWindowPtr = NULL;
+
+static XID           accessPixmapID;
+static Window        accessWindowID;
+static int           imageByteOrder;
+static unsigned char nxagentMasterDepth;
+static unsigned char nxagentCheckDepth = 0;
+static unsigned int  nxagentBppShadow;
+static unsigned int  nxagentBppMaster;
+int                  nxagentShadowXConnectionNumber;
+GCPtr                nxagentShadowGCPtr = NULL;
+PixmapPtr            nxagentShadowPixmapPtr = NULL;
+char *               nxagentShadowBuffer;
+unsigned char        nxagentShadowDepth;
+int                  nxagentShadowWidth;
+int                  nxagentShadowHeight;
+Display *            nxagentShadowDisplay;
+short                nxagentShadowUid = -1;
+
+void nxagentShadowAdaptDepth(unsigned int, unsigned int, unsigned int, char **);
+
+RegionRec nxagentShadowUpdateRegion;
+
+#define NXAGENT_DEFAULT_DPI 75
+
+/*
+ * From randr/randr.c. This was originally static
+ * but we need it here.
+ */
+
+int TellChanged(WindowPtr pWin, pointer value);
+
+int nxagentBitsPerPixel(int depth)
+{
+    if (depth == 1) return 1;
+    else if (depth <= 8) return 8;
+    else if (depth <= 16) return 16;
+    else return 32;
+}
+
+void nxagentSetScreenInfo(ScreenInfo *screenInfo)
+{
+  /*
+   * Setup global screen info parameters. In the Xnest
+   * server this stuff is done after having opened the
+   * real display as Xnest lets the screen reflect the
+   * order of the remote end. Agent will instead set
+   * the order according to local endianess and swap
+   * data whenever it is appropriate.
+   *
+   * From a standard implementation:
+   *
+   * screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+   * screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+   * screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+   * screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+   *
+   * From Xnest implementation:
+   *
+   * screenInfo -> imageByteOrder = ImageByteOrder(nxagentDisplay);
+   * screenInfo -> bitmapScanlineUnit = BitmapUnit(nxagentDisplay);
+   * screenInfo -> bitmapScanlinePad = BitmapPad(nxagentDisplay);
+   * screenInfo -> bitmapBitOrder = BitmapBitOrder(nxagentDisplay);
+   */
+
+  screenInfo -> imageByteOrder = IMAGE_BYTE_ORDER;
+  screenInfo -> bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+  screenInfo -> bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+  screenInfo -> bitmapBitOrder = BITMAP_BIT_ORDER;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetScreenInfo: Server image order is [%d] bitmap order is [%d].\n",
+              screenInfo -> imageByteOrder, screenInfo -> bitmapBitOrder);
+
+  fprintf(stderr, "nxagentSetScreenInfo: Server scanline unit is [%d] scanline pad is [%d].\n",
+              screenInfo -> bitmapScanlineUnit, screenInfo -> bitmapScanlinePad);
+  #endif
+}
+
+void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
+{
+  int i;
+
+  /*
+   * 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.
+   */
+
+  screenInfo -> numPixmapFormats = nxagentNumPixmapFormats;
+
+  for (i = 0; i < nxagentNumPixmapFormats; i++)
+  {
+    screenInfo -> formats[i].depth = nxagentPixmapFormats[i].depth;
+    screenInfo -> formats[i].bitsPerPixel = nxagentPixmapFormats[i].bits_per_pixel;
+    screenInfo -> formats[i].scanlinePad = nxagentPixmapFormats[i].scanline_pad;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSetPixmapFormats: Set format at index [%d] to depth [%d] "
+                "bits per pixel [%d] scanline pad [%d].\n", i,
+                    screenInfo -> formats[i].depth, screenInfo -> formats[i].bitsPerPixel,
+                        screenInfo -> formats[i].scanlinePad);
+    #endif
+  }
+}
+
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
+{
+  XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
+
+  if(nxagentIpaq)
+  {
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+  }
+  else
+  {
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+  }
+}
+
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
+{
+  if(nxagentIpaq)
+  {
+    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+
+    XMapWindow(nxagentDisplay, nxagentFullscreenWindow);
+  }
+  else
+  {
+/*
+    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+    XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+/*
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+  }
+}
+
+Window nxagentCreateIconWindow()
+{
+  XSetWindowAttributes attributes;
+  unsigned long valuemask;
+  char* window_name;
+  XTextProperty windowName;
+  XSizeHints sizeHints;
+  XWMHints wmHints;
+  Window w;
+  Mask mask;
+
+  /*
+   * Create icon window.
+   */
+
+  attributes.override_redirect = False;
+  attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
+  attributes.background_pixmap = nxagentScreenSaverPixmap;
+  valuemask = CWOverrideRedirect | CWBackPixmap | CWColormap;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateIconWindow: Going to create new icon window.\n");
+  #endif
+
+  w = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                        0, 0, 1, 1, 0,
+                            DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+                                InputOutput,
+                                    DefaultVisual(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+                                        valuemask, &attributes);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateIconWindow: Created new icon window with id [%ld].\n",
+              nxagentIconWindow);
+  #endif
+
+  /*
+   *  Set hints to the window manager for the icon window.
+   */
+
+  window_name = nxagentWindowName;
+  XStringListToTextProperty(&window_name, 1, &windowName);
+  sizeHints.flags = PMinSize | PMaxSize;
+  sizeHints.min_width = sizeHints.max_width = 1;
+  sizeHints.min_height = sizeHints.max_height = 1;
+  wmHints.flags = IconPixmapHint | IconMaskHint;
+  wmHints.initial_state = IconicState;
+  wmHints.icon_pixmap = nxagentIconPixmap;
+
+  if (useXpmIcon)
+  {
+    wmHints.icon_mask = nxagentIconShape;
+    wmHints.flags = IconPixmapHint | IconMaskHint;
+  }
+  else
+  {
+    wmHints.flags = StateHint | IconPixmapHint;
+  }
+
+  XSetWMProperties(nxagentDisplay, w,
+                      &windowName, &windowName,
+                          NULL , 0 , &sizeHints, &wmHints, NULL);
+
+  /*
+   * Enable events from the icon window.
+   */
+
+  nxagentGetDefaultEventMask(&mask);
+
+  XSelectInput(nxagentDisplay, w, (mask & ~(KeyPressMask |
+                   KeyReleaseMask)) | StructureNotifyMask);
+
+  /*
+   * Notify to client if user closes icon window.
+   */
+
+  if (nxagentWMIsRunning && !nxagentOption(Rootless))
+  {
+    XlibAtom deleteWMAtom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
+
+    XSetWMProtocols(nxagentDisplay, w, &deleteWMAtom, 1);
+  }
+
+  return w;
+}
+
+Bool nxagentMagicPixelZone(int x, int y)
+{
+  return (x >= nxagentOption(Width) - 1 && y < 1);
+}
+
+void nxagentSetScreenSaverTime(void)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetScreenSaverTime: ScreenSaverTime was [%lu], ScreenSaverInterval was [%lu].\n",
+                  ScreenSaverTime, ScreenSaverInterval);
+  #endif
+
+  /*
+   * More than one timeout could be used here,
+   * to make use of screen-saver handler not
+   * only for the timeout feature. In a case
+   * like this, the lower timeout have to be
+   * used as ScreenSaverTime.
+   */
+
+  if (nxagentAutoDisconnectTimeout > 0)
+  {
+    ScreenSaverTime = nxagentAutoDisconnectTimeout;
+  }
+
+  ScreenSaverInterval = ScreenSaverTime;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentSetScreenSaverTime: ScreenSaverTime now is [%lu], ScreenSaverInterval now is [%lu].\n",
+                  ScreenSaverTime, ScreenSaverInterval);
+  #endif
+}
+
+static Bool nxagentSaveScreen(ScreenPtr pScreen, int what)
+{
+  #ifdef TEST
+  fprintf(stderr, "nxagentSaveScreen: Called for screen at [%p] with parameter [%d].\n",
+              (void *) pScreen, what);
+
+  fprintf(stderr, "nxagentSaveScreen: SCREEN_SAVER_ON is [%d] SCREEN_SAVER_OFF is [%d] "
+              "SCREEN_SAVER_FORCER is [%d] SCREEN_SAVER_CYCLE is [%d].\n",
+                  SCREEN_SAVER_ON, SCREEN_SAVER_OFF, SCREEN_SAVER_FORCER,
+                      SCREEN_SAVER_CYCLE);
+  #endif
+
+  /*
+   * We need only to reset the timeouts
+   * in this case.
+   */
+
+  if (what == SCREEN_SAVER_OFF)
+  {
+    nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND;
+
+    return 1;
+  }
+
+  /*
+   * The lastDeviceEventTime is updated every time
+   * a device event is received, and it is used by
+   * WaitForSomething() to know when the SaveScreens()
+   * function should be called. This solution doesn't
+   * take care of a pointer button not released, so
+   * we have to handle this case by ourselves.
+   */
+
+/*
+FIXME: Do we need to check the key grab if the
+       autorepeat feature is disabled?
+*/
+  if (inputInfo.pointer -> button -> buttonsDown > 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSaveScreen: Ignoring timeout, there is a pointer button down.\n");
+    #endif
+
+    /*
+     * Returning 0 the SaveScreens() function
+     * (which calls this one) tries to build
+     * a screen-saver creating a new window.
+     * We don't want this, so we return 1 in
+     * any case.
+     */
+
+    return 1;
+  }
+
+  /*
+   * Handling the auto-disconnect feature.
+   * If there is any client attached and the persisten-
+   * ce is allowed then leave the session running, else
+   * terminate it. It should use something less brutal,
+   * though raising a signal should ensure that the code
+   * follows the usual execution path.
+   */
+
+  if (nxagentOption(Timeout) > 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSaveScreen: Auto-disconnect timeout was [%d].\n",
+                nxagentAutoDisconnectTimeout);
+    #endif
+
+    nxagentAutoDisconnectTimeout  -= ScreenSaverTime;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentSaveScreen: Auto-disconnect timeout is [%d].\n",
+                nxagentAutoDisconnectTimeout);
+    #endif
+
+    if (nxagentSessionState == SESSION_UP &&
+            nxagentAutoDisconnectTimeout <= 0)
+    {
+      nxagentAutoDisconnectTimeout = nxagentOption(Timeout) * MILLI_PER_SECOND;
+
+      if (nxagentClients == 0)
+      {
+        fprintf(stderr, "Info: Terminating session with no client running.\n");
+
+        raise(SIGTERM);
+      }
+      else if (nxagentOption(Persistent) == 0)
+      {
+        fprintf(stderr, "Info: Terminating session with persistence not allowed.\n");
+
+        raise(SIGTERM);
+      }
+      else
+      {
+        fprintf(stderr, "Info: Suspending session with %d clients running.\n",
+                    nxagentClients);
+
+        raise(SIGHUP);
+      }
+    }
+  }
+
+  return 1;
+}
+
+Bool nxagentCreateScreenResources(ScreenPtr pScreen)
+{
+  Bool ret;
+
+  CreatePixmapProcPtr savedCreatePixmap = pScreen->CreatePixmap;
+  ModifyPixmapHeaderProcPtr savedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
+
+  pScreen->CreatePixmap = fbCreatePixmap;
+  pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
+  ret = miCreateScreenResources(pScreen);
+
+  pScreen->CreatePixmap = savedCreatePixmap;
+  pScreen->ModifyPixmapHeader = savedModifyPixmapHeader;
+
+  return ret;
+}
+
+static Bool nxagentCursorOffScreen(ScreenPtr *pPtrScreen, int *x, int *y)
+{
+  return False;
+}
+
+static void nxagentCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+}
+
+static miPointerScreenFuncRec nxagentPointerCursorFuncs =
+{
+  nxagentCursorOffScreen,
+  nxagentCrossScreen,
+  miPointerWarpCursor
+};
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentInitViewportFrame(ScreenPtr pScreen, WindowPtr pRootWin)
+{
+  int error = Success;
+  VisualID visual = 0;
+  int i;
+  XID xid;
+
+  if (nxagentOption(Rootless))
+  {
+    return;
+  }
+
+  for (i = 0; i < pScreen -> numDepths; i++)
+  {
+    if (pScreen -> allowedDepths[i].depth == pRootWin -> drawable.depth)
+    {
+      visual = pScreen -> allowedDepths[i].vids[0];
+      break;
+    }
+  }
+
+  /*
+   * It is not necessary create the windows on the real X server. But this
+   * windows are not visible. Create them it is not a great effort, and avoids
+   * many errors.
+   *
+   *  nxagentScreenTrap = True;
+   */
+
+  xid = FakeClientID(serverClient -> index);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+  #endif
+
+  nxagentViewportFrameLeft = CreateWindow(xid, pRootWin, -NXAGENT_FRAME_WIDTH, 0, NXAGENT_FRAME_WIDTH,
+                                              pRootWin -> drawable.height,
+                                                  0, InputOutput, 0, NULL,
+                                                      pRootWin -> drawable.depth,
+                                                          serverClient, visual, &error);
+
+  AddResource(xid, RT_WINDOW, (pointer) nxagentViewportFrameLeft);
+
+  if (error != Success)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameLeft.\n");
+    #endif
+
+    error = Success;
+  }
+
+  xid = FakeClientID(serverClient -> index);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+  #endif
+
+  nxagentViewportFrameRight = CreateWindow(xid, pRootWin, pRootWin -> drawable.width, 0,
+                                               NXAGENT_FRAME_WIDTH,
+                                                   pRootWin -> drawable.height,
+                                                       0, InputOutput, 0, NULL,
+                                                           pRootWin -> drawable.depth,
+                                                               serverClient, visual,
+                                                                   &error);
+
+  AddResource(xid, RT_WINDOW, (pointer) nxagentViewportFrameRight);
+
+  if (error != Success)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameRight.\n");
+    #endif
+
+    error = Success;
+  }
+
+  xid = FakeClientID(serverClient -> index);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+  #endif
+
+  nxagentViewportFrameAbove = CreateWindow(xid, pRootWin, 0, -NXAGENT_FRAME_WIDTH,
+                                               pRootWin -> drawable.width,
+                                                   NXAGENT_FRAME_WIDTH, 0,
+                                                       InputOutput, 0, NULL,
+                                                           pRootWin -> drawable.depth,
+                                                               serverClient, visual,
+                                                                   &error);
+
+  AddResource(xid, RT_WINDOW, (pointer) nxagentViewportFrameAbove);
+
+  if (error != Success)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameAbove.\n");
+    #endif
+
+    error = Success;
+  }
+
+  xid = FakeClientID(serverClient -> index);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitViewportFrame: XID = [%lx]\n", xid);
+  #endif
+
+  nxagentViewportFrameBelow = CreateWindow(xid, pRootWin, 0,
+                                               pRootWin -> drawable.height,
+                                                   pRootWin -> drawable.width,
+                                                       NXAGENT_FRAME_WIDTH, 0,
+                                                           InputOutput, 0, NULL,
+                                                               pRootWin -> drawable.depth,
+                                                                   serverClient, visual, &error);
+
+  AddResource(xid, RT_WINDOW, (pointer) nxagentViewportFrameBelow);
+
+  if (error != Success)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentInitViewportFrame: Error creating nxagentViewportFrameBelow.\n");
+    #endif
+  }
+
+  nxagentViewportFrameLeft -> overrideRedirect = 1;
+  nxagentViewportFrameRight -> overrideRedirect = 1;
+  nxagentViewportFrameAbove -> overrideRedirect = 1;
+  nxagentViewportFrameBelow -> overrideRedirect = 1;
+
+  MapWindow(nxagentViewportFrameLeft, serverClient);
+  MapWindow(nxagentViewportFrameRight, serverClient);
+  MapWindow(nxagentViewportFrameAbove, serverClient);
+  MapWindow(nxagentViewportFrameBelow, serverClient);
+
+  /*
+   * nxagentScreenTrap = False;
+   */
+}
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+void nxagentPrintAgentGeometry(char *hdrMessage, char *prefix)
+{
+  #ifdef WARNING
+
+  if (prefix == NULL)
+  {
+    prefix = "";
+  }
+
+  if (hdrMessage)
+  {
+    fprintf(stderr, "--------------- %s -----------------.\n", hdrMessage);
+  }
+
+  fprintf(stderr, "%s Root window at offset (%d,%d) size (%d,%d).\n", prefix,
+              nxagentOption(RootX), nxagentOption(RootY),
+                  nxagentOption(RootWidth), nxagentOption(RootHeight));
+
+  fprintf(stderr, "%s Default window at offset (%d,%d) size (%d,%d) border size %d.\n", prefix,
+              nxagentOption(X), nxagentOption(Y), nxagentOption(Width), nxagentOption(Height),
+                  nxagentOption(BorderWidth));
+
+  fprintf(stderr, "%s Span between root window and default window is (%d,%d).\n", prefix,
+              nxagentOption(ViewportXSpan), nxagentOption(ViewportYSpan));
+
+  fprintf(stderr, "%s Default window in window mode has offset (%d,%d) and size (%d,%d).\n", prefix,
+              nxagentOption(SavedX), nxagentOption(SavedY), nxagentOption(SavedWidth), nxagentOption(SavedHeight));
+
+  fprintf(stderr, "%s Fullscreen is %s.\n", prefix,
+              nxagentOption(Fullscreen) ? "ON" : "OFF");
+
+  fprintf(stderr, "%s Desktop resize mode is %s.\n", prefix,
+              nxagentOption(DesktopResize) ? "ON" : "OFF");
+
+  fprintf(stderr, "%s Resize desktop at startup is %s.\n", prefix,
+              nxagentResizeDesktopAtStartup ? "ON" : "OFF");
+
+  #endif
+}
+
+static int nxagentColorOffset(unsigned long mask)
+{
+  int count;
+
+  for (count = 0; !(mask & 1) && count < 32; count++)
+  {
+    mask >>= 1;
+  }
+
+  return count;
+}
+
+Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
+                           int argc, char *argv[])
+{
+  VisualPtr visuals;
+  DepthPtr depths;
+  int numVisuals, numDepths;
+  int i, j, depthIndex;
+  unsigned long valuemask;
+  XSetWindowAttributes attributes;
+  XWindowAttributes gattributes;
+  XSizeHints sizeHints;
+  XWMHints wmHints;
+  Mask mask;
+  Bool resetAgentPosition = False;
+
+  VisualID defaultVisual;
+  int rootDepth;
+
+  pointer pFrameBufferBits;
+  int bitsPerPixel;
+  int sizeInBytes;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentOpenScreen: Called for screen index [%d].\n",
+              index);
+  #endif
+
+  if (nxagentRenderEnable && nxagentReconnectTrap == False)
+  {
+    PictureScreenPrivateIndex = -1;
+  }
+
+  nxagentDefaultScreen = pScreen;
+
+  nxagentQueryAtoms(pScreen);
+
+  #ifdef NXAGENT_ONSTART
+  nxagentWMStart = nxagentAtoms[3];  /* WM_NX_READY */
+  #endif
+
+  /*
+   * Forced geometry parameter
+   * to user geometry.
+   */
+
+  if (nxagentResizeDesktopAtStartup)
+  {
+    if (nxagentUserGeometry.flag & XValue)
+    {
+      nxagentChangeOption(X, nxagentUserGeometry.X);
+    }
+
+    if (nxagentUserGeometry.flag & YValue)
+    {
+      nxagentChangeOption(Y, nxagentUserGeometry.Y);
+    }
+
+    if (nxagentUserGeometry.flag & WidthValue)
+    {
+      nxagentChangeOption(Width, nxagentUserGeometry.Width);
+      nxagentChangeOption(RootWidth, nxagentUserGeometry.Width);
+
+      if (nxagentOption(SavedWidth) > nxagentUserGeometry.Width)
+      {
+        nxagentChangeOption(SavedWidth, nxagentUserGeometry.Width);
+      }
+    }
+
+    if (nxagentUserGeometry.flag & HeightValue)
+    {
+      nxagentChangeOption(Height, nxagentUserGeometry.Height);
+      nxagentChangeOption(RootHeight, nxagentUserGeometry.Height);
+
+      if (nxagentOption(SavedHeight) > nxagentUserGeometry.Height)
+      {
+        nxagentChangeOption(SavedHeight, nxagentUserGeometry.Height);
+      }
+    }
+  }
+
+  /*
+   * This is first time the
+   * screen is initialized.
+   * Filling the geometry parameter
+   * from user geometry.
+   */
+
+  if (nxagentReconnectTrap == False)
+  {
+    if (nxagentUserGeometry.flag & XValue)
+    {
+      nxagentChangeOption(X, nxagentUserGeometry.X);
+    }
+
+    if (nxagentUserGeometry.flag & YValue)
+    {
+      nxagentChangeOption(Y, nxagentUserGeometry.Y);
+    }
+
+    if (nxagentUserGeometry.flag & WidthValue)
+    {
+      nxagentChangeOption(RootWidth, nxagentUserGeometry.Width);
+    }
+
+    if (nxagentUserGeometry.flag & HeightValue)
+    {
+      nxagentChangeOption(RootHeight, nxagentUserGeometry.Height);
+    }
+  }
+  else if (nxagentWMIsRunning && !nxagentOption(Rootless) && !nxagentOption(Fullscreen))
+  {
+    /*
+     * At reconnection, try to estimate the shift due to WM reparenting.
+     */
+
+    if (nxagentOption(X) >= 6)
+    {
+      nxagentChangeOption(X, nxagentOption(X) - 6);
+    }
+
+    if (nxagentOption(Y) >= 25)
+    {
+      nxagentChangeOption(Y, nxagentOption(Y) - 25);
+    }
+  }
+
+  /*
+   * Determine the size of the root window.
+   * It is the maximum size of the screen
+   * if we are either in rootless or in
+   * fullscreen mode.
+   */
+
+  if (nxagentOption(Rootless) == False && nxagentWMIsRunning == False)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: Forcing fullscreen mode with no window manager running.\n");
+    #endif
+
+    nxagentChangeOption(Fullscreen, True);
+
+    if (nxagentOption(ClientOs) == ClientOsWinnt)
+    {
+      NXSetExposeParameters(nxagentDisplay, 0, 0, 0);
+    }
+  }
+
+  if (nxagentOption(Fullscreen) &&
+          nxagentWMIsRunning &&
+              nxagentReconnectTrap &&
+                  nxagentResizeDesktopAtStartup == False &&
+                      nxagentXServerGeometryChanged())
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: Forcing window mode with server geometry changed.\n");
+    #endif
+
+    nxagentChangeOption(Fullscreen, False);
+
+    resetAgentPosition = True;
+  }
+
+  if (nxagentOption(Fullscreen))
+  {
+    nxagentChangeOption(X, 0);
+    nxagentChangeOption(Y, 0);
+
+    nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+    nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+    nxagentChangeOption(BorderWidth, 0);
+
+    if (nxagentReconnectTrap == False || nxagentResizeDesktopAtStartup)
+    {
+      nxagentChangeOption(RootWidth, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+      nxagentChangeOption(RootHeight, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+      if (nxagentOption(RootWidth) > WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+      {
+        nxagentChangeOption(SavedWidth, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+      }
+      else
+      {
+        nxagentChangeOption(SavedWidth, nxagentOption(RootWidth));
+      }
+
+      if (nxagentOption(RootHeight) > HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+      {
+        nxagentChangeOption(SavedHeight, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+      }
+      else
+      {
+        nxagentChangeOption(SavedHeight, nxagentOption(RootHeight));
+      }
+    }
+
+    nxagentChangeOption(RootX, ((WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+                            nxagentOption(RootWidth)) / 2));
+    nxagentChangeOption(RootY, ((HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+                            nxagentOption(RootHeight)) / 2));
+  }
+  else
+  {
+    nxagentChangeOption(BorderWidth, 0);
+
+    if (nxagentReconnectTrap == False)
+    {
+      nxagentChangeOption(RootX, 0);
+      nxagentChangeOption(RootY, 0);
+
+      nxagentChangeOption(Width, nxagentOption(RootWidth));
+      nxagentChangeOption(Height, nxagentOption(RootHeight));
+    }
+
+    /*
+     * Be sure that the agent window won't be bigger
+     * than the root window.
+     */
+
+    if (nxagentOption(Width) > nxagentOption(RootWidth))
+    {
+      nxagentChangeOption(Width, nxagentOption(RootWidth));
+    }
+
+    if (nxagentOption(Height) > nxagentOption(RootHeight))
+    {
+      nxagentChangeOption(Height, nxagentOption(RootHeight));
+    }
+
+    /*
+     * Be sure that the agent window won't be bigger
+     * than the X server root window.
+     */
+
+    if (nxagentOption(Width) > WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+    {
+      nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+    }
+
+    if (nxagentOption(Height) > HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)))
+    {
+      nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 3 / 4);
+    }
+
+    /*
+     * Forcing the agent window geometry to be equal to
+     * the root window geometry the first time the
+     * screen is initialized if the geometry hasn't been
+     * esplicitly set in the option file and if
+     * the root window isn't bigger than the X server
+     * root window..
+     */
+
+    if (nxagentReconnectTrap == False)
+    {
+      if ((nxagentOption(RootWidth) < WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay))) &&
+              !(nxagentUserGeometry.flag & WidthValue))
+      {
+        nxagentChangeOption(Width, nxagentOption(RootWidth));
+      }
+
+      if ((nxagentOption(RootHeight) < HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))) &&
+              !(nxagentUserGeometry.flag & HeightValue))
+      {
+        nxagentChangeOption(Height, nxagentOption(RootHeight));
+      }
+    }
+
+    if (resetAgentPosition)
+    {
+      nxagentChangeOption(X, ((WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+                              nxagentOption(Width)) / 2));
+
+      nxagentChangeOption(Y, ((HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -
+                              nxagentOption(Height)) / 2));
+    }
+
+    nxagentChangeOption(SavedWidth, nxagentOption(RootWidth));
+    nxagentChangeOption(SavedHeight, nxagentOption(RootHeight));
+  }
+
+  if (nxagentOption(Rootless))
+  {
+    nxagentChangeOption(RootWidth, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+    nxagentChangeOption(RootHeight, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+  }
+
+  nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
+  nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+  nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+  nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+  if (nxagentReconnectTrap == 0)
+  {
+    if (nxagentOption(Persistent))
+    {
+      nxagentArgc = argc;
+      nxagentArgv = argv;
+    }
+
+    #ifdef NXAGENT_TIMESTAMP
+
+    {
+      extern unsigned long startTime;
+
+      fprintf(stderr, "Screen: going to open screen, time is [%d] milliseconds.\n",
+                  GetTimeInMillis() - startTime);
+    }
+
+    #endif
+
+    /*
+     * Initialize all our privates.
+     */
+
+    if (AllocateWindowPrivate(pScreen, nxagentWindowPrivateIndex, sizeof(nxagentPrivWindowRec)) == 0 ||
+            AllocateGCPrivate(pScreen, nxagentGCPrivateIndex, sizeof(nxagentPrivGC)) == 0 ||
+                AllocateClientPrivate(nxagentClientPrivateIndex, sizeof(PrivClientRec)) == 0 ||
+                    AllocatePixmapPrivate(pScreen, nxagentPixmapPrivateIndex, sizeof(nxagentPrivPixmapRec)) == 0)
+    {
+      return False;
+    }
+
+    /*
+     * Initialize the depths.
+     */
+
+    depths = (DepthPtr) xalloc(nxagentNumDepths * sizeof(DepthRec));
+
+    for (i = 0; i < nxagentNumDepths; i++)
+    {
+      depths[i].depth = nxagentDepths[i];
+      depths[i].numVids = 0;
+      depths[i].vids = (VisualID *) xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+    }
+
+    /*
+     * Initialize the visuals.
+     */
+
+    numVisuals = 0;
+    numDepths = nxagentNumDepths;
+
+    visuals = (VisualPtr) xalloc(nxagentNumVisuals * sizeof(VisualRec));
+
+    for (i = 0; i < nxagentNumVisuals; i++)
+    {
+      visuals[numVisuals].vid = FakeClientID(0);
+      visuals[numVisuals].class = nxagentVisuals[i].class;
+      visuals[numVisuals].bitsPerRGBValue = nxagentVisuals[i].bits_per_rgb;
+      visuals[numVisuals].ColormapEntries = nxagentVisuals[i].colormap_size;
+      visuals[numVisuals].nplanes = nxagentVisuals[i].depth;
+      visuals[numVisuals].redMask = nxagentVisuals[i].red_mask;
+      visuals[numVisuals].greenMask = nxagentVisuals[i].green_mask;
+      visuals[numVisuals].blueMask = nxagentVisuals[i].blue_mask;
+      visuals[numVisuals].offsetRed = nxagentColorOffset(nxagentVisuals[i].red_mask);
+      visuals[numVisuals].offsetGreen = nxagentColorOffset(nxagentVisuals[i].green_mask);
+      visuals[numVisuals].offsetBlue = nxagentColorOffset(nxagentVisuals[i].blue_mask);
+
+      /*
+       * Check for and remove the duplicates.
+       */
+
+      for (j = 0; j < numVisuals; j++)
+      {
+        if (visuals[numVisuals].class           == visuals[j].class           &&
+            visuals[numVisuals].bitsPerRGBValue == visuals[j].bitsPerRGBValue &&
+            visuals[numVisuals].ColormapEntries == visuals[j].ColormapEntries &&
+            visuals[numVisuals].nplanes         == visuals[j].nplanes         &&
+            visuals[numVisuals].redMask         == visuals[j].redMask         &&
+            visuals[numVisuals].greenMask       == visuals[j].greenMask       &&
+            visuals[numVisuals].blueMask        == visuals[j].blueMask        &&
+            visuals[numVisuals].offsetRed       == visuals[j].offsetRed       &&
+            visuals[numVisuals].offsetGreen     == visuals[j].offsetGreen     &&
+            visuals[numVisuals].offsetBlue      == visuals[j].offsetBlue)
+          break;
+      }
+
+      if (j < numVisuals)
+        continue;
+
+      depthIndex = UNDEFINED;
+
+      for (j = 0; j < numDepths; j++)
+      {
+        if (depths[j].depth == nxagentVisuals[i].depth)
+        {
+          depthIndex = j;
+          break;
+        }
+      }
+
+      if (depthIndex == UNDEFINED)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentOpenScreen: WARNING! Can't find a matching depth for visual depth [%d].\n",
+                nxagentVisuals[i].depth);
+        #endif
+
+        depthIndex = numDepths;
+
+        depths[depthIndex].depth = nxagentVisuals[i].depth;
+        depths[depthIndex].numVids = 0;
+        depths[depthIndex].vids = (VisualID *) xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+
+        numDepths++;
+      }
+
+      if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH)
+      {
+        FatalError("Visual table overflow");
+      }
+
+      depths[depthIndex].vids[depths[depthIndex].numVids] = visuals[numVisuals].vid;
+
+      depths[depthIndex].numVids++;
+
+      numVisuals++;
+    }
+
+    defaultVisual = visuals[nxagentDefaultVisualIndex].vid;
+    rootDepth = visuals[nxagentDefaultVisualIndex].nplanes;
+
+    nxagentInitAlphaVisual();
+
+    bitsPerPixel = nxagentBitsPerPixel(rootDepth);
+
+    if (bitsPerPixel == 1)
+    {
+      sizeInBytes = PixmapBytePad(nxagentOption(RootWidth), rootDepth) * nxagentOption(RootHeight);
+    }
+    else
+    {
+      sizeInBytes = PixmapBytePad(nxagentOption(RootWidth), rootDepth) * nxagentOption(RootHeight) * bitsPerPixel/8;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: Frame buffer allocated. rootDepth "
+                "[%d] bitsPerPixel [%d] sizeInBytes [%d]\n", rootDepth, bitsPerPixel, sizeInBytes);
+    #endif
+
+    pFrameBufferBits = (char *) Xalloc(sizeInBytes);
+
+    if (!pFrameBufferBits)
+    {
+      return FALSE;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: Before fbScreenInit numVisuals [%d] numDepths [%d] "
+              "rootDepth [%d] defaultVisual [%ld].\n", numVisuals, numDepths,
+                  rootDepth, defaultVisual);
+    #endif
+
+    if (monitorResolution < 1)
+    {
+      monitorResolution = NXAGENT_DEFAULT_DPI;
+    }
+
+    if (!fbScreenInit(pScreen, pFrameBufferBits, nxagentOption(RootWidth), nxagentOption(RootHeight),
+          monitorResolution, monitorResolution, PixmapBytePad(nxagentOption(RootWidth), rootDepth), bitsPerPixel))
+    {
+      return FALSE;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: After fbScreenInit numVisuals [%d] numDepths [%d] "
+              "rootDepth [%d] defaultVisual [%ld].\n", numVisuals, numDepths,
+                  rootDepth, defaultVisual);
+    #endif
+
+    /*
+     * Complete the initialization of the GLX
+     * extension. This will add the GLX visuals
+     * and will modify numVisuals and numDepths.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: Before GLX numVisuals [%d] numDepths [%d] "
+              "rootDepth [%d] defaultVisual [%ld].\n", numVisuals, numDepths,
+                  rootDepth, defaultVisual);
+    #endif
+
+    nxagentInitGlxExtension(&visuals, &depths, &numVisuals, &numDepths,
+                                &rootDepth, &defaultVisual);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: After GLX numVisuals [%d] numDepths [%d] "
+              "rootDepth [%d] defaultVisual [%ld].\n", numVisuals, numDepths,
+                  rootDepth, defaultVisual);
+    #endif
+
+    /*
+     * Replace the visuals and depths initialized
+     * by fbScreenInit with our own.
+     */
+
+    xfree(pScreen -> visuals);
+    xfree(pScreen -> allowedDepths);
+
+    pScreen -> visuals = visuals;
+    pScreen -> allowedDepths = depths;
+    pScreen -> numVisuals = numVisuals;
+    pScreen -> numDepths = numDepths;
+    pScreen -> rootVisual = defaultVisual;
+    pScreen -> rootDepth = rootDepth;
+
+    /*
+     * Complete the initialization of the RANDR
+     * extension.
+     */
+
+    nxagentInitRandRExtension(pScreen);
+
+    /*
+     * Set up the internal structures used for
+     * tracking the proxy resources associated
+     * to the unpack and split operations.
+     */
+
+    nxagentInitSplitResources();
+    nxagentInitUnpackResources();
+
+    /*
+     * Initializing the pixmaps that will serve as
+     * "placeholders" in lazy encoding. We need one 
+     * pixmap for each depth.
+     */
+
+    for (i = 0; i < numDepths; i++)
+    {
+      nxagentMarkPlaceholderNotLoaded(i);
+    }
+
+    #ifdef WATCH
+
+    fprintf(stderr, "nxagentOpenScreen: Watchpoint 7.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+N/A
+*/
+
+    sleep(30);
+
+    #endif
+
+    if (nxagentParentWindow != 0)
+    {
+      /*
+       * This would cause a GetWindowAttributes
+       * and a GetGeometry (asynchronous) reply.
+       */
+
+      XGetWindowAttributes(nxagentDisplay, nxagentParentWindow, &gattributes);
+
+      nxagentChangeOption(Width, gattributes.width);
+      nxagentChangeOption(Height, gattributes.height);
+    }
+
+    if (nxagentOption(Fullscreen))
+    {
+      attributes.override_redirect = True;
+
+      /*
+       * We need to disable the host's screensaver or
+       * it will otherwise grab the screen even if it
+       *  is under agent's control.
+       */
+
+      XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+    }
+
+    if (nxagentTrue24)
+    {
+      fbGetScreenPrivate(pScreen) -> win32bpp = visuals[nxagentDefaultVisualIndex].nplanes;
+      fbGetScreenPrivate(pScreen) -> pix32bpp = visuals[nxagentDefaultVisualIndex].nplanes;
+    }
+    else
+    {
+      fbGetScreenPrivate(pScreen) -> win32bpp = 32;
+      fbGetScreenPrivate(pScreen) -> pix32bpp = 32;
+    }
+
+    /*
+     * We call miScreenInit with NULL in place of the screen area if we
+     * don't want to initialize the frame buffer.
+     *
+     * if (!miScreenInit(pScreen, NULL, nxagentOption(RootWidth),
+     *              nxagentOption(RootHeight), 1, 1, nxagentOption(RootWidth),
+     *              visuals[nxagentDefaultVisualIndex].nplanes, / * Root depth. * / 
+     *              numDepths, depths,
+     *              visuals[nxagentDefaultVisualIndex].vid,* Root visual. * /
+     *              numVisuals, visuals))
+     *   return FALSE;
+     */
+
+    pScreen->defColormap = (Colormap) FakeClientID(0);
+    pScreen->minInstalledCmaps = MINCMAPS;
+    pScreen->maxInstalledCmaps = MAXCMAPS;
+
+    pScreen->whitePixel = nxagentWhitePixel;
+    pScreen->blackPixel = nxagentBlackPixel;
+    /* rgf */
+    /* GCperDepth */
+    /* PixmapPerDepth */
+    /* WindowPrivateLen */
+    /* WindowPrivateSizes */
+    /* totalWindowSize */
+    /* GCPrivateLen */
+    /* GCPrivateSizes */
+    /* totalGCSize */
+
+    /*
+     * Random screen procedures.
+     */
+
+    pScreen->CloseScreen = nxagentCloseScreen;
+    pScreen->QueryBestSize = nxagentQueryBestSize;
+    pScreen->SaveScreen = nxagentSaveScreen;
+    pScreen->GetImage = nxagentGetImage;
+    pScreen->GetSpans = nxagentGetSpans;
+    pScreen->PointerNonInterestBox = (void (*)()) 0;
+    pScreen->SourceValidate = (void (*)()) 0;
+
+    pScreen->CreateScreenResources = nxagentCreateScreenResources;
+
+    /*
+     * Window Procedures.
+     * 
+     * Note that the following functions are not
+     * replaced with nxagent counterparts:
+     *
+     * ValidateTreeProcPtr       ValidateTree;
+     * ClearToBackgroundProcPtr  ClearToBackground;
+     *
+     * Note also that the ConfigureWindow procedure
+     * has not a pointer in the screen structure.
+     */
+
+    pScreen->CreateWindow = nxagentCreateWindow;
+    pScreen->DestroyWindow = nxagentDestroyWindow;
+    pScreen->PositionWindow = nxagentPositionWindow;
+    pScreen->ChangeWindowAttributes = nxagentChangeWindowAttributes;
+    pScreen->RealizeWindow = nxagentRealizeWindow;
+    pScreen->UnrealizeWindow = nxagentUnrealizeWindow;
+    pScreen->PostValidateTree = nxagentPostValidateTree;
+    pScreen->WindowExposures = nxagentWindowExposures;
+    pScreen->PaintWindowBackground = nxagentPaintWindowBackground;
+    pScreen->PaintWindowBorder = nxagentPaintWindowBorder;
+    pScreen->CopyWindow = nxagentCopyWindow;
+    pScreen->ClipNotify = nxagentClipNotify;
+    pScreen->RestackWindow = nxagentRestackWindow;
+    pScreen->ReparentWindow = nxagentReparentWindow;
+
+    /*
+     * Pixmap procedures.
+     */
+
+    pScreen->CreatePixmap = nxagentCreatePixmap;
+    pScreen->DestroyPixmap = nxagentDestroyPixmap;
+
+    /*
+     * This is originally miModifyPixmapHeader()
+     * from miscrinit.c. It is used to recycle
+     * the scratch pixmap for this screen.
+     */
+
+    pScreen->ModifyPixmapHeader = nxagentModifyPixmapHeader;
+
+    /*
+     * Font procedures.
+     */
+
+    pScreen->RealizeFont = nxagentRealizeFont;
+    pScreen->UnrealizeFont = nxagentUnrealizeFont;
+
+    /*
+     * GC procedures.
+     */
+
+    pScreen->CreateGC = nxagentCreateGC;
+    pScreen->BitmapToRegion = nxagentPixmapToRegion;
+
+    /*
+     * Colormap procedures.
+     */
+
+    pScreen->CreateColormap = nxagentCreateColormap;
+    pScreen->DestroyColormap = nxagentDestroyColormap;
+    pScreen->InstallColormap = nxagentInstallColormap;
+    pScreen->UninstallColormap = nxagentUninstallColormap;
+    pScreen->ListInstalledColormaps = nxagentListInstalledColormaps;
+    pScreen->StoreColors = nxagentStoreColors;
+    pScreen->ResolveColor = nxagentResolveColor;
+
+    /*
+     * Backing store procedures.
+     */
+
+    pScreen->SaveDoomedAreas = (void (*)()) 0;
+    pScreen->RestoreAreas = (RegionPtr (*)()) 0;
+    pScreen->ExposeCopy = (void (*)()) 0;
+    pScreen->TranslateBackingStore = (RegionPtr (*)()) 0;
+    pScreen->ClearBackingStore = (RegionPtr (*)()) 0;
+    pScreen->DrawGuarantee = (void (*)()) 0;
+
+    if (enableBackingStore == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentOpenScreen: Going to initialize backing store.\n");
+      #endif
+
+      pScreen -> BackingStoreFuncs.SaveAreas = nxagentSaveAreas;
+      pScreen -> BackingStoreFuncs.RestoreAreas = nxagentRestoreAreas;
+      pScreen -> BackingStoreFuncs.SetClipmaskRgn = 0;
+      pScreen -> BackingStoreFuncs.GetImagePixmap = 0;
+      pScreen -> BackingStoreFuncs.GetSpansPixmap = 0;
+
+      miInitializeBackingStore(pScreen);
+    }
+
+    /*
+     * OS layer procedures.
+     */
+
+    pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
+    pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
+    pScreen->blockData = NULL;
+    pScreen->wakeupData = NULL;
+
+    #ifdef RENDER
+
+    /*
+     * Initialize picture support. This have to be
+     * placed here because miDCInitialize calls
+     * DamageSetup, that should wrap the picture
+     * screen functions. So PictureInit has to be
+     * called before.
+     */
+
+    if (nxagentRenderEnable && !nxagentReconnectTrap)
+    {
+      if (!nxagentPictureInit(pScreen, 0, 0))
+      {
+        nxagentRenderEnable = False;              
+
+        return FALSE;
+      }
+
+      if (nxagentAlphaEnabled)
+      {
+        fprintf(stderr, "Info: Using alpha channel in render extension.\n");
+      }
+    }
+
+    #endif /* RENDER */
+
+    /*
+     * From misprite.c: called from device-dependent screen
+     * initialization proc after all of the function pointers
+     * have been stored in the screen structure.
+     */
+
+    miDCInitialize(pScreen, &nxagentPointerCursorFuncs);
+
+    /*
+     * Cursor Procedures.
+     */
+
+    pScreen->ConstrainCursor = nxagentConstrainCursor;
+    pScreen->CursorLimits = nxagentCursorLimits;
+    pScreen->DisplayCursor = nxagentDisplayCursor;
+    pScreen->RealizeCursor = nxagentRealizeCursor;
+    pScreen->UnrealizeCursor = nxagentUnrealizeCursor;
+    pScreen->RecolorCursor = nxagentRecolorCursor;
+    pScreen->SetCursorPosition = nxagentSetCursorPosition;
+
+    #define POSITION_OFFSET (pScreen->myNum * (nxagentOption(Width) + \
+                               nxagentOption(Height)) / 32)
+  }
+
+  #ifdef TEST
+  nxagentPrintAgentGeometry(NULL, "nxagentOpenScreen:");
+  #endif
+
+  if (nxagentDoFullGeneration == 1 ||
+          nxagentReconnectTrap == 1)
+  {
+    valuemask = CWBackPixel | CWEventMask | CWColormap |
+                    (nxagentOption(Fullscreen) == 1 ? CWOverrideRedirect : 0);
+
+    attributes.background_pixel = nxagentBlackPixel;
+
+    nxagentGetDefaultEventMask((Mask*)&attributes.event_mask);
+
+    attributes.colormap = nxagentDefaultVisualColormap(nxagentDefaultVisual(pScreen));
+
+    if (nxagentOption(Fullscreen) == 1)
+    {
+      attributes.override_redirect = True;
+
+      if (nxagentReconnectTrap)
+      {
+        /*
+         * We need to disable the host's screensaver or
+         * it will otherwise grab the screen even if it
+         * is under agent's control.
+         */
+                                                                                                   
+        XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+      }
+    }
+
+    /*
+     * This would be used when running agent
+     * embedded into another X window.
+     */
+
+    if (nxagentParentWindow != 0)
+    {
+      nxagentDefaultWindows[pScreen->myNum] = nxagentParentWindow;
+
+      nxagentGetDefaultEventMask(&mask);
+
+      XSelectInput(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], mask);
+    }
+    else
+    {
+      /*
+       * Create any top-level window as a child of the
+       * real root of the remote display. See also the
+       * InitRootWindow() procedure and the function
+       * handling the splash screen.
+       */
+
+      if (nxagentOption(Rootless) == True)
+      {
+        nxagentDefaultWindows[pScreen->myNum] = DefaultRootWindow(nxagentDisplay);
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentOpenScreen: Using root window id [%ld].\n",
+                    nxagentDefaultWindows[pScreen->myNum]);
+        #endif
+      }
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentOpenScreen: Going to create new default window.\n");
+      #endif
+
+      nxagentDefaultWindows[pScreen->myNum] =
+          XCreateWindow(nxagentDisplay,
+                        DefaultRootWindow(nxagentDisplay),
+                        nxagentOption(X) + POSITION_OFFSET,
+                        nxagentOption(Y) + POSITION_OFFSET,
+                        nxagentOption(Width),
+                        nxagentOption(Height),
+                        nxagentOption(BorderWidth),
+                        pScreen->rootDepth,
+                        InputOutput,
+                        nxagentDefaultVisual(pScreen),
+                        valuemask, &attributes);
+
+       if (nxagentOption(Rootless) == 0)
+       {
+         valuemask = CWEventMask;
+         mask = PointerMotionMask;
+         attributes.event_mask = mask;
+
+         nxagentInputWindows[pScreen -> myNum] =
+             XCreateWindow(nxagentDisplay,
+                           nxagentDefaultWindows[pScreen -> myNum],
+                           0, 0,
+                           nxagentOption(Width),
+                           nxagentOption(Height),
+                           0, 0, InputOnly,
+                           nxagentDefaultVisual(pScreen),
+                           valuemask , &attributes);
+      }
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentOpenScreen: Created new default window with id [%ld].\n",
+                  nxagentDefaultWindows[pScreen->myNum]);
+      #endif
+
+      if (nxagentOption(Fullscreen))
+      {
+        nxagentFullscreenWindow = nxagentDefaultWindows[pScreen->myNum];
+      }
+
+      if (nxagentIpaq)
+      {
+        XWindowChanges ch;
+        unsigned int ch_mask;
+
+        ch.stack_mode = Below;
+        ch_mask = CWStackMode;
+
+        XConfigureWindow(nxagentDisplay, nxagentFullscreenWindow, ch_mask, &ch);
+      }
+    }
+
+    if (nxagentOption(Fullscreen))
+    {
+      /*
+       * FIXME: Do we still need to set this property?
+       */
+
+      if (nxagentAtoms[8] != 0)
+      {
+        XChangeProperty(nxagentDisplay,
+                        nxagentDefaultWindows[pScreen->myNum],
+                        nxagentAtoms[8], /* NX_AGENT_SIGNATURE */
+                        XA_STRING,
+                        8, 
+                        PropModeReplace, 
+                        (unsigned char*) "X-AGENT",
+                        strlen("X-AGENT"));
+      }
+
+      nxagentGetDefaultEventMask(&mask);
+
+      XSelectInput(nxagentDisplay, nxagentFullscreenWindow, mask);
+    }
+
+    sizeHints.flags = PPosition | PMinSize | PMaxSize;
+    sizeHints.x = nxagentOption(X) + POSITION_OFFSET;
+    sizeHints.y = nxagentOption(Y) + POSITION_OFFSET;
+    sizeHints.min_width = MIN_NXAGENT_WIDTH;
+    sizeHints.min_height = MIN_NXAGENT_HEIGHT;
+
+    sizeHints.width = nxagentOption(RootWidth);
+    sizeHints.height = nxagentOption(RootHeight);
+
+    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;
+
+    XSetStandardProperties(nxagentDisplay,
+                           nxagentDefaultWindows[pScreen->myNum],
+                           nxagentWindowName,
+                           nxagentWindowName,
+                           nxagentIconPixmap,
+                           argv, argc, &sizeHints);
+
+    wmHints.icon_pixmap = nxagentIconPixmap;
+
+    if (useXpmIcon)
+    {
+      wmHints.icon_mask = nxagentIconShape;
+      wmHints.flags = IconPixmapHint | IconMaskHint;
+    }
+    else
+    {
+      wmHints.flags = IconPixmapHint;
+    }
+
+    XSetWMHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &wmHints);
+
+    /*
+     * Clear the window but let it unmapped. We'll map it
+     * at the time the we'll initialize our screen root
+     * and only if we are not running in rootless mode.
+     */
+
+    XClearWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
+
+    if (nxagentOption(Fullscreen))
+    {
+      valuemask = CWBackPixmap | CWColormap | CWOverrideRedirect;
+    }
+    else
+    {
+      valuemask = CWBackPixmap | CWColormap;
+    }
+
+    attributes.background_pixmap = nxagentScreenSaverPixmap;
+    attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
+
+    if (nxagentOption(Fullscreen))
+    {
+      attributes.override_redirect = False;
+      if (nxagentReconnectTrap)
+      {
+        XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, True, GrabModeAsync,
+                      GrabModeAsync, CurrentTime);
+      }
+    }
+
+    if (nxagentOption(Fullscreen))
+    {
+      nxagentIconWindow = nxagentCreateIconWindow();
+    }
+    else
+    {
+      nxagentIconWindow = 0;
+    }
+
+    /*
+     * When we don't have window manager we grab keyboard
+     * to let nxagent get keyboard events.
+     */
+
+    if (!nxagentWMIsRunning && !nxagentOption(Fullscreen))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentOpenScreen: No window manager, we call XGrabKeyboard.\n");
+      #endif
+
+      XGrabKeyboard(nxagentDisplay, RootWindow (nxagentDisplay, 0), True, GrabModeAsync,
+                    GrabModeAsync, CurrentTime);
+    }
+  }
+
+  if (!nxagentCreateDefaultColormap(pScreen))
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentOpenScreen: Failed to create default colormap for screen.\n");
+    #endif
+
+    return False;
+  }
+
+  /*
+   * The purpose of this check is to verify if there
+   * is a window manager running. Unfortunately due
+   * to the way we manage the intern atoms call, the
+   * atom will always exist.
+   */
+
+  if (nxagentWMIsRunning)
+  {
+    XlibAtom deleteWMatom = nxagentAtoms[2];  /* WM_DELETE_WINDOW */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentOpenScreen: Found WM, delete window atom [%ld].\n",
+                deleteWMatom);
+    #endif
+
+    if (nxagentOption(Rootless) == False)
+    {
+      /*
+       * Set the WM_DELETE_WINDOW protocol for the main agent
+       * window and, if we are in fullscreen mode, include the
+       * icon window.
+       */
+
+      XSetWMProtocols(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &deleteWMatom, 1);
+
+      /*
+      if (nxagentOption(Fullscreen))
+      {
+        XSetWMProtocols(nxagentDisplay, nxagentIconWindow, &deleteWMatom, 1);
+      }
+      */
+    }
+    else
+    {
+      /*
+       * We need to register the ICCCM WM_DELETE_WINDOW
+       * protocol for any top-level window or the agent
+       * will be killed if any window is closed.
+       */
+
+      XSetWMProtocols(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &deleteWMatom, 1);
+
+      #ifdef TEST
+      fprintf(stderr, "Warning: Not setting the WM_DELETE_WINDOW protocol.\n");
+      #endif
+    }
+  }
+  else
+  {
+    /*
+     * We should always enable the configuration of the
+     * remote X server's devices if we are running full-
+     * screen and there is no WM running.
+     */
+
+    if (nxagentOption(Fullscreen))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentOpenScreen: WARNING! Forcing propagation of device control changes.\n");
+      #endif
+
+      nxagentChangeOption(DeviceControl, True);
+    }
+  }
+
+  /*
+   * Inform the user whether the agent's clients will
+   * be able to change the real X server's keyboard
+   * and pointer settings.
+   */
+
+  if (nxagentOption(DeviceControl) == False)
+  {
+    fprintf(stderr, "Info: Not using local device configuration changes.\n");
+  }
+  else
+  {
+    fprintf(stderr, "Info: Using local device configuration changes.\n");
+  }
+
+  #ifdef RENDER
+
+  /*
+   * if (nxagentRenderEnable && !nxagentReconnectTrap)
+   * {
+   *   if (!nxagentPictureInit(pScreen, 0, 0))
+   *   {
+   *     nxagentRenderEnable = False;
+   *
+   *     return FALSE;
+   *   }
+   *
+   *   if (nxagentAlphaEnabled)
+   *   {
+   *     fprintf(stderr, "Info: Using alpha channel in render extension.\n");
+   *   }
+   * }
+   */
+
+  #endif /* RENDER */
+
+  /*
+   * Check if the composite extension is
+   * supported on the remote display and
+   * prepare the agent for its use.
+   */
+
+  nxagentCompositeExtensionInit();
+
+
+  #ifdef NXAGENT_TIMESTAMP
+
+  {
+    extern unsigned long startTime;
+
+    fprintf(stderr, "Screen: open screen finished, time is [%d] milliseconds.\n",
+                GetTimeInMillis() - startTime);
+  }
+
+  #endif
+
+  #ifdef WATCH
+
+  fprintf(stderr, "nxagentOpenScreen: Watchpoint 8.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#1   U  2	1	5344 bits (1 KB) ->	2344 bits (0 KB) ->	2672/1 -> 1172/1	= 2.280:1
+#16     11		2816 bits (0 KB) ->	197 bits (0 KB) ->	256/1 -> 18/1	= 14.294:1
+#91     1		16640 bits (2 KB) ->	12314 bits (2 KB) ->	16640/1 -> 12314/1	= 1.351:1
+#98     2		512 bits (0 KB) ->	57 bits (0 KB) ->	256/1 -> 28/1	= 8.982:1
+*/
+
+  sleep(30);
+
+  #endif
+
+  return True;
+}
+
+Bool nxagentCloseScreen(int index, ScreenPtr pScreen)
+{
+  int i;
+
+  for (i = 0; i < pScreen->numDepths; i++)
+  {
+    xfree(pScreen->allowedDepths[i].vids);
+  }
+
+  /*
+   * Free the frame buffer.
+   */
+
+  xfree(((PixmapPtr)pScreen -> devPrivate) -> devPrivate.ptr);
+
+  xfree(pScreen->allowedDepths);
+  xfree(pScreen->visuals);
+  xfree(pScreen->devPrivate);
+
+  /*
+   * Reset the geometry and alpha information
+   * used by proxy to unpack the packed images.
+   */
+
+  nxagentResetVisualCache();
+  nxagentResetAlphaCache();
+  nxagentReleaseAllSplits();
+
+  /*
+   * The assumption is that all X resources will be
+   * destroyed upon closing the display connection.
+   * There is no need to generate extra protocol.
+   */
+
+  return True;
+}
+
+Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
+                             int mmWidth, int mmHeight)
+{
+  BoxRec box;
+  XSizeHints sizeHints;
+  PixmapPtr pPixmap;
+  char *fbBits;
+  
+  int oldWidth;
+  int oldHeight;
+  int oldMmWidth;
+  int oldMmHeight;
+
+  WindowPtr pWin;
+  RegionPtr pRootWinSize;
+
+  #ifdef TEST
+  nxagentPrintAgentGeometry("Before Resize Screen", "nxagentResizeScreen:");
+  #endif
+  
+  /*
+   * Change screen properties.
+   */
+
+  oldWidth = pScreen -> width;
+  oldHeight = pScreen -> height;
+  oldMmWidth = pScreen -> mmWidth;
+  oldMmHeight = pScreen -> mmHeight;
+
+  pScreen -> width = width;
+  pScreen -> height = height;
+
+  /*
+   * Compute screen dimensions if they aren't given.
+   */
+
+  if (mmWidth == 0)
+  {
+    mmWidth  = (width * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+    if (mmWidth < 1)
+    {
+      mmWidth = 1;
+    }
+  }
+
+  if (mmHeight == 0)
+  {
+    mmHeight = (height * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+    if (mmHeight < 1)
+    {
+      mmHeight = 1;
+    }
+  }
+
+  pScreen -> mmWidth = mmWidth;
+  pScreen -> mmHeight = mmHeight;
+
+  pPixmap = fbGetScreenPixmap(pScreen);
+
+  if ((fbBits = realloc(pPixmap -> devPrivate.ptr, PixmapBytePad(width, pScreen->rootDepth) *
+                            height * BitsPerPixel(pScreen->rootDepth) / 8)) == NULL)
+  {
+    pScreen -> width = oldWidth;
+    pScreen -> height = oldHeight;
+    pScreen -> mmWidth = oldMmWidth;
+    pScreen -> mmHeight = oldMmHeight;
+
+    goto nxagentResizeScreenError;
+  }
+
+  if (!miModifyPixmapHeader(pPixmap, width, height,
+                                pScreen->rootDepth, BitsPerPixel(pScreen->rootDepth),
+                                    PixmapBytePad(width,
+                                        pScreen->rootDepth), fbBits))
+  {
+/*
+FIXME: We should try to restore the previously
+       reallocated frame buffer pixmap.
+*/
+
+    pScreen -> width = oldWidth;
+    pScreen -> height = oldHeight;
+    pScreen -> mmWidth = oldMmWidth;
+    pScreen -> mmHeight = oldMmHeight;
+
+    goto nxagentResizeScreenError;
+  }
+
+  nxagentChangeOption(RootWidth, width);
+  nxagentChangeOption(RootHeight, height);
+
+  if (nxagentOption(Fullscreen))
+  {
+    nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+    nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+    nxagentChangeOption(RootX, (WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
+                            - nxagentOption(RootWidth)) / 2);
+    nxagentChangeOption(RootY,  (HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
+                            - nxagentOption(RootHeight)) / 2);
+  }
+  else
+  {
+    nxagentChangeOption(RootX, 0);
+    nxagentChangeOption(RootY, 0);
+  }
+
+  nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+  nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+  /*
+   * Change agent window size and size hints.
+   */
+
+  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);
+
+  if (nxagentOption(Fullscreen))
+  {
+    XResizeWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+    XResizeWindow(nxagentDisplay, nxagentInputWindows[pScreen -> myNum],
+                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+  }
+  else
+  {
+    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.
+   */
+
+  box.x1 = 0;
+  box.y1 = 0;
+  box.x2 = width;
+  box.y2 = height;
+
+  WindowTable[pScreen -> myNum] -> drawable.width = width;
+  WindowTable[pScreen -> myNum] -> drawable.height = height;
+  WindowTable[pScreen -> myNum] -> drawable.x = 0;
+  WindowTable[pScreen -> myNum] -> drawable.y = 0;
+
+  REGION_INIT(pScreen, &WindowTable[pScreen -> myNum] -> borderSize, &box, 1);
+  REGION_INIT(pScreen, &WindowTable[pScreen -> myNum] -> winSize, &box, 1);
+  REGION_INIT(pScreen, &WindowTable[pScreen -> myNum] -> clipList, &box, 1);
+  REGION_INIT(pScreen, &WindowTable[pScreen -> myNum] -> borderClip, &box, 1);
+
+  (*pScreen -> PositionWindow)(WindowTable[pScreen -> myNum], 0, 0);
+
+  pRootWinSize = &WindowTable[pScreen -> myNum] -> winSize;
+
+  /*
+   * Force a fictitious resize of all the top
+   * level windows, in order to trigger the
+   * window tree validation.
+   */
+
+  if (nxagentOption(Rootless) == 0)
+  {
+    for (pWin = WindowTable[pScreen -> myNum] -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
+    {
+
+      (*pWin -> drawable.pScreen -> ResizeWindow)(pWin, pWin -> drawable.x,
+                                                      pWin -> drawable.y,
+                                                          pWin -> drawable.width,
+                                                              pWin -> drawable.height,
+                                                                  pWin -> nextSib);
+
+    }
+  }
+
+  XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[0]),
+                  nxagentOption(RootX), nxagentOption(RootY));
+
+  nxagentMoveViewport(pScreen, 0, 0);
+
+  #ifdef TEST
+  nxagentPrintAgentGeometry("After Resize Screen", "nxagentResizeScreen:");
+  #endif
+
+  fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d].\n",
+              pScreen -> myNum, width, height);
+
+  return 1;
+
+nxagentResizeScreenError:
+
+  return 0;
+}
+
+void nxagentShadowSetRatio(float floatXRatio, float floatYRatio)
+{
+  int intXRatio;
+  int intYRatio;
+
+  if (floatXRatio == 0)
+  {
+    floatXRatio = 1.0;
+  }
+
+  if (floatYRatio == 0)
+  {
+    floatYRatio = 1.0;
+  }
+
+  intXRatio = floatXRatio * (1 << PRECISION);
+  intYRatio = floatYRatio * (1 << PRECISION);
+
+  nxagentChangeOption(FloatXRatio, floatXRatio);
+  nxagentChangeOption(FloatYRatio, floatYRatio);
+
+  nxagentChangeOption(XRatio, intXRatio);
+  nxagentChangeOption(YRatio, intYRatio);
+
+  #ifdef TEST
+  fprintf(stderr, "Info: Using X ratio [%f] Y ratio [%f].\n",
+              nxagentOption(FloatXRatio), nxagentOption(FloatYRatio));
+  #endif
+}
+
+void nxagentShadowSetWindowsSize(void)
+{
+  XResizeWindow(nxagentDisplay, nxagentDefaultWindows[0],
+                    nxagentOption(Width), nxagentOption(Height));
+
+  XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0, 
+                        nxagentOption(Width), nxagentOption(Height));
+}
+
+void nxagentShadowSetWindowOptions(void)
+{
+  nxagentChangeOption(RootWidth,  nxagentScale(nxagentShadowWidth,  nxagentOption(XRatio)));
+  nxagentChangeOption(RootHeight, nxagentScale(nxagentShadowHeight, nxagentOption(YRatio)));
+
+  nxagentChangeOption(SavedRootWidth,  nxagentOption(RootWidth));
+  nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+  nxagentChangeOption(RootX, (nxagentOption(Width)  - nxagentOption(RootWidth))  >> 1);
+  nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) >> 1);
+}
+
+int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
+{
+  int i;
+  char *layout = NULL;
+  extern char *nxagentKeyboard;
+  XlibGC gc;
+  XGCValues value;
+
+  #ifndef __CYGWIN32__
+
+  Atom nxagentShadowAtom;
+
+  int fd;
+
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "Info: Init shadow session. nxagentDisplayName [%s] nxagentDisplay "
+              "[%p] nxagentShadowDisplayName [%s].\n", nxagentDisplayName,
+                  (void *) nxagentDisplay, nxagentShadowDisplayName);
+  #endif
+
+  if (nxagentKeyboard != NULL)
+  {
+    for (i = 0; nxagentKeyboard[i] != '/' && nxagentKeyboard[i] != 0; i++);
+
+    if(nxagentKeyboard[i] == 0 || nxagentKeyboard[i + 1] == 0 || i == 0)
+    {
+      #ifdef WARNING
+      fprintf(stderr,"Warning: Wrong keyboard type: %s.\n", nxagentKeyboard);
+      #endif
+    }
+    else
+    {
+      layout = malloc(strlen(&nxagentKeyboard[i + 1]) + 1);
+
+      strcpy(layout, &nxagentKeyboard[i + 1]);
+    }
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentShadowInit: Setting the master uid [%d].\n", nxagentShadowUid);
+  #endif
+
+#if !defined (__CYGWIN32__) && !defined (WIN32)
+
+  if (nxagentShadowUid != -1)
+  {
+    NXShadowSetDisplayUid(nxagentShadowUid);
+  }
+
+  if (nxagentOption(UseDamage) == 0)
+  {
+    NXShadowDisableDamage();
+  }
+
+#endif
+
+  if (NXShadowCreate(nxagentDisplay, layout, nxagentShadowDisplayName,
+                         (void *) &nxagentShadowDisplay) != 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowInit: Failed to initialize shadow display [%s].\n", nxagentShadowDisplayName);
+    #endif
+
+    return -1;
+  }
+
+  /*
+   * The shadow nxagent sets the _NX_SHADOW
+   * property on the master X server root
+   * window in order to notify its presence.
+   */
+
+  #ifndef __CYGWIN__
+
+  nxagentShadowAtom = XInternAtom(nxagentShadowDisplay, "_NX_SHADOW", False);
+
+  XChangeProperty(nxagentShadowDisplay, DefaultRootWindow(nxagentShadowDisplay),
+                      nxagentShadowAtom, XA_STRING, 8, PropModeReplace, NULL, 0);
+  #endif
+
+  if (NXShadowAddUpdaterDisplay(nxagentDisplay, &nxagentShadowWidth,
+                                    &nxagentShadowHeight, &nxagentMasterDepth) == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowInit: Failed to add display [%s].\n",
+                nxagentDisplayName);
+    #endif
+
+    return -1;
+  }
+
+  #ifndef __CYGWIN32__
+
+  if (nxagentOption(Fullscreen) == 1)
+  {
+    nxagentShadowSetRatio(WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 1.0 / nxagentShadowWidth,
+                              HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) * 1.0 / nxagentShadowHeight);
+  }
+  else if (nxagentUserGeometry.flag != 0)
+  {
+    nxagentShadowSetRatio(nxagentOption(RootWidth) * 1.0 / nxagentShadowWidth,
+                              nxagentOption(RootHeight) * 1.0 / nxagentShadowHeight);
+  }
+
+  if (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -> class != TrueColor ||
+          DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentShadowDisplay)) -> class != TrueColor)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowInit: PANIC! The visual class is not TrueColor.\n");
+    #endif
+
+    return -1;
+  }
+
+  #endif
+
+  nxagentShadowDepth = pScreen -> rootDepth;
+
+  switch (nxagentMasterDepth)
+  {
+    case 32:
+    case 24:
+    {
+      if (nxagentShadowDepth == 16)
+      {
+        nxagentCheckDepth = 1;
+      }
+      else if (nxagentShadowDepth == 8)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentShadowInit: PANIC! The target depth is 8 bit.\n");
+        #endif
+
+        return -1;
+      }
+
+      nxagentBppMaster = 4;
+
+      break;
+    }
+    case 16:
+    {
+      if (nxagentShadowDepth > 16)
+      {
+        nxagentCheckDepth = 1;
+      }
+      else if (nxagentShadowDepth == 8)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentShadowInit: PANIC! The target depth is 8 bit.\n");
+        #endif
+
+        return -1;
+      }
+
+      nxagentBppMaster = 2;
+
+      break;
+    }
+    case 8:
+    {
+      if (nxagentShadowDepth != 8)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentShadowInit: PANIC! The target depth is 8 bit.\n");
+        #endif
+
+        return -1;
+      }
+
+      nxagentBppMaster = 1;
+
+      break;
+    }
+    default:
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentShadowInit: PANIC! The depth is not 32, 24, 16 or 8 bit.\n");
+      #endif
+
+      return -1;
+    }
+  }
+
+  if (nxagentShadowDepth >= 24)
+  {
+    nxagentBppShadow = 4;
+  }
+  else if (nxagentShadowDepth == 16)
+  {
+    nxagentBppShadow = 2;
+  }
+  else if (nxagentShadowDepth == 8)
+  {
+    nxagentBppShadow = 1;
+  }
+
+#if !defined(__CYGWIN__)
+
+  imageByteOrder = nxagentShadowDisplay -> byte_order;
+
+  fd = XConnectionNumber(nxagentShadowDisplay);
+
+  nxagentShadowXConnectionNumber = fd;
+
+#endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentAddXConnection: Adding the X connection [%d] "
+              "to the device set.\n", fd);
+  #endif
+
+  AddEnabledDevice(nxagentShadowXConnectionNumber);
+
+  accessPixmapID = FakeClientID(serverClient -> index);
+
+  AddResource(accessPixmapID, RT_PIXMAP, (pointer)nxagentShadowPixmapPtr);
+
+  accessWindowID = FakeClientID(serverClient -> index);
+
+  AddResource(accessWindowID, RT_WINDOW, (pointer)nxagentShadowWindowPtr);
+
+  nxagentResizeScreen(pScreen, nxagentShadowWidth, nxagentShadowHeight, pScreen -> mmWidth, pScreen -> mmHeight);
+
+  nxagentShadowCreateMainWindow(pScreen, pWin, nxagentShadowWidth, nxagentShadowHeight);
+
+  nxagentShadowSetWindowsSize();
+
+  nxagentSetWMNormalHints(0);
+
+  XMapWindow(nxagentDisplay, nxagentDefaultWindows[0]);
+
+  /*
+   * Clean up the main window.
+   */
+
+  value.foreground = 0x00000000;
+  value.background = 0x00000000;
+  value.plane_mask = 0xffffffff;
+  value.fill_style = FillSolid;
+
+  gc = XCreateGC(nxagentDisplay, nxagentPixmap(nxagentShadowPixmapPtr), GCBackground |
+           GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+  XFillRectangle(nxagentDisplay, nxagentPixmap(nxagentShadowPixmapPtr), gc, 0, 0,
+                     nxagentShadowWidth, nxagentShadowHeight);
+
+  XFreeGC(nxagentDisplay, gc);
+
+  REGION_INIT(pScreen, &nxagentShadowUpdateRegion, (BoxRec*)NULL, 1);
+
+  return 0;
+}
+
+int nxagentShadowCreateMainWindow(ScreenPtr pScreen, WindowPtr pWin, int width, int height)
+{
+  XWindowChanges changes;
+  Mask mask,maskb;
+  XID values[4], *vlist;
+  int error;
+  XID xid;
+
+  nxagentShadowWidth = width;
+  nxagentShadowHeight = height;
+
+  NXShadowUpdateBuffer((void *)&nxagentShadowBuffer);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentShadowCreateMainWindow: Update frame buffer [%p].\n", nxagentShadowBuffer);
+  #endif
+
+  nxagentShadowSetWindowOptions();
+
+  if (nxagentShadowPixmapPtr != NULL)
+  {
+    nxagentDestroyPixmap(nxagentShadowPixmapPtr);
+  }
+
+  if (nxagentShadowWindowPtr != NULL)
+  {
+    DeleteWindow(nxagentShadowWindowPtr, accessWindowID);
+  }
+
+  nxagentShadowPixmapPtr = nxagentCreatePixmap(pScreen, nxagentShadowWidth, nxagentShadowHeight, nxagentShadowDepth);
+
+  if (nxagentShadowPixmapPtr)
+  {
+    ChangeResourceValue(accessPixmapID, RT_PIXMAP, (pointer) nxagentShadowPixmapPtr);
+    nxagentShadowPixmapPtr -> drawable.id = accessPixmapID;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowCreateMainWindow: nxagentShadowPixmapPtr [%p] PixmapM -> drawable.id [%lu].\n",
+                (void *)nxagentShadowPixmapPtr, nxagentShadowPixmapPtr -> drawable.id);
+    fprintf(stderr, "nxagentShadowCreateMainWindow: Create pixmap with width [%d] height [%d] depth [%d].\n",
+                nxagentShadowWidth, nxagentShadowHeight, (int)nxagentShadowDepth);
+    #endif
+  }
+  else
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentShadowCreateMainWindow: PANIC! Failed to create pixmap with width [%d] height [%d] depth [%d].\n",
+                nxagentShadowWidth, nxagentShadowHeight, (int)nxagentShadowDepth);
+    #endif
+  }
+
+  XFreePixmap(nxagentDisplay, nxagentPixmap(nxagentVirtualPixmap(nxagentShadowPixmapPtr)));
+
+  xid = XCreatePixmap(nxagentDisplay, nxagentDefaultWindows[0],
+            nxagentScale(nxagentShadowWidth, nxagentOption(XRatio)),
+                nxagentScale(nxagentShadowHeight, nxagentOption(YRatio)), nxagentShadowDepth);
+
+  nxagentPixmap(nxagentVirtualPixmap(nxagentShadowPixmapPtr)) = xid;
+
+  nxagentPixmap(nxagentRealPixmap(nxagentShadowPixmapPtr)) = xid;
+
+  if (nxagentShadowGCPtr != NULL)
+  {
+    FreeScratchGC(nxagentShadowGCPtr);
+  }
+/*
+ * FIXME: Should use CreateGC.
+ */
+  nxagentShadowGCPtr = GetScratchGC(nxagentShadowPixmapPtr -> drawable.depth, nxagentShadowPixmapPtr -> drawable.pScreen);
+
+  if (nxagentShadowGCPtr)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowCreateMainWindow: Created GC with pGC[%p]\n", nxagentShadowGCPtr);
+    #endif
+    ValidateGC((DrawablePtr)nxagentShadowPixmapPtr, nxagentShadowGCPtr);
+  }
+  else
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentShadowCreateMainWindow: PANIC! Failed to create GC.");
+    #endif
+  }
+
+  mask = CWBackPixmap | CWEventMask | CWCursor;
+
+  nxagentGetDefaultEventMask(&maskb);
+  maskb |= ResizeRedirectMask | ExposureMask;
+
+  vlist = values;
+  *vlist++ = (XID)nxagentShadowPixmapPtr -> drawable.id;
+  *vlist++ = (XID)maskb;
+
+  *vlist = (XID)None;
+
+  nxagentShadowWindowPtr = CreateWindow(accessWindowID, pWin, 0, 0, nxagentShadowWidth,
+                                            nxagentShadowHeight, 0, InputOutput, mask, (XID *)values,
+                                                nxagentShadowDepth, serverClient, CopyFromParent, &error);
+
+  mask = CWWidth | CWHeight;
+  changes.width = nxagentScale(nxagentShadowWidth, nxagentOption(XRatio));
+  changes.height = nxagentScale(nxagentShadowHeight, nxagentOption(YRatio));
+
+  XConfigureWindow(nxagentDisplay, nxagentWindow(nxagentShadowWindowPtr), mask, &changes);
+
+  nxagentMoveViewport(pScreen, 0, 0);
+
+  if (nxagentShadowWindowPtr && !error)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowCreateMainWindow: Create window with nxagentShadowWindowPtr [%p]"
+                "nxagentShadowWindowPtr -> drawable.id [%lu].\n", (void *) nxagentShadowWindowPtr,
+                     nxagentShadowWindowPtr -> drawable.id);
+
+    fprintf(stderr, "nxagentShadowCreateMainWindow: parent nxagentShadowWindowPtr [%p] parent -> drawable.id [%lu].\n",
+                (void *)nxagentShadowWindowPtr->parent, nxagentShadowWindowPtr -> parent -> drawable.id);
+
+    #endif
+
+    ChangeResourceValue(accessWindowID, RT_WINDOW, (pointer) nxagentShadowWindowPtr);
+  }
+  else
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentShadowCreateMainWindow: PANIC! Failed to create window.\n");
+    #endif
+  }
+
+  XMapWindow(nxagentDisplay, nxagentWindow(nxagentShadowWindowPtr));
+  MapWindow(nxagentShadowWindowPtr, serverClient);
+
+  mask = CWX | CWY | CWWidth | CWHeight;
+  changes.x = nxagentOption(RootX);
+  changes.y = nxagentOption(RootY);
+  changes.width = nxagentScale(nxagentShadowWidth, nxagentOption(XRatio));
+  changes.height = nxagentScale(nxagentShadowHeight, nxagentOption(YRatio));
+  XConfigureWindow(nxagentDisplay, nxagentWindow(pWin), mask, &changes);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentShadowCreateMainWindow: Completed mapping of Access window.\n");
+  #endif
+
+  return 0;
+}
+
+int nxagentShadowSendUpdates(int *suspended)
+{
+  *suspended = 0;
+
+  if (REGION_NIL(&nxagentShadowUpdateRegion) == 1)
+  {
+    return 0;
+  }
+
+  nxagentMarkCorruptedRegion((DrawablePtr)nxagentShadowPixmapPtr, &nxagentShadowUpdateRegion);
+
+  REGION_EMPTY(nxagentShadowPixmapPtr -> drawable.pScreen, &nxagentShadowUpdateRegion);
+
+  return 1;
+}
+
+int nxagentShadowPoll(PixmapPtr nxagentShadowPixmapPtr, GCPtr nxagentShadowGCPtr,
+                            unsigned char nxagentShadowDepth, int nxagentShadowWidth,
+                                 int nxagentShadowHeight, char *nxagentShadowBuffer, int *changed, int *suspended)
+{
+  int x, y, y2, n, c, line;
+  int result;
+  long numRects;
+  unsigned int width, height, length;
+  char *tBuffer = NULL;
+  char *iBuffer, *ptBox;
+  BoxRec *pBox;
+  RegionRec updateRegion;
+  RegionRec tempRegion;
+  BoxRec box;
+  int overlap;
+
+
+  REGION_NULL(pScreen, &updateRegion);
+
+  REGION_NULL(pScreen, &tempRegion);
+
+#ifdef __CYGWIN32__
+
+  if (NXShadowCaptureCursor(nxagentWindow(nxagentShadowWindowPtr),
+          nxagentShadowWindowPtr -> drawable.pScreen -> visuals) == -1)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentShadowPoll: Failed to capture cursor.\n");
+    #endif
+  }
+
+#endif
+
+  result = NXShadowHasChanged(nxagentUserInput, NULL, suspended);
+
+  *changed = result;
+
+  if (result == 1)
+  {
+    if (nxagentWMPassed == 0)
+    {
+      nxagentRemoveSplashWindow(NULL);
+    }
+
+    NXShadowExportChanges(&numRects, &ptBox);
+    pBox = (BoxRec *)ptBox;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowPoll: nRects[%ld],pBox[%p] depth[%d].\n", numRects, pBox, nxagentShadowDepth);
+    #endif
+
+    for (n = 0; n < numRects; n++)
+    {
+      /*
+       * The BoxRec struct defined in the Xserver has a different
+       * variable order in comparison with the BoxRec struct in the Xlib.
+       * the second and third field are inverted.
+       */
+
+      x = pBox[n].x1;
+      y = pBox[n].x2;
+      y2 = pBox[n].y2;
+      width = pBox[n].y1 - pBox[n].x1;/* y1 = x2 */
+      height = y2 - pBox[n].x2;   /* x2 = y1 */
+
+      line = PixmapBytePad(width, nxagentMasterDepth);
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentShadowPoll: Rectangle Number[%d] - x[%d]y[%d]W[%u]H[%u].\n", n+1, x, y, width, height);
+      #endif
+
+      length = nxagentImageLength(width, height, ZPixmap, 0, nxagentMasterDepth);
+
+      if (tBuffer)
+      {
+        xfree(tBuffer);
+      }
+
+      tBuffer = xalloc(length);
+
+      if (tBuffer == NULL)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentShadowPoll: xalloc failed.\n");
+        #endif
+
+        return -1;
+      }
+
+      iBuffer = tBuffer;
+
+      for (c = 0; c + y < y2; c++)
+      {
+        memcpy(tBuffer, nxagentShadowBuffer + x * nxagentBppMaster + 
+                   (y + c) * nxagentShadowWidth * nxagentBppMaster, line);
+
+        tBuffer += line;
+
+      }
+
+      tBuffer = iBuffer;
+
+#ifdef __CYGWIN32__
+      if (nxagentBppMaster == 2)
+      {
+        NXShadowCorrectColor(length, tBuffer);
+      }
+#else
+      if (nxagentCheckDepth == 1)
+      {
+        nxagentShadowAdaptDepth(width, height, line, &tBuffer);
+      }
+#endif
+
+      fbPutImage(nxagentVirtualDrawable((DrawablePtr)nxagentShadowPixmapPtr), nxagentShadowGCPtr,
+                          nxagentShadowDepth, x, y, width, height, 0, ZPixmap, tBuffer);
+
+      box.x1 = x;
+      box.x2 = x + width;
+      box.y1 = y;
+      box.y2 = y + height;
+
+      REGION_INIT(pScreen, &tempRegion, &box, 1);
+
+      REGION_APPEND(pScreen, &updateRegion, &tempRegion);
+
+      REGION_UNINIT(pScreen, &tempRegion);
+
+      REGION_VALIDATE(pScreen, &updateRegion, &overlap);
+
+      REGION_UNION(pScreen, &nxagentShadowUpdateRegion, &nxagentShadowUpdateRegion, &updateRegion);
+    }
+
+    if (tBuffer)
+    {
+      xfree(tBuffer);
+    }
+
+    REGION_UNINIT(pScreen, &updateRegion);
+  }
+  else if (result == -1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentShadowPoll: polling failed!\n");
+    #endif
+
+    usleep(50 * 1000);
+
+    return -1;
+  }
+
+  return 0;
+}
+
+void nxagentShadowAdaptDepth(unsigned int width, unsigned int height,
+                                   unsigned int lineMaster, char **buffer)
+{
+  unsigned char red;
+  unsigned char green;
+  unsigned char blue;
+  unsigned short color16 = 0;
+  unsigned char * icBuffer;
+  unsigned char * cBuffer = NULL;
+  unsigned char * tBuffer = (unsigned char *) *buffer;
+  unsigned int lineShadow;
+  unsigned int length;
+  unsigned int c;
+  unsigned int pad;
+  unsigned int color32 = 0;
+  unsigned long redMask;
+  unsigned long greenMask;
+  unsigned long blueMask;
+  Visual *pVisual;
+
+  length = nxagentImageLength(width, height, ZPixmap, 0, nxagentShadowDepth);
+
+  cBuffer = xalloc(length);
+  icBuffer = cBuffer;
+
+  pVisual = nxagentImageVisual((DrawablePtr) nxagentShadowPixmapPtr, nxagentShadowDepth);
+
+  if (pVisual == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCorrectDepthShadow: WARNING! Visual not found. Using default visual.\n");
+    #endif
+    
+    pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCorrectDepthShadow: Shadow redMask [%x] greenMask[%x] blueMask[%x].\n",
+             pVisual -> red_mask, pVisual -> green_mask, pVisual -> blue_mask);
+  #endif
+
+  redMask = nxagentShadowDisplay -> screens[0].root_visual[0].red_mask;
+  greenMask = nxagentShadowDisplay -> screens[0].root_visual[0].green_mask;
+  blueMask = nxagentShadowDisplay -> screens[0].root_visual[0].blue_mask;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCorrectDepthShadow: Master redMask [%x] greenMask[%x] blueMask[%x].\n",
+              redMask, greenMask, blueMask);
+  #endif
+
+  switch(nxagentMasterDepth)
+  {
+   /*
+    * The Shadow agent has 24 bit depth.
+    */
+    case 16:
+    {
+      pad = lineMaster - nxagentBppMaster * width;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentCorrectDepthShadow: line [%d] width[%d] pad[%d].\n", lineMaster, width, pad);
+      #endif
+
+      while (height > 0)
+      {
+        for (c = 0; c < width ; c++)
+        {
+          if (imageByteOrder == LSBFirst)
+          {
+            color16 = *tBuffer++;
+            color16 |= (*tBuffer << 8);
+          }
+          else
+          {
+            color16 = (*tBuffer++) << 8;
+            color16 |= *tBuffer;
+          }
+
+          blue = ((short) blueMask & color16) << 3;
+          blue |= 0x3;
+
+          if (greenMask == 0x7e0)
+          {
+            /*
+             * bit mask 5-6-5
+             */
+
+            green = ((short) greenMask & color16) >> 3;
+            green |= 0x2;
+
+            red = ((short) redMask & color16) >> 8;
+            red |= 0x3;
+          }
+          else
+          {
+            /*
+             * bit mask 5-5-5
+             */
+
+            green = ((short) greenMask & color16) >> 2;
+            green |= 0x3;
+
+            red = ((short) redMask & color16) >> 7;
+            red |= 0x3;
+          }
+
+          tBuffer++;
+
+          if (nxagentDisplay -> byte_order == LSBFirst)
+          {
+            *cBuffer++ = blue;
+            *cBuffer++ = green;
+            *cBuffer++ = red;
+            cBuffer++;
+          }
+          else
+          {
+            cBuffer++;
+            *cBuffer++ = red;
+            *cBuffer++ = green;
+            *cBuffer++ = blue;
+          }
+        }
+        tBuffer += pad;
+        height--;
+      }
+      break;
+    }
+
+    /*
+     * The Shadow agent has 16 bit depth.
+     */
+    case 24:
+    {
+      lineShadow = PixmapBytePad(width, nxagentShadowDepth);
+
+      pad = lineShadow - nxagentBppShadow * width;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentCorrectDepthShadow: line [%d] width[%d] pad[%d].\n", lineShadow, width, pad);
+      #endif
+
+      while (height > 0)
+      {
+        for (c = 0; c < width; c++)
+        {
+          if (imageByteOrder == LSBFirst)
+          {
+            color32 = *tBuffer++;
+            color32 |= (*tBuffer++ << 8);
+            color32 |= (*tBuffer++ << 16);
+            tBuffer++;
+          }
+          else
+          {
+            tBuffer++;
+            color32 = (*tBuffer++ << 16);
+            color32 |= (*tBuffer++ << 8);
+            color32 |= *tBuffer++;
+          }
+
+          color16 = (color32 & (pVisual -> blue_mask << 3)) >> 3;
+
+          if (pVisual -> green_mask == 0x7e0)
+          {
+            /*
+             * bit mask 5-6-5
+             */
+             color16 |= (color32 & (pVisual -> green_mask << 5)) >> 5;
+             color16 |= (color32 & (pVisual -> red_mask << 8)) >> 8;
+          }
+          else
+          {
+            /*
+             * bit mask 5-5-5
+             */
+            color16 |= (color32 & (pVisual -> green_mask << 6)) >> 6;
+            color16 |= (color32 & (pVisual -> red_mask << 9)) >> 9;
+          }
+
+          if (nxagentDisplay -> byte_order == LSBFirst)
+          {
+            *cBuffer++ = color16 & 0xff;
+            *cBuffer++ = (color16 & 0xff00) >> 8;
+          }
+          else
+          {
+            *cBuffer++ = (color16 & 0xff00) >> 8;
+            *cBuffer++ = color16 & 0xff;
+          }
+        }
+        cBuffer += pad;
+        height--;
+      }
+      break;
+    }
+  }
+  cBuffer = (unsigned char *) *buffer;
+  *buffer = (char *) icBuffer;
+
+  if (cBuffer != NULL)
+  {
+    xfree(cBuffer);
+  }
+}
+
+#ifdef NXAGENT_ARTSD
+
+unsigned char fromHexNibble(char c)
+{
+  int uc = (unsigned char)c;
+
+  if(uc >= '0' && uc <= '9') return uc - (unsigned char)'0';
+  if(uc >= 'a' && uc <= 'f') return uc + 10 - (unsigned char)'a';
+  if(uc >= 'A' && uc <= 'F') return uc + 10 - (unsigned char)'A';
+
+  return 16; /*error*/
+}
+
+void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port)
+{
+  Window                rootWin;
+  XlibAtom              atomReturnType;
+  XlibAtom              propAtom;
+  int                   iReturnFormat;
+  unsigned long         ulReturnItems;
+  unsigned long         ulReturnBytesLeft;
+  unsigned char         *pszReturnData = NULL;
+  int                   iReturn;
+
+  int i,in;
+  char tchar[] = "    ";
+/*
+FIXME: The port information is not used at the moment and produces a
+       warning on recent gcc versions. Do we need such information
+       to run the audio forawrding?
+
+  char *chport;
+  char hex[] = "0123456789abcdef";
+*/
+  rootWin = DefaultRootWindow(nxagentDisplay);
+  propAtom = nxagentAtoms[4];  /* MCOPGLOBALS */
+
+  /*
+   * Get at most 64KB of data.
+   */
+
+  iReturn = XGetWindowProperty(nxagentDisplay,
+                               rootWin,
+                               propAtom,
+                               0,
+                               65536 / 4,
+                               False,
+                               XA_STRING,
+                               &atomReturnType,
+                               &iReturnFormat,
+                               &ulReturnItems,
+                               &ulReturnBytesLeft,
+                               &pszReturnData);
+
+  if (iReturn == Success && atomReturnType != None &&
+          ulReturnItems > 0 && pszReturnData != NULL)
+  {
+    char *local_buf;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentPropagateArtsdProperties: Got [%ld] elements of format [%d] with [%ld] bytes left.\n",
+                ulReturnItems, iReturnFormat, ulReturnBytesLeft);
+    #endif
+
+    #ifdef WARNING
+
+    if (ulReturnBytesLeft > 0)
+    {
+      fprintf(stderr, "nxagentPropagateArtsdProperties: WARNING! Could not get the whole ARTSD property data.\n");
+    }
+
+    #endif
+
+    local_buf = (char *) xalloc(strlen((char*)pszReturnData) + 100);
+
+    if (local_buf)
+    {
+      memset(local_buf, 0, strlen((char *) pszReturnData));
+
+      for (i = 0, in = 0; pszReturnData[i] != '\0'; i++)
+      {
+        local_buf[in]=pszReturnData[i];
+
+        if(pszReturnData[i]==':')
+        {
+          i++;
+
+          while(pszReturnData[i]!='\n')
+          {
+             unsigned char h;
+             unsigned char l;
+
+             h = fromHexNibble(pszReturnData[i]);
+             i++;
+             if(pszReturnData[i]=='\0') continue;
+             l = fromHexNibble(pszReturnData[i]);
+             i++;
+
+             if(h >= 16 || l >= 16) continue;
+
+             /*
+              * FIXME: The array tchar[] was used uninitialized.
+              * It's not clear to me the original purpose of the
+              * piece of code using it. To be removed in future
+              * versions.
+              */
+
+             tchar[0]=tchar[1];
+             tchar[1]=tchar[2];
+             tchar[2]=tchar[3];
+             tchar[3] = (h << 4) + l;
+             tchar[4]='\0';
+
+             if (strncmp(tchar, "tcp:", 4) == 0)
+             {
+               local_buf[in-7]='1';
+               local_buf[in-6]=strlen(port)+47;
+
+               in++;
+               local_buf[in]=pszReturnData[i-2];
+               in++;
+               local_buf[in]=pszReturnData[i-1];
+
+               strcat(local_buf,"6c6f63616c686f73743a");
+               in+=20;
+
+/*
+FIXME: The port information is not used at the moment and produces a
+       warning on recent gcc versions. Do we need such information
+       to run the audio forawrding?
+
+               chport=&port[0];
+
+               while(*chport!='\0')
+               {
+                 in++;
+                 local_buf[in]=hex[(*chport >> 4) & 0xf];
+                 in++;
+                 local_buf[in]=hex[*chport & 0xf];
+                 *chport++;
+               }
+*/
+               strcat(local_buf,"00");
+               in+=2;
+
+               while(pszReturnData[i]!='\n')
+               {
+                 i++;
+               }
+             }
+             else
+             {
+               in++;
+               local_buf[in]=pszReturnData[i-2];
+               in++;
+               local_buf[in]=pszReturnData[i-1];
+             }
+           }
+
+           in++;
+           local_buf[in]=pszReturnData[i];
+        }
+
+        in++;
+      }
+
+      local_buf[in]=0;
+
+      if (strlen(local_buf))
+      {
+        mcop_local_atom = MakeAtom(mcop_atom, strlen(mcop_atom), 1);
+
+        ChangeWindowProperty(WindowTable[pScreen->myNum],
+                             mcop_local_atom,
+                             XA_STRING,
+                             iReturnFormat, PropModeReplace,
+                             strlen(local_buf), local_buf, 1);
+      }
+
+      xfree(local_buf);
+    }
+  }
+}
+
+#endif
+
+Bool nxagentReconnectScreen(void *p0)
+{
+  CARD16 w, h;
+  PixmapPtr pPixmap = (PixmapPtr)nxagentDefaultScreen->devPrivate;
+  int flexibility;
+  Mask mask;
+
+  flexibility = *(int*)p0;
+
+#if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_SCREEN_DEBUG)
+  fprintf(stderr, "nxagentReconnectScreen\n");
+#endif
+
+  if (!nxagentOpenScreen(0, nxagentDefaultScreen, nxagentArgc, nxagentArgv))
+  {
+    return False;
+  }
+
+  nxagentPixmap(pPixmap) = XCreatePixmap(nxagentDisplay, 
+                                         nxagentDefaultWindows[nxagentDefaultScreen->myNum],
+                                         pPixmap -> drawable.width,
+                                         pPixmap -> drawable.height,
+                                         pPixmap -> drawable.depth);
+#ifdef NXAGENT_RECONNECT_SCREEN_DEBUG
+  fprintf(stderr, "nxagentReconnectScreen: recreated %p - ID %lx\n",
+                   pPixmap,
+                   nxagentPixmap( pPixmap ));
+#endif
+  w = 16;
+  h = 16;
+  (*nxagentDefaultScreen->QueryBestSize)(StippleShape, &w, &h, nxagentDefaultScreen);
+  if (!(nxagentPixmap(nxagentDefaultScreen->PixmapPerDepth[0]) =
+       XCreatePixmap(nxagentDisplay, 
+                     nxagentDefaultDrawables[1],
+                     w, 
+                     h, 
+                     1)));
+
+  nxagentGetDefaultEventMask(&mask);
+  mask |= NXAGENT_KEYBOARD_EVENT_MASK | NXAGENT_POINTER_EVENT_MASK;
+  nxagentSetDefaultEventMask(mask);
+  XSelectInput(nxagentDisplay, nxagentDefaultWindows[0], mask);
+
+  /*
+   * Turn off the screen-saver and reset the
+   * time to the next auto-disconnection.
+   */
+
+  SaveScreens(SCREEN_SAVER_OFF, ScreenSaverActive);
+
+  lastDeviceEventTime.milliseconds = GetTimeInMillis();
+
+  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;
+
+    pScrPriv = rrGetScrPriv(pScreen);
+   
+    oldWidth = pScreen->width;
+    oldHeight = pScreen->height;
+    
+    if (!pScrPriv)
+    {
+      return 1;
+    }
+
+    if (!RRGetInfo (pScreen))
+    {
+      return 1;
+    }
+
+    rotation = RR_Rotate_0;
+
+    rate = 0;
+
+    mmWidth  = (width * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+    if (mmWidth < 1)
+    {
+      mmWidth = 1;
+    }
+
+    mmHeight = (height * 254 + monitorResolution * 5) / (monitorResolution * 10);
+
+    if (mmHeight < 1)
+    {
+      mmHeight = 1;
+    }
+
+    pSize = xalloc(sizeof(RRScreenSize));
+
+    pSize -> width = width;
+    pSize -> height = height;
+    pSize -> mmWidth = mmWidth;
+    pSize -> mmHeight = mmHeight;
+
+    /*
+     * call out to ddx routine to effect the change
+     */
+
+    if (!(*pScrPriv->rrSetConfig) (pScreen, rotation, rate,
+                                       pSize))
+    {
+      /*
+       * unknown DDX failure.
+       */
+
+      xfree(pSize);
+
+      return 1;
+    }
+
+    /*
+     * TellChanged uses this privates.
+     */
+
+    oldSize = pScrPriv->size;
+    oldSizes = pScrPriv->pSizes;
+
+    pScrPriv->size = 0;
+    pScrPriv->pSizes = 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);
+
+    /*
+     * Restore old privates.
+     */
+
+    pScrPriv->pSizes = oldSizes;
+    pScrPriv->size = oldSize;
+
+    xfree(pSize);
+
+    return 0;
+}
+
+void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, WindowPtr pWin)
+{
+  PixmapPtr pVirtualPixmap;
+  nxagentPrivPixmapPtr pPrivPixmap;
+  XlibGC gc;
+  XGCValues values;
+  DrawablePtr pDrawable;
+  int i;
+  int xSrc, ySrc, xDst, yDst, w, h;
+  int nRects;
+  int size;
+  BoxPtr pBox;
+  XRectangle *pRects;
+  BoxRec extents;
+  RegionRec cleanRegion;
+
+  miBSWindowPtr pBackingStore = (miBSWindowPtr) pWin -> backStorage;
+
+  pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
+
+  pPrivPixmap = nxagentPixmapPriv(pPixmap);
+
+  pPrivPixmap -> isBackingPixmap = 1;
+
+  fbCopyWindowProc(&pWin -> drawable, &pVirtualPixmap -> drawable, 0, REGION_RECTS(prgnSave),
+                       REGION_NUM_RECTS(prgnSave), xorg, yorg, FALSE, FALSE, 0, 0);
+
+  pDrawable = &pWin -> drawable;
+
+  values.subwindow_mode = IncludeInferiors;
+
+  gc = XCreateGC(nxagentDisplay, nxagentWindow(WindowTable[0]), GCSubwindowMode, &values);
+
+  /*
+   * Initialize to the corrupted region.
+   * Coordinates are relative to the window.
+   */
+
+  REGION_INIT(pWin -> pScreen, &cleanRegion, NullBox, 1);
+
+  REGION_COPY(pWin -> pScreen, &cleanRegion, nxagentCorruptedRegion((DrawablePtr) pWin));
+
+  /*
+   * Subtract the corrupted region from the saved region.
+   */
+
+  REGION_SUBTRACT(pWin -> pScreen, &pBackingStore -> SavedRegion, &pBackingStore -> SavedRegion, &cleanRegion);
+
+  /*
+   * Translate the corrupted region. Coordinates
+   * are relative to the backing store pixmap.
+   */
+
+  REGION_TRANSLATE(pWin -> pScreen, &cleanRegion, -pBackingStore -> x, -pBackingStore -> y);
+
+  /*
+   * Compute the clean region to be saved: subtract
+   * the corrupted region from the region to be saved.
+   */
+
+  REGION_SUBTRACT(pWin -> pScreen, &cleanRegion, prgnSave, &cleanRegion);
+
+  nRects = REGION_NUM_RECTS(&cleanRegion);
+  size = nRects * sizeof(*pRects);
+  pRects = (XRectangle *) xalloc(size);
+  pBox = REGION_RECTS(&cleanRegion);
+
+  for (i = nRects; i-- > 0;)
+  {
+    pRects[i].x = pBox[i].x1;
+    pRects[i].y = pBox[i].y1;
+    pRects[i].width = pBox[i].x2 - pBox[i].x1;
+    pRects[i].height = pBox[i].y2 - pBox[i].y1;
+  }
+
+  XSetClipRectangles(nxagentDisplay, gc, 0, 0, pRects, nRects, Unsorted);
+
+  xfree((char *) pRects);
+
+  extents = *REGION_EXTENTS(pWin -> pScreen, &cleanRegion);
+
+  REGION_UNINIT(pWin -> pScreen, &cleanRegion);
+
+  xDst = extents.x1;
+  yDst = extents.y1;
+
+/*
+ * Left here the wrong solution. The window could be not
+ * configured yet on the real X, whilst the x and y in the
+ * WindowRec are the new coordinates. The right solution
+ * is the other, as it is independent from the window
+ * coordinates.
+ *
+ *  xSrc = xDst + xorg - pWin -> drawable.x;
+ *  ySrc = yDst + yorg - pWin -> drawable.y;
+ */
+
+  xSrc = xDst + pBackingStore -> x;
+  ySrc = yDst + pBackingStore -> y;
+
+  w = extents.x2 - extents.x1;
+  h = extents.y2 - extents.y1;
+
+  XCopyArea(nxagentDisplay, nxagentWindow(pWin), nxagentPixmap(pPixmap), gc,
+                xSrc, ySrc, w, h, xDst, yDst);
+
+  nxagentAddItemBSPixmapList(nxagentPixmap(pPixmap), pPixmap, pWin,
+                                 pBackingStore -> x, pBackingStore -> y);
+
+  #ifdef TEST
+  fprintf(stderr,"nxagentSaveAreas: Added pixmap [%p] with id [%d] on window [%p] to BSPixmapList.\n",
+              pPixmap, nxagentPixmap(pPixmap), pWin);
+  #endif
+
+  XFreeGC(nxagentDisplay, gc);
+
+  return;
+}
+
+void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int yorg, WindowPtr pWin)
+{
+  PixmapPtr pVirtualPixmap;
+  RegionPtr clipRegion;
+  XlibGC gc;
+  XGCValues values;
+  DrawablePtr pDrawable;
+  int i;
+  int xSrc, ySrc, xDst, yDst, w, h;
+  int nRects;
+  int size;
+  BoxPtr pBox;
+  XRectangle *pRects;
+  BoxRec extents;
+  miBSWindowPtr pBackingStore;
+
+  pBackingStore = (miBSWindowPtr) pWin -> backStorage;
+
+  pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
+
+  fbCopyWindowProc(&pVirtualPixmap -> drawable, &pWin -> drawable, 0, REGION_RECTS(prgnRestore),
+                       REGION_NUM_RECTS(prgnRestore), -xorg, -yorg, FALSE, FALSE, 0, 0);
+
+  pDrawable = &pVirtualPixmap -> drawable;
+
+  values.subwindow_mode = ClipByChildren;
+
+  gc = XCreateGC(nxagentDisplay, nxagentWindow(WindowTable[0]), GCSubwindowMode, &values);
+
+  /*
+   * Translate the reference point to the origin of the window.
+   */
+
+  REGION_TRANSLATE(pWin -> drawable.pScreen, prgnRestore,
+                       -pWin -> drawable.x - pWin -> borderWidth,
+                           -pWin -> drawable.y - pWin -> borderWidth);
+
+  clipRegion = prgnRestore;
+
+  if (nxagentDrawableStatus((DrawablePtr) pPixmap) == NotSynchronized)
+  {
+    clipRegion = REGION_CREATE(pPixmap -> drawable -> pScreen, NullBox, 1);
+
+    REGION_COPY(pPixmap -> drawable -> pScreen, clipRegion,
+                        nxagentCorruptedRegion((DrawablePtr) pPixmap));
+
+    /*
+     * Translate the reference point to the origin of the window.
+     */
+
+    REGION_TRANSLATE(pPixmap -> drawable -> pScreen, clipRegion,
+                         pBackingStore -> x, pBackingStore -> y);
+
+    REGION_INTERSECT(pPixmap -> drawable -> pScreen, clipRegion, prgnRestore, clipRegion);
+
+    /*
+     * Subtract the corrupted region from the saved areas.
+     * miBSRestoreAreas will return the exposure region.
+     */
+
+    REGION_SUBTRACT(pPixmap -> drawable -> pScreen, &pBackingStore->SavedRegion,
+                        &pBackingStore->SavedRegion, clipRegion);
+
+    /*
+     * Store the corrupted region to send expose later.
+     */
+
+    if (nxagentRemoteExposeRegion != NULL)
+    {
+      REGION_TRANSLATE(pPixmap -> drawable -> pScreen, clipRegion, pWin -> drawable.x, pWin -> drawable.y);
+
+      REGION_UNION(pScreen, nxagentRemoteExposeRegion, nxagentRemoteExposeRegion, clipRegion);
+
+      REGION_TRANSLATE(pPixmap -> drawable -> pScreen, clipRegion, -pWin -> drawable.x, -pWin -> drawable.y);
+    }
+
+    /*
+     * Compute the region to be restored.
+     */
+
+    REGION_SUBTRACT(pPixmap -> drawable -> pScreen, clipRegion, prgnRestore, clipRegion);
+  }
+
+  nRects = REGION_NUM_RECTS(clipRegion);
+  size = nRects * sizeof(*pRects);
+  pRects = (XRectangle *) xalloc(size);
+  pBox = REGION_RECTS(clipRegion);
+
+  for (i = nRects; i-- > 0;)
+  {
+    pRects[i].x = pBox[i].x1;
+    pRects[i].y = pBox[i].y1;
+    pRects[i].width = pBox[i].x2 - pBox[i].x1;
+    pRects[i].height = pBox[i].y2 - pBox[i].y1;
+  }
+
+  XSetClipRectangles(nxagentDisplay, gc, 0, 0, pRects, nRects, Unsorted);
+
+  xfree(pRects);
+
+  extents = *REGION_EXTENTS(pWin -> pScreen, clipRegion);
+
+  xDst = extents.x1;
+  yDst = extents.y1;
+
+  xSrc = xDst - xorg + pWin -> drawable.x;
+  ySrc = yDst - yorg + pWin -> drawable.y;
+
+  w = extents.x2 - extents.x1;
+  h = extents.y2 - extents.y1;
+
+  nxagentFlushConfigureWindow();
+
+  XCopyArea(nxagentDisplay, nxagentPixmap(pPixmap), nxagentWindow(pWin), gc,
+                xSrc, ySrc, w, h, xDst, yDst);
+
+  XFreeGC(nxagentDisplay, gc);
+
+  if (clipRegion != NULL && clipRegion != prgnRestore)
+  {
+    REGION_DESTROY(pPixmap -> drawable -> pScreen, clipRegion);
+  }
+
+  /*
+   * Restore the reference point to the origin of the screen.
+   */
+
+  REGION_TRANSLATE(pWin -> drawable.pScreen, prgnRestore,
+                       pWin -> drawable.x - pWin -> borderWidth,
+                           pWin -> drawable.y + pWin -> borderWidth);
+
+  return;
+}
+
+void nxagentSetWMNormalHints(int screen)
+{
+  XSizeHints sizeHints;
+
+  /*
+   * Change agent window size and size hints.
+   */
+
+  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 = nxagentOption(Width);
+  sizeHints.height = nxagentOption(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[screen], &sizeHints);
+}
+
+void nxagentShadowAdaptToRatio(void)
+{
+  XSizeHints sizeHints;
+  ScreenPtr pScreen;
+  RegionRec region;
+  BoxRec box;
+
+  pScreen = screenInfo.screens[0];
+
+  nxagentShadowSetRatio(nxagentOption(Width) * 1.0 / WindowTable[0] -> drawable.width, 
+                            nxagentOption(Height) * 1.0 / WindowTable[0] -> drawable.height);
+
+  nxagentShadowCreateMainWindow(pScreen, WindowTable[0], nxagentShadowWidth, nxagentShadowHeight);
+
+  sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+  sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+
+  sizeHints.flags = PMaxSize;
+
+  XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &sizeHints);
+
+  box.x1 = 0;
+  box.y1 = 0;
+  box.x2 = nxagentShadowPixmapPtr -> drawable.width;
+  box.y2 = nxagentShadowPixmapPtr -> drawable.height;
+
+  REGION_INIT(pScreen, &region, &box, 1);
+
+  nxagentMarkCorruptedRegion((DrawablePtr)nxagentShadowPixmapPtr, &region);
+
+  REGION_UNINIT(pScreen, &region);
+}
+
+#ifdef DUMP
+
+void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height)
+{
+  static int init = 1;
+  static Display *shadow;
+  static Window win;
+
+  XlibGC gc;
+  XGCValues value;
+  XImage *image;
+  WindowPtr pWin = WindowTable[0];
+  unsigned int format;
+  int depth, pixmapWidth, pixmapHeight, length;
+  char *data;
+
+  depth = pPixmap -> drawable.depth;
+  pixmapWidth = pPixmap -> drawable.width;
+  pixmapHeight = pPixmap -> drawable.height;
+  format = (depth == 1) ? XYPixmap : ZPixmap;
+
+  if (init)
+  {
+    shadow = XOpenDisplay("localhost:0");
+
+    if (shadow == NULL)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentShowPixmap: WARNING! Shadow display not opened.\n");
+      #endif
+
+      return;
+    }
+
+    init = False;
+  }
+
+  if (win == 0)
+  {
+    win = XCreateSimpleWindow(shadow, DefaultRootWindow(shadow), 0, 0,
+                                    width, height, 0, 0xFFCC33, 0xFF);
+
+    XSelectInput(shadow, win, StructureNotifyMask);
+
+    XMapWindow(shadow, win);
+
+    for(;;)
+    {
+      XEvent e;
+
+      XNextEvent(shadow, &e);
+
+      if (e.type == MapNotify)
+      {
+        break;
+      }
+    }
+  }
+  else
+  {
+    XResizeWindow(nxagentDisplay, win, width, height);
+    XRaiseWindow(nxagentDisplay, win);
+  }
+
+  length = nxagentImageLength(width, height, format, 0, depth);
+
+  if ((data = xalloc(length)) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentShowPixmap: xalloc failed.\n");
+    #endif
+
+    return;
+  }
+
+/*
+FIXME
+  image = XGetImage(nxagentDisplay, nxagentPixmap(pPixmap), x, y,
+                        width, height, AllPlanes, format);
+*/
+
+  image = XGetImage(nxagentDisplay, RootWindow(nxagentDisplay, 0), 0, 0,
+                        width, height, AllPlanes, format);
+
+  if (image == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentShowPixmap: XGetImage failed.\n");
+    #endif
+
+    if (data)
+    {
+      xfree(data);
+    }
+
+    return;
+  }
+
+  fbGetImage((DrawablePtr)pPixmap, 0, 0,
+                 width, height, format, AllPlanes, data);
+
+  memcpy(image -> data, data, length);
+
+  value.foreground = 0xffffff;
+  value.background = 0x000000;
+  value.plane_mask = 0xffffff;
+  value.fill_style = FillSolid;
+
+  gc = XCreateGC(shadow, win, GCBackground |
+                     GCForeground | GCFillStyle | GCPlaneMask, &value);
+
+  XSync(shadow, 0);
+
+  NXCleanImage(image);
+
+  XPutImage(shadow, win, gc, image, 0, 0, 0, 0, width, height);
+
+  XFlush(shadow);
+
+  XFreeGC(shadow, gc);
+
+  if (image != NULL)
+  {
+    XDestroyImage(image);
+  }
+
+  if (data != NULL)
+  {
+    xfree(data);
+  }
+
+/*
+FIXME
+  if (win != NULL)
+  {
+    XDestroyWindow(shadow, win);
+  }
+*/
+}
+
+void nxagentFbRestoreArea(PixmapPtr pPixmap, WindowPtr pWin, int xSrc, int ySrc, int width,
+                              int height, int xDst, int yDst)
+{
+  Display *shadow;
+
+  XlibGC gc;
+  XGCValues value;
+  XImage *image;
+  unsigned int format;
+  int depth, pixmapWidth, pixmapHeight, length;
+  char *data = NULL;
+  Visual *pVisual;
+
+  depth = pPixmap -> drawable.depth;
+  pixmapWidth = pPixmap -> drawable.width;
+  pixmapHeight = pPixmap -> drawable.height;
+  format = (depth == 1) ? XYPixmap : ZPixmap;
+
+  shadow = nxagentDisplay;
+
+  length = nxagentImageLength(width, height, format, 0, depth);
+
+  if ((data = xalloc(length)) == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbRestoreArea: xalloc failed.\n");
+    #endif
+
+    return;
+  }
+/*
+  image = XGetImage(nxagentDisplay, nxagentPixmap(pPixmap), xSrc, ySrc,
+                        width, height, AllPlanes, format);
+*/
+
+  if (image == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbRestoreArea: XGetImage failed.\n");
+    #endif
+
+    if (data)
+    {
+      xfree(data);
+    }
+
+    return;
+  }
+
+  fbGetImage((DrawablePtr)pPixmap, xSrc, ySrc,
+                 width, height, format, AllPlanes, data);
+
+/*
+FIXME
+*/
+  pVisual = nxagentImageVisual((DrawablePtr) pPixmap, depth);
+
+  if (pVisual == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentFbRestoreArea: WARNING! Visual not found. Using default visual.\n");
+    #endif
+    
+    pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
+  } 
+
+  image = XCreateImage(nxagentDisplay, pVisual,
+                                  depth, format, 0, (char *) data,
+                                  width, height, BitmapPad(nxagentDisplay),
+                                  nxagentImagePad(width, format, 0, depth));
+/*
+FIXME
+  memcpy(image -> data, data, length);
+*/
+
+  fprintf(stderr, "nxagentFbRestoreArea: Cleaning %d bytes of image.\n", length);
+
+  value.foreground = 0xffffff;
+  value.background = 0x000000;
+  value.plane_mask = 0xffffff;
+  value.fill_style = FillSolid;
+  value.function = GXcopy;
+
+  gc = XCreateGC(shadow, nxagentWindow(WindowTable[0]), GCBackground |
+                     GCForeground | GCFillStyle | GCPlaneMask | GCFunction, &value);
+
+  NXCleanImage(image);
+
+  XPutImage(shadow, nxagentWindow(pWin), gc, image, 0, 0, xDst, yDst, width, height);
+
+/*
+FIXME
+*/
+  XFlush(shadow);
+
+  XFreeGC(shadow, gc);
+
+  if (image)
+  {
+    XDestroyImage(image);
+  }
+
+/*
+FIXME
+  if (data)
+  {
+    xfree(data);
+  }
+*/
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
new file mode 100644
index 000000000..3550dd553
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -0,0 +1,130 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Screen_H__
+#define __Screen_H__
+
+#define MIN_NXAGENT_WIDTH  80
+#define MIN_NXAGENT_HEIGHT 60
+#define NXAGENT_FRAME_WIDTH 2000
+
+extern int nxagentClients;
+
+extern int nxagentAutoDisconnectTimeout;
+
+extern ScreenPtr nxagentDefaultScreen;
+
+extern Pixmap nxagentPixmapLogo;
+
+extern Window nxagentIconWindow;
+extern Window nxagentFullscreenWindow;
+
+extern RegionRec nxagentShadowUpdateRegion;
+
+extern WindowPtr nxagentShadowWindowPtr;
+
+extern int nxagentShadowResize;
+
+extern short nxagentShadowUid;
+
+void nxagentSetScreenInfo(ScreenInfo *screenInfo);
+void nxagentSetPixmapFormats(ScreenInfo *screenInfo);
+
+extern Window nxagentDefaultWindows[MAXSCREENS];
+extern Window nxagentInputWindows[MAXSCREENS];
+extern Window nxagentScreenSaverWindows[MAXSCREENS];
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentInitViewportFrame(ScreenPtr pScreen, WindowPtr pRootWin);
+
+#else /* #ifdef VIEWPORT_FRAME */
+
+#define nxagentInitViewportFrame(pScreen, pRootWin)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
+                           int argc, char *argv[]);
+
+Bool nxagentCloseScreen(int index, ScreenPtr pScreen);
+
+#define nxagentScreen(window) nxagentDefaultScreen
+
+extern int nxagentBitsPerPixel(int depth);
+
+void nxagentSetScreenSaverTime(void);
+
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
+
+Window nxagentCreateIconWindow(void);
+
+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);
+
+extern Bool nxagentReconnectScreen(void *p0);
+
+void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg, WindowPtr pWin);
+
+void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int yorg, WindowPtr pWin);
+
+extern int monitorResolution;
+
+int nxagentShadowCreateMainWindow( ScreenPtr pScreen, WindowPtr pWin,int width, int height);
+
+int nxagentShadowSendUpdates(int *);
+
+int nxagentShadowPoll(PixmapPtr, GCPtr, unsigned char, int, int, char *, int *, int *);
+
+void nxagentShadowSetWindowsSize(void);
+
+void nxagentSetWMNormalHints(int);
+
+void nxagentShadowSetRatio(float, float);
+
+/*
+ * Change window settings to adapt to a ratio.
+ */
+
+extern void nxagentShadowAdaptToRatio(void);
+
+/*
+ * The pixmap shadowing the real frame buffer.
+ */
+
+extern PixmapPtr nxagentShadowPixmapPtr;
+
+#endif /* __Screen_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
new file mode 100644
index 000000000..8de74b85b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
@@ -0,0 +1,335 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "windowstr.h"
+#include "scrnintstr.h"
+
+#ifdef _XSERVER64
+
+#include "Agent.h"
+
+#define GC XlibGC
+
+#endif /* _XSERVER64 */
+
+#include "Xlib.h"
+#include "Xutil.h"
+
+#include "Display.h"
+#include "Splash.h"
+#include "Screen.h"
+#include "Windows.h"
+#include "Atoms.h"
+#include "Trap.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Colors used to paint the splash screen.
+ */
+
+int nxagentLogoDepth;
+int nxagentLogoWhite;
+int nxagentLogoRed;
+int nxagentLogoBlack;
+
+void nxagentPaintLogo(Window win, GC gc, int scale, int width, int height);
+
+/*
+ * From Screen.c.
+ */
+
+extern Atom nxagentWMStart;
+
+/*
+ * From Clipboard.c.
+ */
+
+extern Atom serverCutProperty;
+
+int nxagentShowSplashWindow(Window parentWindow)
+{
+  XWindowAttributes getAttributes;
+  XWindowChanges    values;
+  XSetWindowAttributes attributes;
+  GC gc;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentShowSplash: Got called.\n");
+  #endif
+
+  #ifdef NXAGENT_TIMESTAMP
+  {
+    extern unsigned long startTime;
+
+    fprintf(stderr, "nxagentShowSplash: Initializing splash start at [%d] milliseconds.\n",
+            GetTimeInMillis() - startTime);
+  }
+  #endif
+
+  XSetSelectionOwner(nxagentDisplay, nxagentWMStart, None, CurrentTime);
+
+  nxagentWMPassed = False;
+
+  /*
+   * This would cause a GetWindowAttributes and a
+   * GetGeometry (asynchronous) reply. We use instead
+   * the geometry requested by the user for the agent
+   * window.
+   *
+   * XGetWindowAttributes(nxagentDisplay, parentWindow, &getAttributes);
+   */
+
+  /*
+   * During reconnection we draw the splash over
+   * the default window and not over the root
+   * window because it would be hidden  by other
+   * windows.
+   */
+
+  if (nxagentReconnectTrap)
+  {
+    getAttributes.x = nxagentOption(RootX);
+    getAttributes.y = nxagentOption(RootY);
+  }
+  else
+  {
+    getAttributes.x = 0;
+    getAttributes.y = 0;
+  }
+
+  getAttributes.width  = nxagentOption(RootWidth);
+  getAttributes.height = nxagentOption(RootHeight);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentShowSplash: Going to create new splash window.\n");
+  #endif
+
+  nxagentSplashWindow =
+      XCreateSimpleWindow(nxagentDisplay,
+                          parentWindow,
+                          getAttributes.x, getAttributes.y,
+                          getAttributes.width, getAttributes.height,
+                          0,
+                          WhitePixel (nxagentDisplay, 0),
+                          BlackPixel (nxagentDisplay, 0));
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentShowSplash: Created new splash window with id [%ld].\n",
+              nxagentSplashWindow);
+  #endif
+
+  gc = XCreateGC(nxagentDisplay, nxagentSplashWindow, 0, NULL);
+  nxagentPaintLogo(nxagentSplashWindow, gc, 1, getAttributes.width, getAttributes.height);
+  XMapRaised (nxagentDisplay, nxagentSplashWindow);
+  values.stack_mode = Above;
+  XConfigureWindow(nxagentDisplay, nxagentSplashWindow, CWStackMode, &values);
+  attributes.override_redirect = True;
+  XChangeWindowAttributes(nxagentDisplay, nxagentSplashWindow, CWOverrideRedirect, &attributes);
+  XFreeGC(nxagentDisplay, gc);
+
+  #ifdef NXAGENT_TIMESTAMP
+  {
+    extern unsigned long startTime;
+    fprintf(stderr, "nxagentShowSplash: Splash ends [%d] milliseconds.\n",
+            GetTimeInMillis() - startTime);
+  }
+  #endif
+
+  return True;
+}
+
+void nxagentPaintLogo(Window win, GC gc, int scale, int width, int height)
+{
+  XPoint    rect[4];
+  XPoint    m[12];
+  int w, h, c, w2, h2;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagenShowtLogo: Got called.\n");
+  #endif
+
+  #ifdef NXAGENT_LOGO_DEBUG
+  fprintf(stderr, "nxagentPaintLogo: begin\n");
+  fprintf(stderr, "nxagentPaintLogo: gen params are: w=%d h=%d d=%d r=%x w=%x b=%x\n",width, height,
+          nxagentLogoDepth, nxagentLogoRed,
+          nxagentLogoWhite, nxagentLogoBlack);
+  #endif
+
+  w = width/scale;
+  h = height/scale;
+
+  w2 = w/2;
+  h2 = h/2;
+
+  if (height > width)
+  {
+    c = w/30;
+  }
+  else
+  {
+    c = w/48;
+  }
+
+  rect[0].x = 0;               rect[0].y = 0;
+  rect[1].x = 0;               rect[1].y = h;
+  rect[2].x = w;               rect[2].y = h;
+  rect[3].x = w;               rect[3].y = 0;
+
+  XSetFunction(nxagentDisplay, gc, GXcopy);
+  XSetFillStyle(nxagentDisplay, gc, FillSolid);
+  XSetForeground(nxagentDisplay, gc, nxagentLogoBlack);
+  XSetBackground(nxagentDisplay, gc, nxagentLogoRed);
+
+  nxagentPixmapLogo = XCreatePixmap(nxagentDisplay, win, width, height, nxagentLogoDepth);
+
+  if (!nxagentPixmapLogo)
+  {
+    return;
+  }
+
+  XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+  #ifdef NXAGENT_LOGO_DEBUG
+  fprintf(stderr, "filled first poly\n");
+  #endif
+
+  XSetForeground(nxagentDisplay, gc, nxagentLogoRed);
+  XSetBackground(nxagentDisplay, gc, nxagentLogoWhite);
+
+  rect[0].x = w2-10*c;               rect[0].y = h2-8*c;
+  rect[1].x = w2-10*c;               rect[1].y = h2+8*c;
+  rect[2].x = w2+10*c;               rect[2].y = h2+8*c;
+  rect[3].x = w2+10*c;               rect[3].y = h2-8*c;
+
+  XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+  #ifdef NXAGENT_LOGO_DEBUG
+  fprintf(stderr, "filled red rect\n");
+  #endif
+
+  rect[0].x = w2-9*c;               rect[0].y = h2-7*c;
+  rect[1].x = w2-9*c;               rect[1].y = h2+7*c;
+  rect[2].x = w2+9*c;               rect[2].y = h2+7*c;
+  rect[3].x = w2+9*c;               rect[3].y = h2-7*c;
+
+  XSetForeground(nxagentDisplay, gc, nxagentLogoWhite);
+  XSetBackground(nxagentDisplay, gc, nxagentLogoRed);
+
+  XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+  /*
+   * Begin 'M'.
+   */
+
+  m[0].x = w2-3*c;  m[0].y = h2-5*c;
+  m[1].x = w2+7*c;  m[1].y = h2-5*c;
+  m[2].x = w2+7*c;  m[2].y = h2+5*c;
+  m[3].x = w2+5*c;  m[3].y = h2+5*c;
+  m[4].x = w2+5*c;  m[4].y = h2-3*c;
+  m[5].x = w2+3*c;  m[5].y = h2-3*c;
+  m[6].x = w2+3*c;  m[6].y = h2+5*c;
+  m[7].x = w2+1*c;  m[7].y = h2+5*c;
+  m[8].x = w2+1*c;  m[8].y = h2-3*c;
+  m[9].x = w2-1*c;  m[9].y = h2-3*c;
+  m[10].x = w2-1*c; m[10].y = h2+5*c;
+  m[11].x = w2-3*c; m[11].y = h2+5*c;
+
+  XSetForeground(nxagentDisplay, gc, nxagentLogoRed);
+  XSetBackground(nxagentDisplay, gc, nxagentLogoWhite);
+
+  XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, m, 12, Nonconvex, CoordModeOrigin);
+
+  /*
+   * End 'M'.
+   */
+
+  /*
+   * Begin '!'.
+   */
+
+  rect[0].x = w2-7*c;               rect[0].y = h2-5*c;
+  rect[1].x = w2-5*c;               rect[1].y = h2-5*c;
+  rect[2].x = w2-5*c;               rect[2].y = h2+2*c;
+  rect[3].x = w2-7*c;               rect[3].y = h2+2*c;
+
+  XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+  rect[0].x = w2-7*c;               rect[0].y = h2+3*c;
+  rect[1].x = w2-5*c;               rect[1].y = h2+3*c;
+  rect[2].x = w2-5*c;               rect[2].y = h2+5*c;
+  rect[3].x = w2-7*c;               rect[3].y = h2+5*c;
+
+  XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin);
+
+  /*
+   * End 'M'.
+   */
+
+  XSetWindowBackgroundPixmap(nxagentDisplay, win, nxagentPixmapLogo);
+
+  #ifdef NXAGENT_LOGO_DEBUG
+  fprintf(stderr, "nxagentPaintLogo: end\n");
+  #endif
+}
+
+void nxagentRemoveSplashWindow(WindowPtr pWin)
+{
+  if (nxagentReconnectTrap) return;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRemoveSplashWindow: Destroying the splash window.\n");
+  #endif
+
+  if (!nxagentWMPassed)
+  {
+    XSetSelectionOwner(nxagentDisplay, nxagentWMStart,
+                          nxagentDefaultWindows[0], CurrentTime);
+
+    nxagentWMPassed = True;
+  }
+
+  if (nxagentSplashWindow != None)
+  {
+    XDestroyWindow(nxagentDisplay, nxagentSplashWindow);
+
+    nxagentSplashWindow = None;
+    nxagentRefreshWindows(WindowTable[0]);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentRemoveSplashWindow: setting the ownership of %s (%d) on window 0x%lx\n",
+                "NX_CUT_BUFFER_SERVER", (int)serverCutProperty, nxagentWindow(WindowTable[0]));
+    #endif
+
+    XSetSelectionOwner(nxagentDisplay, serverCutProperty,
+                           nxagentWindow(WindowTable[0]), CurrentTime);
+  }
+
+  if (nxagentPixmapLogo)
+  {
+    XFreePixmap(nxagentDisplay, nxagentPixmapLogo);
+
+    nxagentPixmapLogo = (Pixmap) 0;
+  }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.h b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
new file mode 100644
index 000000000..bcc3a90b1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
@@ -0,0 +1,45 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Splash_H__
+#define __Splash_H__
+
+#include "Windows.h"
+#include "X11/Xdmcp.h"
+#include "NXalert.h"
+
+#define XDM_TIMEOUT       20000
+
+extern xdmcp_states XdmcpState;
+extern int XdmcpTimeOutRtx;
+extern int XdmcpStartTime;
+extern int nxagentXdmcpUp;
+
+extern int nxagentLogoDepth;
+extern int nxagentLogoWhite;
+extern int nxagentLogoRed;
+extern int nxagentLogoBlack;
+
+extern Window nxagentSplashWindow;
+
+extern int nxagentWMPassed;
+
+extern int nxagentShowSplashWindow(Window);
+
+extern void nxagentRemoveSplashWindow(WindowPtr pWin);
+
+#endif /* __Splash_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.c b/nx-X11/programs/Xserver/hw/nxagent/Split.c
new file mode 100644
index 000000000..8f1c65eba
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.c
@@ -0,0 +1,1248 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Drawable.h"
+#include "Events.h"
+#include "GCs.h"
+
+#include "NXlib.h"
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * This should be a macro but for now
+ * we make it a real function to log
+ * a warning in the logs.
+ */
+
+DrawablePtr nxagentSplitDrawable(DrawablePtr pDrawable)
+{
+  if (pDrawable -> type == DRAWABLE_PIXMAP &&
+          nxagentPixmapIsVirtual((PixmapPtr) pDrawable))
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSplitDrawable: WARNING! The drawable at [%p] is "
+                "virtual. Assuming real at [%p].\n", (void *) pDrawable,
+                    (void *) nxagentRealPixmap((PixmapPtr) pDrawable));
+    #endif
+
+    return (DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable);
+  }
+  else
+  {
+    return pDrawable;
+  }
+}
+
+void nxagentInitSplitResources()
+{
+  int resource;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentInitSplitResources: Initializing the split resources.\n");
+  #endif
+
+  for (resource = 0; resource < NXNumberOfResources; resource++)
+  {
+    SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+    pResource -> pending  = 0;
+    pResource -> commit   = 0;
+    pResource -> split    = NXNoResource;
+    pResource -> unpack   = NXNoResource;
+    pResource -> drawable = NULL;
+    pResource -> region   = NullRegion;
+    pResource -> gc       = NULL;
+  }
+}
+
+SplitResourcePtr nxagentAllocSplitResource()
+{
+  int resource;
+
+  SplitResourcePtr pResource;
+
+  for (;;)
+  {
+    resource = NXAllocSplit(nxagentDisplay, NXAnyResource);
+
+    if (resource != NXNoResource)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentAllocSplitResource: Reserving resource [%d] for the next split.\n",
+                  resource);
+      #endif
+
+      break;
+    }
+    else
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentAllocSplitResource: PANIC! No more resources for the next split.\n");
+      #endif
+/*
+FIXME: Must deal with the case all resources are exausted.
+*/
+      FatalError("nxagentAllocSplitResource: PANIC! No more resources for the next split.\n");
+    }
+  }
+
+  pResource = &nxagentSplitResources[resource];
+
+  if (pResource -> pending != 0 || pResource -> split != NXNoResource ||
+          pResource -> unpack != NXNoResource || pResource -> drawable != NULL ||
+              pResource -> region != NullRegion || pResource -> commit != 0 ||
+                  pResource -> gc != NULL)
+  {
+    /*
+     * This is really an unrecoverable error.
+     */
+
+    #ifdef PANIC
+    fprintf(stderr, "nxagentAllocSplitResource: PANIC! Invalid record for resource [%d] with "
+                "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                    resource, pResource -> pending, pResource -> split, pResource -> unpack,
+                        (void *) pResource -> drawable, (void *) pResource -> region,
+                            pResource -> commit, (void *) pResource -> gc);
+    #endif
+
+    FatalError("nxagentAllocSplitResource: PANIC! Invalid record for resource [%d] with "
+                   "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                       resource, pResource -> pending, pResource -> split, pResource -> unpack,
+                           (void *) pResource -> drawable, (void *) pResource -> region,
+                               pResource -> commit, (void *) pResource -> gc);
+  }
+
+  pResource -> pending = 1;
+  pResource -> split   = resource;
+
+  return pResource;
+}
+
+void nxagentFreeSplitResource(SplitResourcePtr pResource)
+{
+  if (pResource -> pending == 0 || pResource -> split == NXNoResource ||
+          pResource -> drawable != NULL || pResource -> region != NullRegion ||
+              pResource -> gc != NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentFreeSplitResource: PANIC! Invalid record provided with values "
+                "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                    pResource -> pending, pResource -> split, pResource -> unpack,
+                        (void *) pResource -> drawable, (void *) pResource -> region,
+                            pResource -> commit, (void *) pResource -> gc);
+    #endif
+
+    FatalError("nxagentFreeSplitResource: PANIC! Invalid record provided with values "
+                   "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                       pResource -> pending, pResource -> split, pResource -> unpack,
+                           (void *) pResource -> drawable, (void *) pResource -> region,
+                               pResource -> commit, (void *) pResource -> gc);
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentFreeSplitResource: Clearing the record for resource [%d].\n",
+              pResource -> split);
+  #endif
+
+  NXFreeSplit(nxagentDisplay, pResource -> split);
+
+  pResource -> pending  = 0;
+  pResource -> commit   = 0;
+  pResource -> split    = NXNoResource;
+  pResource -> unpack   = NXNoResource;
+  pResource -> drawable = NULL;
+  pResource -> region   = NullRegion;
+  pResource -> gc       = NULL;
+}
+
+void nxagentInitUnpackResources()
+{
+/*
+FIXME: This must be implemented.
+*/
+}
+
+UnpackResourcePtr nxagentAllocUnpackResource()
+{
+/*
+FIXME: This must be implemented.
+*/
+  return NULL;
+}
+
+void nxagentFreeUnpackResource(UnpackResourcePtr pResource)
+{
+/*
+FIXME: This must be implemented.
+*/
+}
+
+void nxagentReleaseAllSplits(void)
+{
+  int resource;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReleaseAllSplits: Going to release all the split resources.\n");
+  #endif
+
+  for (resource = 0; resource < NXNumberOfResources; resource++)
+  {
+    SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+    if (pResource != NULL && pResource -> pending == 1)
+    {
+      DrawablePtr pDrawable = pResource -> drawable;
+
+      if (pDrawable != NULL)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentReleaseAllSplits: Releasing the drawable at [%p] for "
+                    "resource [%d].\n", (void *) pDrawable, pResource -> split);
+        #endif
+
+        nxagentReleaseSplit(pDrawable);
+      }
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentReleaseAllSplits: Freeing the resource [%d].\n",
+                  resource);
+      #endif
+
+      nxagentFreeSplitResource(pResource);
+    }
+  }
+}
+
+/*
+ * Check the coherency of the split record.
+ */
+
+#ifdef TEST
+
+static void nxagentCheckSplit(DrawablePtr pDrawable, SplitResourcePtr pResource)
+{
+  if (pResource == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCheckSplit: PANIC! No record associated to drawable at [%p].\n",
+              (void *) pDrawable);
+    #endif
+
+    FatalError("nxagentCheckSplit: PANIC! No record associated to drawable at [%p].\n",
+                   (void *) pDrawable);
+  }
+  else if (pResource -> drawable != pDrawable ||
+               pResource -> split == NXNoResource)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCheckSplit: PANIC! The record [%d] doesn't match the drawable at [%p].\n",
+                pResource -> split, (void *) pDrawable);
+    #endif
+
+    FatalError("nxagentCheckSplit: PANIC! The record [%d] doesn't match the drawable at [%p].\n",
+                pResource -> split, (void *) pDrawable);
+  }
+  else if (pResource -> commit == 1 &&
+               pResource -> gc == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCheckSplit: PANIC! The record [%d] doesn't have a valid GC.\n",
+                pResource -> split);
+    #endif
+
+    FatalError("nxagentCheckSplit: PANIC! The record [%d] doesn't have a valid GC.\n",
+                   pResource -> split);
+  }
+}
+
+static void nxagentCheckResource(SplitResourcePtr pResource, int resource)
+{
+  if (pResource == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCheckResource: PANIC! No record associated to resource [%d].\n",
+                resource);
+    #endif
+
+    FatalError("nxagentCheckResource: PANIC! No record associated to resource [%d].\n",
+                   resource);
+  }
+  else if ((pResource -> split != resource || pResource -> pending != 1) ||
+               (pResource -> commit == 1 && (pResource -> drawable == NULL ||
+                   pResource -> gc == NULL)))
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCheckResource: PANIC! Invalid record for resource [%d] with "
+                "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                    resource, pResource -> pending, pResource -> split, pResource -> unpack,
+                        (void *) pResource -> drawable, (void *) pResource -> region,
+                            pResource -> commit, (void *) pResource -> gc);
+    #endif
+
+    FatalError("nxagentCheckResource: PANIC! Invalid record for resource [%d] with "
+                   "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                       resource, pResource -> pending, pResource -> split, pResource -> unpack,
+                           (void *) pResource -> drawable, (void *) pResource -> region,
+                                pResource -> commit, (void *) pResource -> gc);
+  }
+}
+
+#endif
+
+int nxagentCreateSplit(DrawablePtr pDrawable, GCPtr *pGC)
+{
+  SplitResourcePtr pResource;
+
+  pDrawable = nxagentSplitDrawable(pDrawable);
+
+  pResource = nxagentAllocSplitResource();
+
+  if (pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    nxagentPixmapPriv((PixmapPtr) pDrawable) -> splitResource = pResource;
+  }
+  else
+  {
+    nxagentWindowPriv((WindowPtr) pDrawable) -> splitResource = pResource;
+  }
+
+  pResource -> drawable = pDrawable;
+  pResource -> commit   = 1;
+
+  /*
+   * Make a copy of the GC so the client
+   * can safely remove it.
+   */
+
+  pResource -> gc = CreateScratchGC(pDrawable -> pScreen, pDrawable -> depth);
+
+/*
+FIXME: What do we do here?
+*/
+  if (pResource -> gc == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCreateSplit: PANIC! Failed to create split GC for resource [%d].\n",
+                pResource -> split);
+    #endif
+
+    FatalError("nxagentCreateSplit: PANIC! Failed to create split GC for resource [%d].\n",
+                   pResource -> split);
+  }
+  else if (CopyGC(*pGC, pResource -> gc, GCFunction | GCPlaneMask |
+                      GCSubwindowMode | GCClipXOrigin | GCClipYOrigin |
+                           GCClipMask | GCForeground | GCBackground) != Success)
+  {
+/*
+FIXME: What do we do here?
+*/
+    #ifdef PANIC
+    fprintf(stderr, "nxagentCreateSplit: PANIC! Failed to copy split GC for resource [%d].\n",
+                pResource -> split);
+    #endif
+
+    FatalError("nxagentCreateSplit: PANIC! Failed to copy split GC for resource [%d].\n",
+                   pResource -> split);
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateSplit: Associated GC at [%p] to resource [%d] "
+              "with id [%lu].\n", (void *) pResource -> gc, pResource -> split,
+                  (unsigned long) nxagentGC(pResource -> gc));
+  #endif
+
+  *pGC = pResource -> gc;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateSplit: Associated resource [%d] to drawable at [%p].\n",
+              pResource -> split, (void *) pResource -> drawable);
+  #endif
+
+  return pResource -> split;
+}
+
+/*
+ * Set the region to be the current
+ * streaming region.
+ */
+
+void nxagentRegionSplit(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+  SplitResourcePtr pResource;
+
+  pDrawable = nxagentSplitDrawable(pDrawable);
+
+  pResource = nxagentSplitResource(pDrawable);
+
+  #ifdef TEST
+
+  fprintf(stderr, "nxagentRegionSplit: Associating region to resource [%d] drawable at [%p].\n",
+              pResource -> split, (void *) pDrawable);
+
+  nxagentCheckSplit(pDrawable, pResource);
+
+  #endif
+  
+  if (pResource == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentRegionSplit: PANIC! No valid split record for drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRegionSplit: Associated region [%d,%d,%d,%d] to drawable at [%p] "
+              "with resource [%d].\n", pRegion -> extents.x1, pRegion -> extents.y1,
+                  pRegion -> extents.x2, pRegion -> extents.y2, (void *) pDrawable,
+                      pResource -> split);
+  #endif
+
+  pResource -> region = pRegion;
+}
+
+/*
+ * Remove the association between the drawable
+ * and the split resource. The resource is not
+ * deallocated until the end of the split.
+ */
+
+void nxagentReleaseSplit(DrawablePtr pDrawable)
+{
+  SplitResourcePtr pResource;
+
+  pDrawable = nxagentSplitDrawable(pDrawable);
+
+  pResource = nxagentSplitResource(pDrawable);
+
+  if (pResource == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentReleaseSplit: No split resources for drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+
+  fprintf(stderr, "nxagentReleaseSplit: Going to release resource [%d] for drawable at [%p].\n",
+              pResource -> split, (void *) pDrawable);
+
+  nxagentCheckSplit(pDrawable, pResource);
+
+  #endif
+
+  if (pResource -> region != NullRegion)
+  {
+    /*
+     * If we have a region the commits
+     * had to be still valid. In this
+     * case tell the proxy to abort the
+     * data transfer.
+     */
+
+    #ifdef TEST
+
+    if (pResource -> commit == 0)
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentReleaseSplit: PANIC! Found a region for resource [%d] but the "
+                  "commits are invalid.\n", pResource -> split);
+      #endif
+
+      FatalError("nxagentCheckSplit: PANIC! Found a region for resource [%d] but the "
+                     "commits are invalid.\n", pResource -> split);
+    }
+
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentValidateSplit: Aborting the data transfer for resource [%d].\n",
+                pResource -> split);
+    #endif
+
+    NXAbortSplit(nxagentDisplay, pResource -> split);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentReleaseSplit: Freeing the region for drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    REGION_DESTROY(pDrawable -> pScreen, pResource -> region);
+
+    pResource -> region = NullRegion;
+  }
+
+  if (pResource -> gc != NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentReleaseSplit: Freeing the split GC for drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    FreeScratchGC(pResource -> gc);
+
+    pResource -> gc = NULL;
+  }
+
+  /*
+   * Remove the association between the
+   * drawable and the resource record.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReleaseSplit: Removing association to drawable at [%p].\n",
+              (void *) pDrawable);
+  #endif
+
+  if (pDrawable -> type == DRAWABLE_PIXMAP)
+  {
+    nxagentPixmapPriv((PixmapPtr) pDrawable) -> splitResource = NULL;
+  }
+  else
+  {
+    nxagentWindowPriv((WindowPtr) pDrawable) -> splitResource = NULL;
+  }
+
+  /*
+   * Invalidate the commits and remove the
+   * association between the resource and
+   * the drawable.
+   */
+
+  pResource -> drawable = NULL;
+  pResource -> commit   = 0;
+}
+
+void nxagentValidateSplit(DrawablePtr pDrawable, RegionPtr pRegion)
+{
+  SplitResourcePtr pResource;
+
+  pDrawable = nxagentSplitDrawable(pDrawable);
+
+  pResource = nxagentSplitResource(pDrawable);
+
+  if (pResource == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentValidateSplit: No split resource for drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    return;
+  }
+  else if (pResource -> region == NullRegion)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentValidateSplit: No split region yet for drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    return;
+  }
+  else if (pResource -> commit == 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentValidateSplit: WARNING! Split for drawable at [%p] was "
+                "already invalidated.\n", (void *) pDrawable);
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+
+  fprintf(stderr, "nxagentValidateSplit: Going to validate resource [%d] drawable at [%p].\n",
+              pResource -> split, (void *) pDrawable);
+
+  nxagentCheckSplit(pDrawable, pResource);
+
+  #endif
+  
+  #ifdef TEST
+  fprintf(stderr, "nxagentValidateSplit: Checking the region for resource [%d] "
+              "and drawable at [%p].\n", pResource -> split, (void *) pDrawable);
+  #endif
+
+  /*
+   * If a null region is passed as parameter,
+   * we assume that all the commits have to
+   * be discarded.
+   */
+
+  if (pRegion == NullRegion)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentValidateSplit: Forcing all commits as invalid for "
+                "drawable at [%p].\n", (void *) pDrawable);
+    #endif
+
+    nxagentReleaseSplit(pDrawable);
+  }
+  else
+  {
+    RegionRec tmpRegion;
+
+    /*
+     * Check if the provided region overlaps
+     * the area covered by the image being
+     * streamed.
+     */
+
+    REGION_INIT(pDrawable -> pScreen, &tmpRegion, NullBox, 1);
+
+    REGION_INTERSECT(pDrawable -> pScreen, &tmpRegion, pResource -> region, pRegion);
+
+    if (REGION_NIL(&tmpRegion) == 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentValidateSplit: Marking the overlapping commits as invalid "
+                  "for drawable at [%p].\n", (void *) pDrawable);
+      #endif
+
+      nxagentReleaseSplit(pDrawable);
+    }
+    #ifdef TEST
+    else
+    {
+      fprintf(stderr, "nxagentValidateSplit: Leaving the commits as valid for "
+                  "drawable at [%p].\n", (void *) pDrawable);
+    }
+    #endif
+
+    REGION_UNINIT(pDrawable -> pScreen, &tmpRegion);
+  }
+}
+
+void nxagentFreeSplit(int resource)
+{
+  DrawablePtr pDrawable;
+
+  SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+  if (pResource == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentFreeSplit: PANIC! No valid split record for resource [%d].\n",
+                resource);
+    #endif
+
+    FatalError("nxagentFreeSplit: PANIC! No valid split record for resource [%d].\n",
+                   resource);
+  }
+  else if (pResource -> split != resource)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentFreeSplit: PANIC! The record [%d] doesn't match the resource [%d].\n",
+                pResource -> split, resource);
+    #endif
+
+    FatalError("nxagentFreeSplit: PANIC! The record [%d] doesn't match the resource [%d].\n",
+                   pResource -> split, resource);
+  }
+
+  pDrawable = pResource -> drawable;
+
+  if (pDrawable != NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentFreeSplit: Removing association to drawable at [%p].\n",
+                (void *) pDrawable);
+    #endif
+
+    nxagentReleaseSplit(pDrawable);
+  }
+  #ifdef TEST
+  else
+  {
+    /*
+     * The end of the split has come after we have
+     * invalidated the operation and removed the
+     * association to the drawable. This happens,
+     * for example, if the drawable is destroyed.
+     */
+
+    fprintf(stderr, "nxagentFreeSplit: WARNING! Releasing invalidated resource [%d].\n",
+                pResource -> split);
+  }
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentFreeSplit: Freeing the record for resource [%d].\n",
+              pResource -> split);
+  #endif
+
+  nxagentFreeSplitResource(pResource);
+}
+
+/*
+FIXME: This must be enabled when the vanilla
+       synchronization procedure is working.
+*/
+#define USE_FINISH_SPLIT
+
+void nxagentWaitDrawable(DrawablePtr pDrawable)
+{
+  SplitResourcePtr pResource;
+
+  pDrawable = nxagentSplitDrawable(pDrawable);
+
+  pResource = nxagentSplitResource(pDrawable);
+
+  if (pResource == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "++++++nxagentWaitDrawable: WARNING! The drawable at [%p] is already awake.\n",
+	    (void *) pDrawable);
+    #endif
+
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "++++++nxagentWaitDrawable: Waiting drawable at [%p] with resource [%d].\n",
+              (void *) pDrawable, pResource -> split);
+  #endif
+
+  /*
+   * Be sure we intercept an I/O error
+   * as well as an interrupt.
+   */
+
+  #ifdef USE_FINISH_SPLIT
+
+  NXFinishSplit(nxagentDisplay, pResource -> split);
+
+  #endif
+
+  NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+  for (;;)
+  {
+    /*
+     * Handling all the possible events here
+     * preempts the queue and makes a better
+     * use of the link.
+     *
+     * We should better use XIfEvent() instead
+     * of looping again and again through the
+     * event queue.
+     */
+
+    nxagentDispatchEvents(NULL);
+
+    /*
+     * Wait indefinitely until the resource
+     * is released or the display is shut
+     * down.
+     */
+
+    if (nxagentSplitResource(pDrawable) == NULL ||
+            NXDisplayError(nxagentDisplay) == 1)
+    {
+      #ifdef TEST
+
+      if (NXDisplayError(nxagentDisplay) == 1)
+      {
+        fprintf(stderr, "++++++nxagentWaitDrawable: WARNING! Display error detected while "
+                    "waiting for the drawable.\n");
+      }
+      else
+      {
+        fprintf(stderr, "++++++nxagentWaitDrawable: Drawable at [%p] can now be restarted.\n",
+		(void *) pDrawable);
+      }
+
+      #endif
+ 
+      return;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "++++++nxagentWaitDrawable: Yielding control to the NX transport.\n");
+    #endif
+
+    nxagentWaitEvents(nxagentDisplay, NULL);
+  }
+}
+
+static Bool nxagentCommitSplitPredicate(Display *display, XEvent *event, XPointer ptr)
+{
+  return (event -> type == ClientMessage &&
+              event -> xclient.data.l[0] == NXCommitSplitNotify &&
+                  event -> xclient.window == 0 && event -> xclient.message_type == 0 &&
+                      event -> xclient.format == 32);
+}
+
+void nxagentWaitCommitEvent(int resource)
+{
+  XEvent event;
+
+  /*
+   * Check if there is any commit pending. As
+   * we are at it, handle any commit, even those
+   * commits pertaining to other resources.
+   *
+   * We can receive some commits even if we'll
+   * later receive a no-split event. The proxy,
+   * in fact, may have missed to find the image
+   * in the memory cache and could have loaded it
+   * from disk (so requiring a commit) before we
+   * marked the end of the split sequence.
+   */
+
+  while (nxagentCheckEvents(nxagentDisplay, &event,
+                                nxagentCommitSplitPredicate, NULL) == 1)
+  {
+    int client   = event.xclient.data.l[1];
+    int request  = event.xclient.data.l[2];
+    int position = event.xclient.data.l[3];
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentWaitCommitEvent: Commit event received with "
+                "client [%d] request [%d] and position [%d].\n",
+                    client, request, position);
+    #endif
+
+    nxagentHandleCommitSplitEvent(client, request, position);
+  }
+}
+
+static Bool nxagentWaitSplitPredicate(Display *display, XEvent *event, XPointer ptr)
+{
+  return (event -> type == ClientMessage &&
+              (event -> xclient.data.l[0] == NXNoSplitNotify ||
+                  event -> xclient.data.l[0] == NXStartSplitNotify) &&
+                      event -> xclient.window == 0 && event -> xclient.message_type == 0 &&
+                          event -> xclient.format == 32);
+}
+
+int nxagentWaitSplitEvent(int resource)
+{
+  XEvent event;
+
+  int split = 0;
+
+  /*
+   * Don't flush the link. We only want to
+   * query the NX transport to check whether
+   * the operation caused a split.
+   */
+
+  NXFlushDisplay(nxagentDisplay, NXFlushBuffer);
+
+  for (;;)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentWaitSplitEvent: Waiting for the split event for resource [%d].\n",
+                resource);
+    #endif
+
+    XIfEvent(nxagentDisplay, &event, nxagentWaitSplitPredicate, NULL);
+
+    if (NXDisplayError(nxagentDisplay) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentWaitSplitEvent: WARNING! Error detected reading the event.\n");
+      #endif
+
+      nxagentHandleNoSplitEvent(resource);
+
+      break;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentWaitSplitEvent: Going to process the split event.\n");
+    #endif
+
+    if (resource != (int) event.xclient.data.l[1])
+    {
+      #ifdef PANIC
+      fprintf(stderr, "nxagentWaitSplitEvent: PANIC! Got event for resource [%d] while "
+                  "waiting for resource [%d].\n", (int) event.xclient.data.l[1], resource);
+
+      fprintf(stderr, "nxagentWaitSplitEvent: PANIC! Restarting resource [%d] due to the "
+                  "missing split event.\n", resource);
+      #endif
+
+      nxagentHandleNoSplitEvent(resource);
+
+      break;
+    }
+    else if (event.xclient.data.l[0] == NXNoSplitNotify)
+    {
+      nxagentHandleNoSplitEvent(resource);
+
+      break;
+    }
+    else
+    {
+      nxagentHandleStartSplitEvent(resource);
+
+      split = 1;
+
+      break;
+    }
+  }
+
+  return split;
+}
+
+void nxagentHandleNoSplitEvent(int resource)
+{
+  if (resource >= 0 && resource < NXNumberOfResources)
+  {
+    #ifdef TEST
+
+    SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+    fprintf(stderr, "nxagentHandleNoSplitEvent: Received event for resource [%d].\n",
+                resource);
+
+    nxagentCheckResource(pResource, resource);
+
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleNoSplitEvent: Checking if there is any commit pending.\n");
+    #endif
+
+    nxagentWaitCommitEvent(resource);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleNoSplitEvent: No streaming was required with resource [%d] "
+                "and drawable at [%p].\n", resource, (void *) pResource -> drawable);
+    #endif
+
+    /*
+     * Release the resource.
+     */
+
+    nxagentFreeSplit(resource);
+  }
+  #ifdef PANIC
+  else
+  {
+    fprintf(stderr, "nxagentHandleNoSplitEvent: PANIC! Invalid resource identifier [%d] "
+                " received in event.\n", resource);
+  }
+  #endif
+}
+
+void nxagentHandleStartSplitEvent(int resource)
+{
+  if (resource >= 0 && resource < NXNumberOfResources)
+  {
+    #ifdef TEST
+
+    SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+    fprintf(stderr, "nxagentHandleStartSplitEvent: Received event for resource [%d].\n",
+                resource);
+
+    nxagentCheckResource(pResource, resource);
+
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleStartSplitEvent: Checking if there is any commit pending.\n");
+    #endif
+
+    nxagentWaitCommitEvent(resource);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleStartSplitEvent: Streaming started with resource [%d] "
+                "and drawable at [%p].\n", resource, (void *) pResource -> drawable);
+    #endif
+  }
+  #ifdef PANIC
+  else
+  {
+    fprintf(stderr, "nxagentHandleStartSplitEvent: PANIC! Invalid resource identifier [%d] "
+                " received in event.\n", resource);
+  }
+  #endif
+}
+
+void nxagentHandleCommitSplitEvent(int resource, int request, int position)
+{
+  if (resource >= 0 && resource < NXNumberOfResources &&
+          request >= 0 && position >= 0)
+  {
+    SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleCommitSplitEvent: Received event for resource [%d].\n",
+                resource);
+    #endif
+
+    if (pResource != NULL && pResource -> commit == 1)
+    {
+      #ifdef TEST
+
+      nxagentCheckResource(pResource, resource);
+
+      fprintf(stderr, "nxagentHandleCommitSplitEvent: Committing request [%d] with "
+                  "position [%d] for resource [%d].\n", request, position, resource);
+
+      #endif
+
+      NXCommitSplit(nxagentDisplay, resource, 1, request, position);
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleCommitSplitEvent: Discarding request [%d] for "
+                  "resource [%d] with position [%d].\n", request, resource, position);
+      #endif
+
+      NXCommitSplit(nxagentDisplay, resource, 0, request, position);
+    }
+  }
+  #ifdef PANIC
+  else
+  {
+    fprintf(stderr, "nxagentHandleCommitSplitEvent: PANIC! Invalid commit event with "
+                "request [%d] and position [%d] for resource [%d].\n", request,
+                    position, resource);
+  }
+  #endif
+}
+
+void nxagentHandleEndSplitEvent(int resource)
+{
+  if (resource >= 0 && resource < NXNumberOfResources)
+  {
+    SplitResourcePtr pResource = &nxagentSplitResources[resource];
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleEndSplitEvent: Received event for resource [%d].\n",
+                resource);
+
+    nxagentCheckResource(pResource, resource);
+
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentHandleEndSplitEvent: Checking if there is any commit pending.\n");
+    #endif
+
+    nxagentWaitCommitEvent(resource);
+
+    if (pResource != NULL && pResource -> commit == 1)
+    {
+      #ifdef TEST
+
+      fprintf(stderr, "nxagentHandleEndSplitEvent: Checking the split region at [%p] "
+                  "for drawable at [%p].\n", (void *) pResource -> drawable,
+                      (void *) pResource -> region);
+
+      if (pResource -> region == NULL)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! Invalid region [%p] for drawable at [%p].\n",
+                    (void *) pResource -> region, (void *) pResource -> drawable);
+        #endif
+
+        FatalError("nxagentHandleEndSplitEvent: PANIC! Invalid region [%p] for drawable at [%p].\n",
+                       (void *) pResource -> region, (void *) pResource -> drawable);
+      }
+      else if (pResource -> gc == NULL)
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! Invalid GC [%p] for drawable at [%p].\n",
+                    (void *) pResource -> gc, (void *) pResource -> drawable);
+        #endif
+
+        FatalError("nxagentHandleEndSplitEvent: PANIC! Invalid GC [%p] for drawable at [%p].\n",
+                       (void *) pResource -> gc, (void *) pResource -> drawable);
+      }
+
+      #endif
+
+      if (pResource -> drawable != NULL &&
+              pResource -> region != NullRegion)
+      {
+        if (REGION_NIL(pResource -> region) == 0)
+        {
+          REGION_SUBTRACT(pResource -> drawable -> pScreen,
+                              nxagentCorruptedRegion(pResource -> drawable),
+                                  nxagentCorruptedRegion(pResource -> drawable),
+                                      pResource -> region);
+
+/*
+FIXME: Implementing the valid region policy
+
+          nxagentExpandValidRegion(pResource -> drawable, pResource -> region);
+*/
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentHandleEndSplitEvent: Synchronized region [%d,%d,%d,%d] "
+                      "for drawable at [%p].\n", pResource -> region -> extents.x1,
+                          pResource -> region -> extents.y1, pResource -> region -> extents.x2,
+                              pResource -> region -> extents.y2, (void *) pResource -> drawable);
+          #endif
+        }
+        else
+        {
+          #ifdef PANIC
+          fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! The region [%d,%d,%d,%d] for drawable "
+                      "at [%p] is empty.\n", pResource -> region -> extents.x1,
+                          pResource -> region -> extents.y1, pResource -> region -> extents.x2,
+                              pResource -> region -> extents.y2, (void *) pResource -> drawable);
+          #endif
+
+          FatalError("nxagentHandleEndSplitEvent: PANIC! The region [%d,%d,%d,%d] for drawable "
+                      "at [%p] is empty.\n", pResource -> region -> extents.x1,
+                          pResource -> region -> extents.y1, pResource -> region -> extents.x2,
+                              pResource -> region -> extents.y2, (void *) pResource -> drawable);
+        }
+      }
+      else
+      {
+        #ifdef PANIC
+        fprintf(stderr, "nxagentHandleEndSplitEvent: PANIC! Invalid record for resource [%d] with "
+                    "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                        resource, pResource -> pending, pResource -> split, pResource -> unpack,
+                            (void *) pResource -> drawable, (void *) pResource -> region,
+                                pResource -> commit, (void *) pResource -> gc);
+        #endif
+
+        FatalError("nxagentHandleEndSplitEvent: PANIC! Invalid record for resource [%d] with "
+                       "pending [%d] split [%d] unpack [%d] drawable [%p] region [%p] commit [%d] gc [%p].\n",
+                           resource, pResource -> pending, pResource -> split, pResource -> unpack,
+                               (void *) pResource -> drawable, (void *) pResource -> region,
+                                    pResource -> commit, (void *) pResource -> gc);
+      }
+    }
+
+    /*
+     * Release the resource.
+     */
+
+    nxagentFreeSplit(resource);
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentHandleEndSplitEvent: WARNING! Ignoring split event "
+                "for resource [%d].\n", resource);
+  }
+  #endif
+}
+
+void nxagentHandleEmptySplitEvent()
+{
+/*
+FIXME: Should run a consistency check here.
+*/
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleEmptySplitEvent: No more split event to handle.\n");
+  #endif
+}
+
+/*
+ * The drawable is going to become corrupted.
+ */
+
+void nxagentSetCorruptedTimestamp(DrawablePtr pDrawable)
+{
+  if (nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    if (pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSetCorruptedTimestamp: Corruption timestamp for pixmap at [%p] was [%lu].\n",
+                  (void *) pDrawable, nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp);
+      #endif
+
+      nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp = GetTimeInMillis();
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentSetCorruptedTimestamp: New corruption timestamp for pixmap at [%p] is [%lu].\n",
+                  (void *) pDrawable, nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp);
+      #endif
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSetCorruptedTimestamp: Corruption timestamp for window at [%p] was [%lu].\n",
+                  (void *) pDrawable, nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp);
+      #endif
+
+      nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp = GetTimeInMillis();
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentSetCorruptedTimestamp: New corruption timestamp for window at [%p] is [%lu].\n",
+                  (void *) pDrawable, nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp);
+      #endif
+    }
+  }
+}
+
+/*
+ * Reset the timestamp taken when the drawable
+ * became initially corrupted. The timestamp is
+ * reset only after the drawable has been fully
+ * synchronized.
+ */
+
+void nxagentResetCorruptedTimestamp(DrawablePtr pDrawable)
+{
+  if (nxagentDrawableStatus(pDrawable) == Synchronized)
+  {
+    if (pDrawable -> type == DRAWABLE_PIXMAP)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentResetCorruptedTimestamp: Corruption timestamp for pixmap at [%p] was [%lu].\n",
+                  (void *) pDrawable, nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp);
+      #endif
+
+      nxagentPixmapPriv((PixmapPtr) pDrawable) -> corruptedTimestamp = 0;
+    }
+    else
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentResetCorruptedTimestamp: Corruption timestamp for window at [%p] was [%lu].\n",
+                  (void *) pDrawable, nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp);
+      #endif
+
+      nxagentWindowPriv((WindowPtr) pDrawable) -> corruptedTimestamp = 0;
+    }
+  }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.h b/nx-X11/programs/Xserver/hw/nxagent/Split.h
new file mode 100644
index 000000000..397feef16
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.h
@@ -0,0 +1,84 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Split_H__
+#define __Split_H__
+
+typedef struct _SplitResourceRec
+{
+  int         pending;
+  int         split;
+  int         unpack;
+  DrawablePtr drawable;
+  RegionPtr   region;
+  GCPtr       gc;
+  int         commit;
+
+} SplitResourceRec;
+
+typedef SplitResourceRec *SplitResourcePtr;
+
+extern SplitResourceRec nxagentSplitResources[];
+
+typedef struct _UnpackResourceRec
+{
+  int         pending;
+  int         unpack;
+  DrawablePtr drawable;
+
+} UnpackResourceRec;
+
+typedef UnpackResourceRec *UnpackResourcePtr;
+
+extern UnpackResourceRec nxagentUnpackResources[];
+
+void nxagentInitSplitResources();
+void nxagentInitUnpackResources();
+
+SplitResourcePtr nxagentAllocSplitResource();
+void nxagentFreeSplitResource(SplitResourcePtr pResource);
+
+UnpackResourcePtr nxagentAllocUnpackResource();
+void nxagentFreeUnpackResource(UnpackResourcePtr pResource);
+
+#define nxagentSplitResource(pDrawable) \
+    ((pDrawable) -> type == DRAWABLE_PIXMAP ? \
+        (nxagentPixmapPriv(nxagentRealPixmap((PixmapPtr) pDrawable)) -> splitResource) : \
+            (nxagentWindowPriv((WindowPtr) pDrawable) -> splitResource))
+
+/*
+FIXME: Make it a real function to log a warning
+       in the logs.
+
+#define nxagentSplitDrawable(pDrawable) \
+    (((pDrawable) -> type == DRAWABLE_PIXMAP && \
+         nxagentPixmapIsVirtual((PixmapPtr) pDrawable)) ? \
+             (DrawablePtr) nxagentRealPixmap((PixmapPtr) pDrawable) : pDrawable)
+*/
+DrawablePtr nxagentSplitDrawable(DrawablePtr pDrawable);
+
+int nxagentCreateSplit(DrawablePtr pDrawable, GCPtr *pGC);
+void nxagentRegionSplit(DrawablePtr pDrawable, RegionPtr pRegion);
+void nxagentValidateSplit(DrawablePtr pDrawable, RegionPtr pRegion);
+void nxagentReleaseSplit(DrawablePtr pDrawable);
+
+void nxagentReleaseAllSplits(void);
+
+void nxagentSetCorruptedTimestamp(DrawablePtr pDrawable);
+void nxagentResetCorruptedTimestamp(DrawablePtr pDrawable);
+
+#endif /* __Split_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
new file mode 100644
index 000000000..704c63e51
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
@@ -0,0 +1,83 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xlib.h>
+#undef Bool
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "mipointer.h"
+#define XTestSERVER_SIDE
+#include "xtestext1.h"
+
+extern CARD32 nxagentLastEventTime;
+
+void XTestGetPointerPos(short *fmousex, short *fmousey);
+
+void XTestJumpPointer(int jx, int jy, int dev_type);
+
+void XTestGenerateEvent(int dev_type, int keycode, int keystate,
+                            int mousex, int mousey);
+
+void XTestGetPointerPos(short *fmousex, short *fmousey)
+{
+  int x,y;
+  
+  miPointerPosition(&x, &y);
+  *fmousex = x;
+  *fmousey = y;
+}
+
+void XTestJumpPointer(int jx, int jy, int dev_type)
+{
+  miPointerAbsoluteCursor(jx, jy, GetTimeInMillis());
+}
+
+void XTestGenerateEvent(int dev_type, int keycode, int keystate,
+                            int mousex, int mousey)
+{
+/*
+  xEvent tevent;
+  
+  tevent.u.u.type = (dev_type == XE_POINTER) ?
+    (keystate == XTestKEY_UP) ? ButtonRelease : ButtonPress :
+      (keystate == XTestKEY_UP) ? KeyRelease : KeyPress;
+  tevent.u.u.detail = keycode;
+  tevent.u.keyButtonPointer.rootX = mousex;
+  tevent.u.keyButtonPointer.rootY = mousey;
+  tevent.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+  mieqEnqueue(&tevent);
+*/
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
new file mode 100644
index 000000000..3b801d803
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -0,0 +1,99 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include "Trap.h"
+
+/*
+ * Set if we are dispatching a render
+ * extension request. Used to avoid
+ * reentrancy in GC operations.
+ */
+
+int nxagentGCTrap = 0;
+
+/*
+ * Set if we are enqueing an internal
+ * operation, CreateWindow and Reparent-
+ * Window. Used to remove any screen operation.
+ */
+
+int nxagentScreenTrap = 0;
+
+/*
+ * Set if we detected that our RENDER
+ * implementation is faulty.
+ */
+
+int nxagentRenderTrap = 0;
+
+/*
+ * Set if we are executing a GC operation
+ * only on the X side. Used to avoid
+ * reentrancy in FB layer.
+ */
+
+int nxagentFBTrap = 0;
+
+/*
+ * Set if we are dispatching a shared
+ * memory extension request.
+ */
+
+int nxagentShmTrap = 0;
+
+/*
+ * Set if a shared pixmap operation is
+ * requested by the client.
+ */
+
+int nxagentShmPixmapTrap = 0;
+
+/*
+ * Set if we are dispatching a XVideo
+ * extension request.
+ */
+
+int nxagentXvTrap = 0;
+
+/*
+ * Set if we are dispatching a GLX
+ * extension request.
+ */
+
+int nxagentGlxTrap = 0;
+
+/*
+ * Set while we are resuming the session.
+ */
+
+int nxagentReconnectTrap = 0;
+
+/*
+ * Set if we need to realize a drawable
+ * by using a lossless encoding.
+ */
+
+int nxagentLosslessTrap = 0;
+
+/*
+ * Set to force the synchronization of
+ * a drawable.
+ */
+
+int nxagentSplitTrap = 0;
+
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
new file mode 100644
index 000000000..f699306ab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -0,0 +1,100 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Traps_H__
+#define __Traps_H__
+
+/*
+ * Set if we are dispatching a render
+ * extension request. Used to avoid
+ * reentrancy in GC operations.
+ */
+
+extern int nxagentGCTrap;
+
+/*
+ * Set if we are enqueing an internal
+ * operation, CreateWindow and Reparent-
+ * Window. Used to remove any screen operation.
+ */
+
+extern int nxagentScreenTrap;
+
+/*
+ * Set if we detected that our RENDER
+ * implementation is faulty.
+ */
+
+extern int nxagentRenderTrap;
+
+/*
+ * Set if we are executing a GC operation
+ * only on the X side. Used to avoid
+ * reentrancy in FB layer.
+ */
+
+extern int nxagentFBTrap;
+
+/*
+ * Set if we are dispatching a shared
+ * memory extension request.
+ */
+
+extern int nxagentShmTrap;
+
+/*
+ * Set if a shared pixmap operation is
+ * requested by the client.
+ */
+
+extern int nxagentShmPixmapTrap;
+
+/*
+ * Set if we are dispatching a XVideo
+ * extension request.
+ */
+
+extern int nxagentXvTrap;
+
+/*
+ * Set if we are dispatching a GLX
+ * extension request.
+ */
+
+extern int nxagentGlxTrap;
+
+/*
+ * Set while we are resuming the session.
+ */
+
+extern int nxagentReconnectTrap;
+
+/*
+ * Set if we need to realize a drawable
+ * by using a lossless encoding.
+ */
+
+extern int nxagentLosslessTrap;
+
+/*
+ * Set to force the synchronization of
+ * a drawable.
+ */
+
+extern int nxagentSplitTrap;
+
+#endif /* __Trap_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Utils.h b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
new file mode 100644
index 000000000..9334a7868
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
@@ -0,0 +1,39 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Utils_H__
+#define __Utils_H__
+
+/*
+ * Number of bits in fixed point operations.
+ */
+
+#define PRECISION  16
+
+/*
+ * "1" ratio means "don't scale".
+ */
+
+#define DONT_SCALE  (1 << PRECISION)
+
+#define nxagentScale(i, ratio) (((i) * (ratio)) >> (PRECISION))
+
+#ifndef MIN
+#define MIN(A, B) ( (A) < (B) ? (A) : (B) )
+#endif
+
+#endif /* __Utils_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.c b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
new file mode 100644
index 000000000..2a8283a30
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
@@ -0,0 +1,159 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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 "scrnintstr.h"
+#include "dix.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "resource.h"
+
+#include "X.h"
+#include "Xproto.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Visual.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Predefined visual used for drawables
+ * having a 32 bits depth.
+ */
+
+Visual nxagentAlphaVisual;
+
+Visual *nxagentVisual(VisualPtr pVisual)
+{
+  XVisualInfo visual;
+
+  int i;
+
+  visual.class = pVisual->class;
+  visual.bits_per_rgb = pVisual->bitsPerRGBValue;
+  visual.colormap_size = pVisual->ColormapEntries;
+  visual.depth = pVisual->nplanes;
+  visual.red_mask = pVisual->redMask;
+  visual.green_mask = pVisual->greenMask;
+  visual.blue_mask = pVisual->blueMask;
+
+  for (i = 0; i < nxagentNumVisuals; i++)
+  {
+    if (nxagentCompareVisuals(visual, nxagentVisuals[i]) == 1)
+    {
+      return nxagentVisuals[i].visual;
+    }
+  }
+
+  return NULL;
+}
+
+Visual *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual)
+{
+  int i;
+
+  for (i = 0; i < pScreen->numVisuals; i++)
+  {
+    if (pScreen->visuals[i].vid == visual)
+    {
+      return nxagentVisual(&pScreen->visuals[i]);
+    }
+  }
+  
+  return NULL;
+}
+
+Colormap nxagentDefaultVisualColormap(Visual *visual)
+{
+  int i;
+
+  for (i = 0; i < nxagentNumVisuals; i++)
+  {
+    if (nxagentVisuals[i].visual == visual)
+    {
+      return nxagentDefaultColormaps[i];
+    }
+  }
+
+  return None;
+}
+
+/*
+ * This is currently unused. It should serve
+ * the scope of matching a visual whenever
+ * a drawable has a different depth than the
+ * real display.
+ */
+
+Visual *nxagentVisualFromDepth(ScreenPtr pScreen, int depth)
+{
+  int i;
+
+  for (i = 0; i < pScreen->numVisuals; i++)
+  {
+    if (pScreen->visuals[i].nplanes == depth)
+    {
+      return nxagentVisual(&pScreen->visuals[i]);
+    }
+  }
+
+  return NULL;
+}
+
+/*
+ * Create a fake 32 bits depth visual and
+ * initialize it based on the endianess
+ * of the remote display.
+ */
+
+void nxagentInitAlphaVisual()
+{
+  nxagentAlphaVisual.visualid = XAllocID(nxagentDisplay);
+
+  /*
+   * Color masks are referred to bits inside
+   * the pixel. This is independent from the
+   * endianess.
+   */
+
+  nxagentAlphaVisual.red_mask   = 0x00ff0000;
+  nxagentAlphaVisual.green_mask = 0x0000ff00;
+  nxagentAlphaVisual.blue_mask  = 0x000000ff;
+
+  #ifdef TEST
+  fprintf(stderr,"nxagentInitAlphaVisual: Set alpha visual with id [0x%lx] mask [0x%lx,0x%lx,0x%lx].\n",
+              nxagentAlphaVisual.visualid, nxagentAlphaVisual.red_mask,
+                  nxagentAlphaVisual.green_mask, nxagentAlphaVisual.blue_mask);
+  #endif
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.h b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
new file mode 100644
index 000000000..6d8a8742d
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
@@ -0,0 +1,73 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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.
+
+*/
+
+#ifndef __Visual_H__
+#define __Visual_H__
+
+Visual *nxagentVisual(VisualPtr pVisual);
+Visual *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
+Visual *nxagentVisualFromDepth(ScreenPtr pScreen, int depth);
+
+Colormap nxagentDefaultVisualColormap(Visual *visual);
+
+#define nxagentDefaultVisual(pScreen) \
+    nxagentVisualFromID((pScreen), (pScreen) -> rootVisual)
+
+/*
+ * Visual generated by Xorg and Xfree86 at
+ * 16-bit depth differs on the bits_per_rgb
+ * value, so we avoid checking it.
+ */
+
+/*
+ * Some Solaris X servers uses the color
+ * masks inverted, so that the red and
+ * the blue mask are switched. To reconnect
+ * the session on this displays, we do a
+ * double check, as workaround.
+ */
+
+#define nxagentCompareVisuals(v1, v2)           \
+    ((v1).depth         == (v2).depth &&        \
+     /*(v1).bits_per_rgb  == (v2).bits_per_rgb &&*/ \
+     (v1).class         == (v2).class &&        \
+     ((v1).red_mask      == (v2).red_mask ||    \
+      (v1).red_mask      == (v2).blue_mask) &&  \
+     (v1).green_mask    == (v2).green_mask &&   \
+     ((v1).blue_mask     == (v2).blue_mask ||   \
+      (v1).blue_mask     == (v2).red_mask) &&   \
+     (v1).colormap_size == (v2).colormap_size)
+
+Visual nxagentAlphaVisual;
+
+void nxagentInitAlphaVisual();
+
+#endif /* __Visual_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
new file mode 100644
index 000000000..ff775f272
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -0,0 +1,3614 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#include <unistd.h>
+
+#include "X.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "../../include/window.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "region.h"
+#include "dixstruct.h"
+#include "selection.h"
+#include "mi.h"
+#include "fb.h"
+#include "mibstorest.h"
+
+#include "Agent.h"
+#include "Display.h"
+#include "Screen.h"
+#include "GCs.h"
+#include "GCOps.h"
+#include "Drawable.h"
+#include "Colormap.h"
+#include "Cursor.h"
+#include "Visual.h"
+#include "Events.h"
+#include "Clipboard.h"
+#include "Args.h"
+#include "Trap.h"
+#include "Rootless.h"
+#include "Atoms.h"
+#include "Client.h"
+#include "Reconnect.h"
+#include "Dialog.h"
+#include "Splash.h"
+#include "Holder.h"
+#include "Init.h"
+#include "Composite.h"
+#include "Events.h"
+
+#include "NX.h"
+#include "NXlib.h"
+
+#include "Xatom.h"
+
+/*
+ * Used to register the window's privates.
+ */
+
+int nxagentWindowPrivateIndex;
+
+/*
+ * Number of windows which need synchronization.
+ */
+
+int nxagentCorruptedWindows;
+
+/*
+ * Used to track nxagent window's visibility.
+ */
+
+int nxagentVisibility = VisibilityUnobscured;
+unsigned long nxagentVisibilityTimeout = 0;
+Bool nxagentVisibilityStop = False;
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+/*
+ * Useful to test the window configuration
+ * failures.
+ */
+
+#ifdef TEST
+#define MAKE_SYNC_CONFIGURE_WINDOW  XSync(nxagentDisplay, 0)
+#else
+#define MAKE_SYNC_CONFIGURE_WINDOW
+#endif
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+extern WindowPtr nxagentRootTileWindow;
+
+/*
+ * Also referenced in Events.c.
+ */
+
+int nxagentSplashCount = 0;
+
+#define RECTLIMIT 25
+#define BSPIXMAPLIMIT 128
+
+Bool nxagentExposeArrayIsInitialized = False;
+Window nxagentConfiguredSynchroWindow;
+static int nxagentExposeSerial = 0; 
+
+StoringPixmapPtr nxagentBSPixmapList[BSPIXMAPLIMIT];
+
+/*
+ * Used to walk through the window hierarchy
+ * to find a window
+ */
+
+typedef struct _WindowMatch
+{
+  WindowPtr pWin;
+  Window    id;
+
+} WindowMatchRec;
+
+Bool nxagentReconnectAllWindows(void *);
+
+Bool nxagentDisconnectAllWindows(void);
+
+Bool nxagentIsIconic(WindowPtr);
+
+/*
+ * From NXproperty.c.
+ */
+
+int GetWindowProperty(WindowPtr, Atom, long, long, Bool, Atom, Atom*, int*,
+                                 unsigned long*, unsigned long*, unsigned char**);
+
+/*
+ * From NXwindow.c.
+ */
+
+void nxagentClearSplash(WindowPtr pWin);
+
+/*
+ * Other local functions.
+ */
+
+static Bool nxagentSomeWindowsAreMapped(void);
+
+static void nxagentFrameBufferPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
+
+static void nxagentTraverseWindow(WindowPtr, void(*)(pointer, XID, pointer), pointer);
+
+static void nxagentDisconnectWindow(pointer, XID, pointer);
+
+static Bool nxagentLoopOverWindows(void(*)(pointer, XID, pointer));
+
+static void nxagentReconfigureWindowCursor(pointer, XID, pointer);
+
+static void nxagentReconnectWindow(pointer, XID, pointer);
+
+static void nxagentReconfigureWindow(pointer, XID, pointer);
+
+static int nxagentForceExposure(WindowPtr pWin, pointer ptr);
+
+/*
+ * This is currently unused.
+ */
+
+#ifdef TEST
+
+static Bool nxagentCheckWindowIntegrity(WindowPtr pWin);
+
+#endif
+
+WindowPtr nxagentGetWindowFromID(Window id)
+{
+  WindowPtr pWin = WindowTable[0];
+
+  while (pWin && nxagentWindowPriv(pWin))
+  {
+    if (nxagentWindow(pWin) == id)
+    {
+      return pWin;
+    }
+
+    if (pWin -> nextSib)
+    {
+      pWin = pWin -> nextSib;
+    }
+    else
+    {
+      pWin = pWin -> firstChild;
+    }
+  }
+
+  return NULL;
+}
+
+static int nxagentFindWindowMatch(WindowPtr pWin, pointer ptr)
+{
+  WindowMatchRec *match = (WindowMatchRec *) ptr;
+
+  if (match -> id == nxagentWindow(pWin))
+  {
+    match -> pWin = pWin;
+
+    return WT_STOPWALKING;
+  }
+  else
+  {
+    return WT_WALKCHILDREN;
+  }
+}
+
+WindowPtr nxagentWindowPtr(Window window)
+{
+  int i;
+
+  WindowMatchRec match;
+
+  match.pWin = NullWindow;
+  match.id   = window;
+
+  for (i = 0; i < nxagentNumScreens; i++)
+  {
+    WalkTree(screenInfo.screens[i], nxagentFindWindowMatch, (pointer) &match);
+
+    if (match.pWin) break;
+  }
+
+  return match.pWin;
+}
+
+Bool nxagentCreateWindow(pWin)
+     WindowPtr pWin;
+{
+  unsigned long mask;
+  XSetWindowAttributes attributes;
+  Visual *visual;
+  ColormapPtr pCmap;
+
+  if (nxagentScreenTrap)
+  {
+    return True;
+  }
+
+  nxagentSplashCount++;
+
+  if (nxagentSplashCount == 2)
+  {
+      nxagentClearSplash(nxagentRootTileWindow);
+  }
+#ifdef NXAGENT_LOGO_DEBUG
+  fprintf(stderr, "nxagentSplashCount: %d\n", nxagentSplashCount);
+#endif
+
+  if (pWin->drawable.class == InputOnly) {
+    mask = CWEventMask;
+    visual = CopyFromParent;
+  }
+  else {
+    mask = CWEventMask | CWBackingStore;
+
+    if (pWin->optional)
+    {
+      mask |= CWBackingPlanes | CWBackingPixel;
+      attributes.backing_planes = pWin->optional->backingBitPlanes;
+      attributes.backing_pixel = pWin->optional->backingPixel;
+    }
+
+    attributes.backing_store = NotUseful;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentCreateWindow: Backing store on window at %p is %d.\n",
+                (void*)pWin, attributes.backing_store);
+    #endif
+
+/*
+FIXME: We need to set save under on the real display?
+*/
+    if (nxagentSaveUnder == True)
+      {
+        mask |= CWSaveUnder;
+        attributes.save_under = False;
+      }
+
+    if (pWin->parent) {
+      if (pWin->optional && pWin->optional->visual != wVisual(pWin->parent)) {
+        visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+        mask |= CWColormap;
+        if (pWin->optional->colormap) {
+          pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+          attributes.colormap = nxagentColormap(pCmap);
+        }
+        else
+          attributes.colormap = nxagentDefaultVisualColormap(visual);
+      }
+      else if (pWin->optional)
+       visual = CopyFromParent;
+      else {
+        visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+        mask |= CWColormap;
+        attributes.colormap = nxagentDefaultVisualColormap(visual);
+      }
+    }
+    else { /* root windows have their own colormaps at creation time */
+      visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+      pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+      mask |= CWColormap;
+      attributes.colormap = nxagentColormap(pCmap);
+    }
+  }
+
+  if (mask & CWEventMask)
+  {
+    nxagentGetEventMask(pWin, (Mask*)&attributes.event_mask);
+  }
+  #ifdef WARNING
+  else
+  {
+    attributes.event_mask = NoEventMask;
+  }
+  #endif
+
+  /*
+   * Select the event mask if window is a top level
+   * window. This at least makes the keyboard barely
+   * work.
+   */
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateWindow: Going to create new window.\n");
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateWindow: Creating %swindow at %p current event mask = %lX mask & CWEventMask = %ld "
+              "event_mask = %lX\n",
+                  nxagentWindowTopLevel(pWin) ? "toplevel " : "", (void*)pWin, pWin -> eventMask,
+                      mask & CWEventMask, attributes.event_mask);
+
+  fprintf(stderr, "nxagentCreateWindow: position [%d,%d] size [%d,%d] depth [%d] border [%d] class [%d].\n",
+              pWin->origin.x - wBorderWidth(pWin), pWin->origin.y - wBorderWidth(pWin),
+                  pWin->drawable.width, pWin->drawable.height, pWin->drawable.depth, pWin->borderWidth,
+                      pWin->drawable.class);
+  #endif
+
+  nxagentWindowPriv(pWin)->window = XCreateWindow(nxagentDisplay,
+                                                  nxagentWindowParent(pWin),
+                                                  pWin->origin.x -
+                                                  wBorderWidth(pWin),
+                                                  pWin->origin.y -
+                                                  wBorderWidth(pWin),
+                                                  pWin->drawable.width,
+                                                  pWin->drawable.height,
+                                                  pWin->borderWidth,
+                                                  pWin->drawable.depth,
+                                                  pWin->drawable.class,
+                                                  visual,
+                                                  mask, &attributes);
+
+  nxagentWindowPriv(pWin) -> isMapped = 0;
+  nxagentWindowPriv(pWin) -> isRedirected = 0;
+
+  nxagentWindowPriv(pWin) -> visibilityState = VisibilityUnobscured;
+
+  nxagentWindowPriv(pWin) -> corruptedRegion = REGION_CREATE(pWin -> drawable.pScreen, NULL, 1);
+
+  nxagentWindowPriv(pWin) -> hasTransparentChildren = 0;
+
+  nxagentWindowPriv(pWin) -> containGlyphs = 0;
+
+  nxagentWindowPriv(pWin) -> corruptedId = 0;
+
+  nxagentWindowPriv(pWin) -> deferredBackgroundExpose = 0;
+
+  nxagentWindowPriv(pWin) -> synchronizationBitmap = NullPixmap;
+
+  nxagentWindowPriv(pWin) -> corruptedTimestamp = 0;
+
+  nxagentWindowPriv(pWin) -> splitResource = NULL;
+
+  if (nxagentOption(Rootless) == 1)
+  {
+    if (pWin != nxagentRootlessWindow)
+    {
+      WindowPtr pParent = pWin -> parent;
+
+      if (pParent && nxagentWindowPriv(pParent) -> isMapped == 1)
+      {
+        nxagentWindowPriv(pWin) -> isMapped = 1;
+      }
+      else
+      {
+        nxagentWindowPriv(pWin) -> isMapped = 0;
+      }
+    }
+    else
+    {
+      nxagentWindowPriv(pWin) -> isMapped = 0;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateWindow: Created new window with id [%ld].\n",
+              nxagentWindowPriv(pWin)->window);
+  #endif
+
+  /*
+   * Set the WM_DELETE_WINDOW protocols on every
+   * top level window. Also redirect the window
+   * if it is a top level.
+   */
+
+  if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin))
+  {
+    Atom prop = nxagentMakeAtom("WM_PROTOCOLS", strlen("WM_PROTOCOLS"), True);
+
+    XlibAtom atom = nxagentMakeAtom("WM_DELETE_WINDOW", strlen("WM_DELETE_WINDOW"), True);
+
+    XSetWMProtocols(nxagentDisplay, nxagentWindowPriv(pWin)->window, &atom, 1);
+
+    nxagentAddPropertyToList(prop, pWin);
+
+    /*
+     * Redirect the window to the off-screen
+     * memory, if the composite extension is
+     * supported on the display.
+     */
+/*
+FIXME: Do all the windows for which nxagentWindowTopLevel(pWin)
+       returns true need to be redirected?
+*/
+    nxagentRedirectWindow(pWin);
+  }
+
+  nxagentWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
+  nxagentWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
+  nxagentWindowPriv(pWin)->width = pWin->drawable.width;
+  nxagentWindowPriv(pWin)->height = pWin->drawable.height;
+  nxagentWindowPriv(pWin)->borderWidth = pWin->borderWidth;
+  nxagentWindowPriv(pWin)->siblingAbove = None;
+  nxagentWindowPriv(pWin)->pPicture = NULL;
+
+  if (nxagentRootTileWindow)
+  {
+    if (nxagentWindowPriv(pWin)->window != nxagentWindowPriv(nxagentRootTileWindow)->window)
+    {
+      XClearWindow(nxagentDisplay, nxagentWindowPriv(nxagentRootTileWindow)->window);
+    }
+  }
+
+  if (pWin->nextSib)
+  {
+    nxagentWindowPriv(pWin->nextSib)->siblingAbove = nxagentWindow(pWin);
+  }
+
+#ifdef NXAGENT_SHAPE2
+#ifdef SHAPE
+  nxagentWindowPriv(pWin)->boundingShape = NULL;
+  nxagentWindowPriv(pWin)->clipShape = NULL;
+#endif /* SHAPE */
+#else
+#ifdef SHAPE
+  nxagentWindowPriv(pWin)->boundingShape = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+  nxagentWindowPriv(pWin)->clipShape = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+#endif /* SHAPE */
+#endif
+
+  fbCreateWindow(pWin);
+
+  /*
+   * Only the root window will have
+   * the right colormap.
+   */
+
+  if (!pWin->parent)
+  {
+    nxagentSetInstalledColormapWindows(pWin->drawable.pScreen);
+  }
+
+  return True;
+}
+
+Bool nxagentSomeWindowsAreMapped()
+{
+  WindowPtr pWin = WindowTable[0] -> firstChild;
+
+  while (pWin)
+  {
+    if ((pWin -> mapped || nxagentIsIconic(pWin)) &&
+            pWin -> drawable.class == InputOutput)
+    {
+      return True;
+    }
+
+    pWin = pWin -> nextSib;
+  }
+
+  return False;
+}
+
+Bool nxagentDestroyWindow(WindowPtr pWin)
+{
+  int i;
+  int j;
+
+  nxagentPrivWindowPtr pWindowPriv;
+
+  if (nxagentScreenTrap == 1)
+  {
+    return 1;
+  }
+
+  nxagentClearClipboard(NULL, pWin);
+
+  for (j = 0; j < nxagentExposeQueue.length; j++)
+  {
+    i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+    if (nxagentExposeQueue.exposures[i].pWindow == pWin)
+    {
+      if (nxagentExposeQueue.exposures[i].localRegion != NullRegion)
+      {
+        REGION_DESTROY(pWin -> drawable.pScreen, nxagentExposeQueue.exposures[i].localRegion);
+      }
+
+      nxagentExposeQueue.exposures[i].localRegion = NullRegion;
+
+      if (nxagentExposeQueue.exposures[i].remoteRegion != NullRegion)
+      {
+        REGION_DESTROY(pWin -> drawable.pScreen, nxagentExposeQueue.exposures[i].remoteRegion);
+      }
+
+      nxagentExposeQueue.exposures[i].remoteRegion = NullRegion;
+    }
+  }
+
+  nxagentDeleteConfiguredWindow(pWin);
+
+  pWindowPriv = nxagentWindowPriv(pWin);
+
+  if (pWin->nextSib)
+  {
+    nxagentWindowPriv(pWin->nextSib)->siblingAbove =
+           pWindowPriv->siblingAbove;
+  }
+
+  #ifdef NXAGENT_SHAPE2
+
+  #ifdef SHAPE
+
+  if (pWindowPriv->boundingShape)
+  {
+    REGION_DESTROY(pWin->drawable.pScreen,
+                       pWindowPriv->boundingShape);
+  }
+
+  if (pWindowPriv->clipShape)
+  {
+    REGION_DESTROY(pWin->drawable.pScreen,
+                       pWindowPriv->clipShape);
+  }
+
+  #endif
+
+  #else
+
+  REGION_DESTROY(pWin->drawable.pScreen,
+                     pWindowPriv->boundingShape);
+
+  REGION_DESTROY(pWin->drawable.pScreen,
+                     pWindowPriv->clipShape);
+
+  #endif
+
+  if (pWindowPriv -> corruptedRegion)
+  {
+    REGION_DESTROY(pWin -> drawable.pScreen,
+                       pWindowPriv -> corruptedRegion);
+
+    pWindowPriv -> corruptedRegion = NULL;
+  }
+
+  if (nxagentSynchronization.pDrawable == (DrawablePtr) pWin)
+  {
+    nxagentSynchronization.pDrawable = NULL;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentDestroyWindow: Synchronization drawable [%p] removed from resources.\n",
+                (void *) pWin);
+    #endif
+  }
+
+  nxagentDestroyCorruptedResource((DrawablePtr) pWin, RT_NX_CORR_WINDOW);
+
+  nxagentDestroyDrawableBitmap((DrawablePtr) pWin);
+
+  if (pWindowPriv -> splitResource != NULL)
+  {
+    nxagentReleaseSplit((DrawablePtr) pWin);
+  }
+
+  XDestroyWindow(nxagentDisplay, nxagentWindow(pWin));
+
+  if (nxagentOption(Rootless))
+  {
+    nxagentRootlessDelTopLevelWindow(pWin);
+  }
+
+  nxagentSplashCount--;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentDestroyWindow: The splash counter is now [%d].\n",
+              nxagentSplashCount);
+  #endif
+
+  if (nxagentSplashCount == 1)
+  {
+    XClearWindow(nxagentDisplay, nxagentWindowPriv(nxagentRootTileWindow) -> window);
+  }
+
+  if (pWin == nxagentRootTileWindow)
+  {
+    nxagentWindowPriv(nxagentRootTileWindow)->window = None;
+
+    nxagentRootTileWindow = None;
+  }
+
+  pWindowPriv->window = None;
+
+  if (pWin -> optional)
+  {
+    pWin -> optional -> userProps = NULL;
+  }
+
+  if (nxagentOption(Rootless) && nxagentRootlessDialogPid == 0 &&
+          nxagentLastWindowDestroyed == False && nxagentSomeWindowsAreMapped() == False)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentDestroyWindow: Last mapped window as been destroyed.\n");
+    #endif
+
+    nxagentLastWindowDestroyed     = True;
+    nxagentLastWindowDestroyedTime = GetTimeInMillis();
+  }
+
+  return True;
+}
+
+Bool nxagentPositionWindow(WindowPtr pWin, int x, int y)
+{
+  if (nxagentScreenTrap == 1)
+  {
+    return True;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentPositionWindow: Changing position of window [%p][%ld] to [%d,%d].\n",
+              (void *) pWin, nxagentWindow(pWin), x, y);
+  #endif
+
+  nxagentAddConfiguredWindow(pWin, CWParent | CWX | CWY | CWWidth |
+                                 CWHeight | CWBorderWidth);
+
+  return True;
+}
+
+void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
+{
+  if (nxagentScreenTrap == 1)
+  {
+    return;
+  }
+
+  nxagentAddConfiguredWindow(pWin, CW_RootlessRestack);
+
+}
+
+void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
+{
+  Window w;
+  XSetWindowAttributes attributes;
+  unsigned long valuemask;
+
+  if (nxagentOption(Rootless))
+  {
+    return;
+  }
+
+  if (!switchOn)
+  {
+    nxagentWMDetect();
+
+    if (!nxagentWMIsRunning)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "Warning: Can't switch to window mode, no window manager has been detected.\n");
+      #endif
+
+      return;
+    }
+  }
+
+  w = nxagentDefaultWindows[pScreen -> myNum];
+  attributes.override_redirect = switchOn;
+  valuemask = CWOverrideRedirect;
+  XUnmapWindow(nxagentDisplay, w);
+  XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+
+  if (switchOn)
+  {
+    /*
+     * Change to fullscreen mode.
+     */
+
+    struct timeval timeout;
+    int i;
+    XEvent e;
+
+    /*
+     * Wait for window manager reparenting the default window.
+     */
+
+    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
+      #endif
+
+      if (XCheckTypedWindowEvent(nxagentDisplay, w, ReparentNotify, &e))
+      {
+        break;
+      }
+
+      /*
+       * This should also flush
+       * the NX link for us.
+       */
+
+      XSync(nxagentDisplay, 0);
+
+      timeout.tv_sec  = 0;
+      timeout.tv_usec = 50 * 1000;
+
+      nxagentWaitEvents(nxagentDisplay, &timeout);
+    }
+
+    if (i < 100)
+    {
+      /*
+       * The window manager has done with the reparent
+       * operation. We can resize and map the window.
+       */
+
+      nxagentChangeOption(Fullscreen, True);
+
+      /*
+       * Save the window-mode configuration.
+       */
+
+      nxagentChangeOption(SavedX, nxagentOption(X));
+      nxagentChangeOption(SavedY, nxagentOption(Y));
+      nxagentChangeOption(SavedWidth, nxagentOption(Width));
+      nxagentChangeOption(SavedHeight, nxagentOption(Height));
+      nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
+      nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+      /*
+       * Reconf the Default window.
+       */
+
+      nxagentChangeOption(X, 0);
+      nxagentChangeOption(Y, 0);
+      nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+      nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+      /*
+       * Move the root window.
+       */
+
+      nxagentChangeOption(RootX, (nxagentOption(Width) - nxagentOption(RootWidth)) / 2);
+      nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) / 2);
+      nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+      nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+      XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+                            nxagentOption(Width), nxagentOption(Height));
+
+      nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight));
+
+      XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                      nxagentOption(RootX), nxagentOption(RootY));
+
+      /*
+       * We disable the screensaver when changing
+       * mode to fullscreen. Is it really needed?
+       */
+
+      XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+
+      if (nxagentIconWindow == None)
+      {
+        nxagentIconWindow = nxagentCreateIconWindow();
+
+        XMapWindow(nxagentDisplay, nxagentIconWindow);
+      }
+
+      XMapRaised(nxagentDisplay, w);
+      XSetInputFocus(nxagentDisplay, w, RevertToParent, CurrentTime);
+      XCheckTypedWindowEvent(nxagentDisplay, w, LeaveNotify, &e);
+      nxagentFullscreenWindow = w;
+
+      if (nxagentOption(DesktopResize) == 1)
+      {
+        if (nxagentOption(Shadow) == 0)
+        {
+          nxagentRRSetScreenConfig(pScreen, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+                                       HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+        }
+        else
+        {
+          nxagentShadowAdaptToRatio();
+        }
+      }
+    }
+    else
+    {
+      /*
+       * We have waited for a reparent event unsuccessfully.
+       * Something happened to the window manager.
+       */
+
+      #ifdef WARNING
+      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Expected ReparentNotify event missing.\n");
+      #endif
+
+      nxagentWMIsRunning = False;
+      attributes.override_redirect = False;
+      XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+      XMapWindow(nxagentDisplay, w);
+    }
+  }
+  else
+  {
+    /*
+     * FIXME:
+     * It could be necessary:
+     * - To restore screensaver.
+     * - To set or reset nxagentForceBackingStore flag.
+     * - To grab keyboard.
+     * - To propagate device settings to the X server if no WM is running.
+     */
+
+    /*
+     * Change to windowed mode.
+     */
+
+    nxagentChangeOption(Fullscreen, False);
+    XDestroyWindow(nxagentDisplay, nxagentIconWindow);
+    nxagentIconWindow = nxagentFullscreenWindow = None;
+
+    if (nxagentOption(DesktopResize) == 1)
+    {
+      nxagentChangeOption(RootWidth, nxagentOption(SavedRootWidth));
+      nxagentChangeOption(RootHeight, nxagentOption(SavedRootHeight));
+
+      if (nxagentOption(Shadow) == 0)
+      {
+        nxagentRRSetScreenConfig(pScreen, nxagentOption(RootWidth), nxagentOption(RootHeight));
+      }
+    }
+
+    nxagentChangeOption(X, nxagentOption(SavedX));
+    nxagentChangeOption(Y, nxagentOption(SavedY));
+    nxagentChangeOption(Width, nxagentOption(SavedWidth));
+    nxagentChangeOption(Height, nxagentOption(SavedHeight));
+
+    if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1)
+    {
+      nxagentShadowAdaptToRatio();
+    }
+
+    XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+                          nxagentOption(Width), nxagentOption(Height));
+
+    nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height));
+
+    XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), 0, 0);
+    XMapWindow(nxagentDisplay, w);
+
+    nxagentChangeOption(RootX, 0);
+    nxagentChangeOption(RootY, 0);
+  }
+
+  XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+                        nxagentOption(Width), nxagentOption(Height));
+}
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentUpdateViewportFrame(int x, int y, int w, int h)
+{
+  /*
+   * Four virtual windows make a frame around the viewport. We move the frame
+   * with the viewport together. The areas going into the viewport were covered by
+   * the frame and become exposed. This make the agent send expose events to his
+   * clients.
+   */
+
+  XID values[3];
+  Mask mask;
+
+  /*
+   * nxagentScreenTrap = True;
+   */
+
+  values[2] = Above;
+
+  values[1] = nxagentOption(RootHeight);
+
+  mask = CWX | CWHeight | CWStackMode;
+  values[0] = x - NXAGENT_FRAME_WIDTH;
+  ConfigureWindow(nxagentViewportFrameLeft, mask, (XID *) &values, serverClient);
+
+  values[0] = x + w;
+  ConfigureWindow(nxagentViewportFrameRight, mask, (XID *) &values, serverClient);
+
+  values[1] = nxagentOption(RootWidth);
+
+  mask = CWY | CWWidth | CWStackMode;
+  values[0] = y - NXAGENT_FRAME_WIDTH;
+  ConfigureWindow(nxagentViewportFrameAbove, mask, (XID *) &values, serverClient);
+
+  values[0] = y + h;
+  ConfigureWindow(nxagentViewportFrameBelow, mask, (XID *) &values, serverClient);
+
+  /*
+   * nxagentScreenTrap = False;
+   */
+}
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift)
+{
+  int newX;
+  int newY;
+  int oldX;
+  int oldY;
+
+  Bool doMove = False;
+  oldX = 0;
+  oldY = 0;
+
+  if (nxagentOption(Rootless))
+  {
+    return;
+  }
+
+  /*
+   * We must keep x coordinate between viewportXSpan and zero, if viewportXSpan
+   * is less then zero. If viewportXSpan is greater or equal to zero, it means
+   * the agent root window has a size smaller than the agent default window.
+   * In this case we keep the old coordinate.
+   */
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentMoveViewport: RootX[%i] RootY[%i], hShift[%i] vShift[%i].\n",
+          nxagentOption(RootX), nxagentOption(RootY), hShift, vShift);
+  #endif
+
+  nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+
+  nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+  if (nxagentOption(ViewportXSpan) < 0)
+  {
+    newX = nxagentOption(RootX) - hShift;
+
+    if (newX > 0)
+    {
+      newX = 0;
+    }
+    else if (newX < nxagentOption(ViewportXSpan))
+    {
+      newX = nxagentOption(ViewportXSpan);
+    }
+  }
+  else if (nxagentOption(ViewportXSpan) == 0)
+  {
+    newX = 0;
+  }
+  else
+  {
+    newX = nxagentOption(RootX);
+  }
+
+  if (nxagentOption(ViewportYSpan) < 0)
+  {
+    newY = nxagentOption(RootY) - vShift;
+
+    if (newY > 0)
+    {
+      newY = 0;
+    }
+    else if (newY < nxagentOption(ViewportYSpan))
+    {
+      newY = nxagentOption(ViewportYSpan);
+    }
+  }
+  else if (nxagentOption(ViewportYSpan) == 0)
+  {
+    newY = 0;
+  }
+  else
+  {
+    newY = nxagentOption(RootY);
+  }
+
+  oldX = nxagentOption(RootX);
+
+  if (newX != nxagentOption(RootX))
+  {
+    nxagentChangeOption(RootX, newX);
+
+    doMove = True;
+  }
+
+  oldY = nxagentOption(RootY);
+
+  if (newY != nxagentOption(RootY))
+  {
+    nxagentChangeOption(RootY, newY);
+
+    doMove = True;
+  }
+
+  if (doMove)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentMoveViewport: New viewport geometry: (%d, %d)-"
+                "(%d, %d)\n", -nxagentOption(RootX), -nxagentOption(RootY),
+                    -nxagentOption(RootX) + nxagentOption(Width),
+                        -nxagentOption(RootY) + nxagentOption(Height));
+
+    fprintf(stderr, "nxagentMoveViewport: Root geometry x=[%d] y=[%d]\n",
+                WindowTable[pScreen -> myNum] -> drawable.x,
+                    WindowTable[pScreen -> myNum] -> drawable.y );
+    #endif
+
+    XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                    nxagentOption(RootX), nxagentOption(RootY));
+
+    if (nxagentOption(ClientOs) == ClientOsWinnt)
+    {
+      /* 
+       * If doMove is True we add exposed rectangles
+       * to the remote expose region. This is done to
+       * refresh the areas showed newly in the viewport.
+       * We create two rectangles, one for horizontal
+       * pan and one for vertical pan.
+       */
+
+      BoxRec hRect;
+      BoxRec vRect;
+
+      hRect.x1 = -newX;
+      hRect.y1 = -newY;
+
+      if (hShift < 0)
+      {
+        hRect.x2 = -oldX;
+        hRect.y2 = -newY + nxagentOption(Height);
+      }
+      else if (hShift > 0)
+      {
+        hRect.x1 = -oldX + nxagentOption(Width);
+        hRect.x2 = -newX + nxagentOption(Width);
+        hRect.y2 = -newY + nxagentOption(Height);
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentMoveViewport: hRect p1[%i, %i] - p2[%i, %i].\n", hRect.x1, hRect.y1, hRect.x2, hRect.y2);
+      #endif
+
+      vRect.x1 = -newX;
+      vRect.y1 = -newY;
+
+      if (vShift < 0)
+      {
+        vRect.x2 = -newX + nxagentOption(Width);
+        vRect.y2 = -oldY;
+      }
+      else if (vShift > 0)
+      {
+        vRect.y1 = -oldY + nxagentOption(Height);
+        vRect.x2 = -newX + nxagentOption(Width);
+        vRect.y2 = -newY + nxagentOption(Height);
+      }
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentMoveViewport: vRect p1[%i, %i] - p2[%i, %i].\n", vRect.x1, vRect.y1, vRect.x2, vRect.y2);
+      #endif
+
+      if (oldX != newX && hRect.x1 != hRect.x2 && hRect.y1 != hRect.y2)
+      {
+        nxagentAddRectToRemoteExposeRegion(&hRect);
+      }
+
+      if (oldY != newY && vRect.x1 != vRect.x2 && vRect.y1 != vRect.y2)
+      {
+        nxagentAddRectToRemoteExposeRegion(&vRect);
+      }
+    }
+  }
+
+  nxagentUpdateViewportFrame(-nxagentOption(RootX), -nxagentOption(RootY),
+                                 nxagentOption(Width), nxagentOption(Height));
+}
+
+void nxagentConfigureWindow(WindowPtr pWin, unsigned int mask)
+{
+  unsigned int valuemask;
+  XWindowChanges values;
+
+  if (nxagentScreenTrap == 1)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentConfigureWindow: WARNING: Called with the screen trap set.\n");
+    #endif
+
+    return;
+  }
+
+  if (nxagentOption(Rootless) == 1 &&
+          nxagentWindowTopLevel(pWin) == 1)
+  {
+    mask &= ~(CWSibling | CWStackMode);
+  }
+  else
+  {
+    if (mask & CW_RootlessRestack)
+    {
+      mask = CWStackingOrder;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentConfigureWindow: Called with window [%p][%ld] and mask [%x].\n",
+              (void *) pWin, nxagentWindow(pWin), mask);
+  #endif
+
+  nxagentMoveCorruptedRegion(pWin, mask);
+
+  valuemask = 0;
+
+  if (mask & CW_Update)
+  {
+    mask |= CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWStackingOrder;
+  }
+
+  if (mask & CWX)
+  {
+    valuemask |= CWX;
+
+    values.x = nxagentWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
+  }
+
+  if (mask & CWY)
+  {
+    valuemask |= CWY;
+
+    values.y = nxagentWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
+  }
+
+  if (mask & CWWidth)
+  {
+    valuemask |= CWWidth;
+
+    values.width = nxagentWindowPriv(pWin)->width = pWin->drawable.width;
+  }
+
+  if (mask & CWHeight)
+  {
+    valuemask |= CWHeight;
+
+    values.height = nxagentWindowPriv(pWin)->height = pWin->drawable.height;
+  }
+
+  if (mask & CWBorderWidth)
+  {
+    valuemask |= CWBorderWidth;
+
+    values.border_width = nxagentWindowPriv(pWin)->borderWidth =
+        pWin->borderWidth;
+  }
+
+  if (mask & CW_Update)
+  {
+    valuemask = 0;
+  }
+
+  if (valuemask)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentConfigureWindow: Going to configure window [%p][%ld] with mask [%x].\n",
+                (void *) pWin, nxagentWindow(pWin), valuemask);
+    #endif
+
+    XConfigureWindow(nxagentDisplay, nxagentWindow(pWin), valuemask, &values);
+
+    MAKE_SYNC_CONFIGURE_WINDOW;
+  }
+
+  if (mask & CWStackingOrder &&
+          nxagentWindowPriv(pWin)->siblingAbove != nxagentWindowSiblingAbove(pWin))
+  {
+    WindowPtr pSib;
+
+    /*
+     * Find the top sibling.
+     */
+
+    for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
+
+    /*
+     * Configure the top sibling.
+     */
+
+    valuemask = CWStackMode;
+
+    values.stack_mode = Above;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentConfigureWindow: Going to configure top sibling [%ld] "
+                "with mask [%x] and parent [%ld].\n", nxagentWindow(pSib),
+                    valuemask, nxagentWindowParent(pWin));
+    #endif
+
+    XConfigureWindow(nxagentDisplay, nxagentWindow(pSib), valuemask, &values);
+
+    MAKE_SYNC_CONFIGURE_WINDOW;
+
+    nxagentWindowPriv(pSib)->siblingAbove = None;
+
+    /*
+     * Configure the rest of siblings.
+     */
+
+    valuemask = CWSibling | CWStackMode;
+
+    values.stack_mode = Below;
+
+    for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib)
+    {
+      values.sibling = nxagentWindowSiblingAbove(pSib);
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentConfigureWindow: Going to configure other sibling [%ld] "
+                  "with mask [%x] and parent [%ld] below [%ld].\n", nxagentWindow(pSib),
+                      valuemask, nxagentWindowParent(pWin), nxagentWindowSiblingAbove(pSib));
+      #endif
+
+      XConfigureWindow(nxagentDisplay, nxagentWindow(pSib), valuemask, &values);
+
+      MAKE_SYNC_CONFIGURE_WINDOW;
+
+      nxagentWindowPriv(pSib)->siblingAbove = nxagentWindowSiblingAbove(pSib);
+    }
+
+    #ifdef TEST
+    {
+      Window root_return;
+      Window parent_return;
+      Window *children_return;
+      unsigned int nchildren_return;
+      Window *pw;
+      Status result;
+
+      result = XQueryTree(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                              &root_return, &parent_return, &children_return, &nchildren_return);
+
+      if (result)
+      {
+        pw = children_return;
+
+        fprintf(stderr, "nxagentConfigureWindow: Children of the root: ");
+        while(nchildren_return > 0)
+        {
+          pSib = nxagentWindowPtr(children_return[--nchildren_return]);
+          if (pSib)
+          {
+            fprintf(stderr, "%lu  ", children_return[nchildren_return]);
+          }
+        }
+        fprintf(stderr, "\n");
+
+        if (children_return)
+        {
+          XFree(children_return);
+        }
+      }
+      else
+      {
+        fprintf(stderr, "nxagentConfigureWindow: Failed QueryTree request.\n ");
+      }
+    }
+    #endif
+  }
+
+  #ifdef NXAGENT_SPLASH
+
+  /*
+   * This should bring again the splash window
+   * on top, so why the else clause? Is this
+   * really needed?
+   *
+   *
+   *  else if (mask & CWStackingOrder)
+   *  {
+   *    if (nxagentSplashWindow)
+   *    {
+   *      valuemask = CWStackMode;
+   *
+   *      values.stack_mode = Above;
+   *
+   *      #ifdef TEST
+   *      fprintf(stderr, "nxagentConfigureWindow: Going to configure splash window [%ld].\n",
+   *                  nxagentSplashWindow);
+   *      #endif
+   *
+   *      XConfigureWindow(nxagentDisplay, nxagentSplashWindow, valuemask, &values);
+   *
+   *      MAKE_SYNC_CONFIGURE_WINDOW;
+   *    }
+   *  }
+   */
+
+  #endif
+
+  if (mask & CW_RootlessRestack)
+  {
+    if (!pWin -> prevSib)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentConfigureWindow: Raising window [%p][%ld].\n",
+                  (void *) pWin, nxagentWindow(pWin));
+      #endif
+
+      XRaiseWindow(nxagentDisplay, nxagentWindow(pWin));
+    }
+    else if (!pWin -> nextSib)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentConfigureWindow: Lowering window [%p][%ld].\n",
+                  (void *) pWin, nxagentWindow(pWin));
+      #endif
+
+      XLowerWindow(nxagentDisplay, nxagentWindow(pWin));
+    }
+    else
+    {
+      XlibWindow windowList[2];
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentConfigureWindow: Putting window [%p][%ld] in the middle.\n",
+                  (void *) pWin, nxagentWindow(pWin));
+      #endif
+
+      windowList[0] = nxagentWindow(pWin->prevSib);
+      windowList[1] = nxagentWindow(pWin);
+
+      XRestackWindows(nxagentDisplay, windowList, 2);
+    }
+  }
+
+  #ifdef SHAPE
+
+  if (mask & CW_Shape)
+  {
+    nxagentShapeWindow(pWin);
+  }
+
+  #endif
+
+  if (mask & CW_Map &&
+         (!nxagentOption(Rootless) ||
+             nxagentRootlessWindow != pWin))
+  {
+    XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+
+    return;
+  }
+}
+
+void nxagentReparentWindow(pWin, pOldParent)
+     WindowPtr pWin;
+     WindowPtr pOldParent;
+{
+  if (nxagentScreenTrap)
+  {
+    return;
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReparentWindow:  window at %p [%lx] previous parent at %p [%lx].\n",
+              (void*)pWin, nxagentWindow(pWin),
+                  (void*)pOldParent, nxagentWindow(pOldParent));
+  #endif
+
+  XReparentWindow(nxagentDisplay, nxagentWindow(pWin),
+                      nxagentWindowParent(pWin),
+                          pWin->origin.x - wBorderWidth(pWin),
+                              pWin->origin.y - wBorderWidth(pWin));
+}
+
+Bool nxagentChangeWindowAttributes(pWin, mask)
+     WindowPtr pWin;
+     unsigned long mask;
+{
+  XSetWindowAttributes attributes;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentChangeWindowAttributes: Changing attributes for window at [%p] with mask [%lu].\n",
+              (void *) pWin, mask);
+  #endif
+
+  if (nxagentScreenTrap)
+  {
+    return True;
+  }
+
+  if (mask & CWBackPixmap)
+  {
+    switch (pWin->backgroundState)
+    {
+      case None:
+      {
+        attributes.background_pixmap = None;
+        attributes.background_pixel = nxagentWhitePixel;
+
+        /*
+         * One of problems faced during the implementation of lazy
+         * encoding policies was due to the presence of windows with
+         * transparent background, usually created by X clients to
+         * cover some sensible areas (i.e. checkboxes used by
+         * Konqueror 3.5). The sequence of operations consists in
+         * drawing the underneath part before covering it with the
+         * transparent window, so when we synchronize the deferred
+         * drawing operation we have to bear in mind that the dest-
+         * ination area is covered by a window. By using the Inclu-
+         * deInferiors GC's property and by clipping the region to
+         * synchronize to the borderClip instead of clipList (to
+         * include the areas covered by children) we can easily take
+         * care of this situation, but there is a drawback: if the
+         * children are not transparent, we are going to synchronize
+         * invisible areas. To avoid this we have added the 'has-
+         * TransparentChildren' flag, which is set when a window has
+         * at least one child with background None. The problem is
+         * that we don't know when to reset the flag. This solution,
+         * also, doesn't take care of transparent windows which don't
+         * have childhood relationships with underneath windows.
+         * We tried to mark the whole windows as dirty when they are
+         * created to force the synchronization of transparent windows
+         * with the content of underneath windows, but, of course,
+         * this works only with the first synchronization because the
+         * transparent windows will be never marked again as dirty.
+         */
+
+        if (pWin -> parent != NULL)
+        {
+          nxagentWindowPriv(pWin -> parent) -> hasTransparentChildren = 1;
+
+          #ifdef DEBUG
+          fprintf(stderr, "nxagentChangeWindowAttributes: WARNING! Window at [%p] got the "
+                      "hasTransparentChildren flag.\n", (void *) pWin);
+          #endif
+        }
+
+        break;
+      }
+      case ParentRelative:
+      {
+        attributes.background_pixmap = ParentRelative;
+
+        break;
+      }
+      case BackgroundPixmap:
+      {
+        /*
+         * If a window background is corrupted, we grant
+         * its usability by clearing it with a solid co-
+         * lor. When the pixmap will be fully synchroni-
+         * zed, an expose will be sent to the window's
+         * hierarchy.
+         */
+
+        if (nxagentDrawableStatus((DrawablePtr) pWin -> background.pixmap) == NotSynchronized)
+        {
+          #ifdef TEST
+          fprintf(stderr, "nxagentChangeWindowAttributes: The window at [%p] has the background at [%p] "
+                      "not synchronized.\n", (void *) pWin, (void *) pWin -> background.pixmap);
+          #endif
+
+          if (nxagentIsCorruptedBackground(pWin -> background.pixmap) == 0)
+          {
+            nxagentIsCorruptedBackground(pWin -> background.pixmap) = 1;
+
+            nxagentAllocateCorruptedResource((DrawablePtr) pWin -> background.pixmap, RT_NX_CORR_BACKGROUND);
+
+            /*
+             * Clearing the remote background to
+             * make it usable.
+             */
+
+            nxagentFillRemoteRegion((DrawablePtr) pWin -> background.pixmap,
+                                        nxagentCorruptedRegion((DrawablePtr) pWin -> background.pixmap));
+          }
+        }
+
+        attributes.background_pixmap = nxagentPixmap(pWin -> background.pixmap);
+
+        break;
+      }
+      case BackgroundPixel:
+      {
+        mask &= ~CWBackPixmap;
+
+        break;
+      }
+    }
+  }
+
+  if (mask & CWBackPixel)
+  {
+    if (pWin -> backgroundState == BackgroundPixel)
+    {
+      attributes.background_pixel = nxagentPixel(pWin -> background.pixel);
+    }
+    else
+    {
+      mask &= ~CWBackPixel;
+    }
+  }
+
+  if (mask & CWBorderPixmap)
+  {
+    if (pWin -> borderIsPixel != 0)
+    {
+      mask &= ~CWBorderPixmap;
+    }
+    else
+    {
+      attributes.border_pixmap = nxagentPixmap(pWin -> border.pixmap);
+    }
+  }
+
+  if (mask & CWBorderPixel)
+  {
+    if (pWin -> borderIsPixel != 0)
+    {
+      attributes.border_pixel = nxagentPixel(pWin -> border.pixel);
+    }
+    else
+    {
+      mask &= ~CWBorderPixel;
+    }
+  }
+
+  if (mask & CWBitGravity)
+  {
+    attributes.bit_gravity = pWin -> bitGravity;
+  }
+
+  /*
+   * As we set this bit, whe must change dix in
+   * order not to perform PositionWindow and let
+   * X move children windows for us.
+   */
+
+  if (mask & CWWinGravity)
+  {
+    attributes.win_gravity = pWin -> winGravity;
+  }
+
+/*
+FIXME: Do we need to set the attribute on the
+       remote display?
+*/
+  if (mask & CWBackingStore)
+  {
+    attributes.backing_store = pWin -> backingStore;
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentChangeWindowAttributes: Changing backing store value to %d"
+                " for window at %p.\n", pWin -> backingStore, (void*)pWin);
+    #endif
+  }
+
+  if (mask & CWBackingPlanes)
+  {
+    if ((nxagentBackingStore == NotUseful) || (pWin -> optional == NULL))
+    {
+      mask &= ~CWBackingPlanes;
+    }
+    else
+    {
+      attributes.backing_planes = pWin -> optional -> backingBitPlanes;
+    }
+  }
+
+  if (mask & CWBackingPixel)
+  {
+    if ((nxagentBackingStore == NotUseful) || (pWin -> optional == NULL))
+    {
+      mask &= ~CWBackingPixel;
+    }
+    else
+    {
+      attributes.backing_pixel = pWin -> optional -> backingPixel;
+    }
+  }
+
+  if (mask & CWOverrideRedirect)
+  {
+    attributes.override_redirect = pWin -> overrideRedirect;
+  }
+
+/*
+FIXME: Do we need to set the attribute on the
+       remote display?
+*/
+  if (mask & CWSaveUnder)
+  {
+    attributes.save_under = pWin -> saveUnder;
+  }
+
+  /*
+   * Events are handled elsewhere.
+   */
+
+  if (mask & CWEventMask)
+  {
+    mask &= ~CWEventMask;
+  }
+
+  if (mask & CWDontPropagate)
+  {
+    mask &= ~CWDontPropagate;
+  }
+
+  if (mask & CWColormap)
+  {
+    ColormapPtr pCmap;
+
+    pCmap = (ColormapPtr) LookupIDByType(wColormap(pWin), RT_COLORMAP);
+
+/*
+FIXME: When the caller is nxagentReconfigureWindow
+       sometimes wColormap(pWin) is 0. Could a window
+       have no colormap?
+*/
+    if (pCmap != NULL)
+    {
+      attributes.colormap = nxagentColormap(pCmap);
+
+      nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+    }
+    else
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentChangeWindowAttributes: WARNING! Bad colormap "
+                  "[%lu] for window at [%p].\n", wColormap(pWin), (void *) pWin);
+      #endif
+
+      mask &= ~CWColormap;
+    }
+  }
+
+  if (mask & CWCursor)
+  {
+    if (nxagentOption(Rootless))
+    {
+      if (pWin->cursorIsNone == 0 && pWin->optional != NULL && 
+              pWin->optional->cursor != NULL && nxagentCursorPriv(pWin ->
+                  optional -> cursor, pWin -> drawable.pScreen) != NULL)
+      {
+        attributes.cursor = nxagentCursor(pWin -> optional -> cursor,
+                                              pWin -> drawable.pScreen);
+      }
+      else
+      {
+        attributes.cursor = None;
+      }
+    }
+    else
+    {
+      /*
+       * This is handled in cursor code
+       */
+
+      mask &= ~CWCursor;
+    }
+  }
+
+  if (mask != 0)
+  {
+    XChangeWindowAttributes(nxagentDisplay, nxagentWindow(pWin), mask, &attributes);
+  }
+
+  return 1;
+}
+
+Bool nxagentRealizeWindow(WindowPtr pWin)
+{
+  if (nxagentScreenTrap == 1)
+  {
+    return True;
+  }
+
+  /*
+   * Not needed.
+   *
+   * nxagentConfigureWindow(pWin, CWStackingOrder);
+   *
+   * nxagentFlushConfigureWindow();
+   */
+
+  nxagentAddConfiguredWindow(pWin, CWStackingOrder);
+  nxagentAddConfiguredWindow(pWin, CW_Shape);
+
+  #ifdef SHAPE
+
+  /*
+   * Not needed.
+   *
+   * nxagentShapeWindow(pWin);
+   */
+
+  #endif /* SHAPE */
+
+  /*
+   * Mapping of the root window is called by
+   * InitRootWindow in DIX. Skip the operation
+   * if we are in rootless mode.
+   */
+
+  /*
+   * if (!nxagentOption(Rootless) ||
+   *         nxagentRootlessWindow != pWin)
+   * {
+   *   XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+   * }
+   */
+
+  #ifdef TEST
+  if (nxagentOption(Rootless) && nxagentLastWindowDestroyed)
+  {
+    fprintf(stderr, "nxagentRealizeWindow: Window realized. Stopped termination for rootless session.\n");
+  }
+  #endif
+
+  nxagentAddConfiguredWindow(pWin, CW_Map);
+
+  nxagentLastWindowDestroyed = False;
+
+  return True;
+}
+
+Bool nxagentUnrealizeWindow(pWin)
+    WindowPtr pWin;
+{
+  if (nxagentScreenTrap)
+  {
+    return True;
+  }
+
+  XUnmapWindow(nxagentDisplay, nxagentWindow(pWin));
+
+  return True;
+}
+
+void nxagentFrameBufferPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+
+  void *PaintWindowBackgroundBackup;
+
+  if (pWin->backgroundState == BackgroundPixmap)
+  {
+    pWin->background.pixmap = nxagentVirtualPixmap(pWin->background.pixmap);
+  }
+
+  if (pWin->borderIsPixel == False)
+  {
+    pWin->border.pixmap = nxagentVirtualPixmap(pWin->border.pixmap);
+  }
+
+  PaintWindowBackgroundBackup = pWin->drawable.pScreen -> PaintWindowBackground;
+
+  pWin->drawable.pScreen -> PaintWindowBackground = nxagentFrameBufferPaintWindow;
+
+  fbPaintWindow(pWin, pRegion, what);
+
+  pWin->drawable.pScreen -> PaintWindowBackground = PaintWindowBackgroundBackup;
+
+  if (pWin->backgroundState == BackgroundPixmap)
+  {
+    pWin->background.pixmap = nxagentRealPixmap(pWin->background.pixmap);
+  }
+
+  if (pWin->borderIsPixel == False)
+  {
+    pWin->border.pixmap = nxagentRealPixmap(pWin->border.pixmap);
+  }
+}
+
+void nxagentPaintWindowBackground(pWin, pRegion, what)
+     WindowPtr pWin;
+     RegionPtr pRegion;
+     int what;
+{
+  int i;
+
+  RegionRec temp;
+
+  if (pWin -> realized)
+  {
+    BoxPtr pBox;
+
+    pBox = REGION_RECTS(pRegion);
+
+    for (i = 0; i < REGION_NUM_RECTS(pRegion); i++)
+    {
+      XClearArea(nxagentDisplay, nxagentWindow(pWin),
+                 pBox[i].x1 - pWin->drawable.x,
+                 pBox[i].y1 - pWin->drawable.y,
+                 pBox[i].x2 - pBox[i].x1,
+                 pBox[i].y2 - pBox[i].y1,
+                 False);
+    }
+  }
+  #ifdef TEST
+  else
+  {
+    fprintf(stderr, "nxagentPaintWindowBackground: Saving the operation with window "
+                "at [%p] not realized.\n", (void *) pWin);
+  }
+  #endif
+
+  /*
+   * The framebuffer operations don't take care of
+   * clipping to the actual area of the framebuffer
+   * so we need to clip ourselves.
+   */
+
+  REGION_INIT(pWin -> drawable.pScreen, &temp, NullBox, 1);
+
+  REGION_INTERSECT(pWin -> drawable.pScreen, &temp, pRegion, &pWin -> clipList);
+
+  nxagentFrameBufferPaintWindow(pWin, &temp, what);
+
+  REGION_UNINIT(pWin -> drawable.pScreen, &temp);
+}
+
+void nxagentPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what)
+{
+  RegionRec temp;
+
+  /*
+   * The framebuffer operations don't take care of
+   * clipping to the actual area of the framebuffer
+   * so we need to clip ourselves.
+   */
+
+  REGION_INIT(pWin -> drawable.pScreen, &temp, NullBox, 1);
+
+  REGION_INTERSECT(pWin -> drawable.pScreen, &temp, pRegion, &pWin -> borderClip);
+
+  nxagentFrameBufferPaintWindow(pWin, &temp, what);
+
+  REGION_UNINIT(pWin -> drawable.pScreen, &temp);
+}
+
+void nxagentCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion)
+{
+  fbCopyWindow(pWin, oldOrigin, oldRegion);
+}
+
+void nxagentClipNotify(WindowPtr pWin, int dx, int dy)
+{
+  /*
+   * nxagentConfigureWindow(pWin, CWStackingOrder);
+   */
+
+  nxagentAddConfiguredWindow(pWin, CWStackingOrder);
+  nxagentAddConfiguredWindow(pWin, CW_Shape);
+
+#ifdef NXAGENT_SHAPE
+  return;
+#else
+
+#ifdef SHAPE
+
+/*
+ * nxagentShapeWindow(pWin);
+ */
+
+#endif /* SHAPE */
+
+#endif /* NXAGENT_SHAPE */
+}
+
+void nxagentWindowExposures(WindowPtr pWin, RegionPtr pRgn, RegionPtr other_exposed)
+{
+  /*
+   * The problem: we want to synthetize the expose events internally, so
+   * that we reduce the time between a window operation and the corresp-
+   * onding graphical output, but at the same time we need to take care
+   * of the remote exposures, as we need to handle those cases where our
+   * windows are covered by the windows on the real display. Handling
+   * both the local and the remote exposures we would generate the same
+   * redraws twice, something we call "double refreshes", so we must be
+   * able to identify which events have been already sent to our clients.
+   *
+   * Here is how the algorithm is working:
+   *
+   * - We collect the exposures that the agent sent to its clients in a
+   *   region (the "local-region") and store the region for a given win-
+   *   dow in a vector.
+   *
+   * - Another region collects the expose that were received from the
+   *   real X server (the "remote-region") for the same window.
+   *
+   * - We create a "fake" off-screen window. For every generated region
+   *   we send a ConfigureWindow request for that window to synchronize
+   *  ourselves with both the remote X server and/or the window manager.
+   *
+   * - When the ConfigureNotify is received, we calculate the difference
+   *   between the "remote-region" and the "local-region" for the window
+   *   that had collected exposures.
+   *
+   * - Finally we send the resulting exposures to our clients.
+   *
+   * As you may have guessed, the windows are synchronized per-region,
+   * that is there is a single region for a set of exposures. The regions
+   * are handled in order. This means that we can always calculate the
+   * final region by referring to the first element of the vector.
+   */
+
+  RegionRec temp;
+  BoxRec box;
+
+  if (nxagentSessionState != SESSION_DOWN)
+  {
+    if (nxagentExposeArrayIsInitialized == 0)
+    {
+      int i;
+
+      XSetWindowAttributes attributes;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentWindowExposures: Initializing expose queue.\n");
+      #endif
+
+      attributes.event_mask = StructureNotifyMask;
+
+      for (i = 0; i < EXPOSED_SIZE; i++)
+      {
+        nxagentExposeQueue.exposures[i].pWindow = NULL;
+        nxagentExposeQueue.exposures[i].localRegion = NullRegion;
+        nxagentExposeQueue.exposures[i].remoteRegion = NullRegion;
+        nxagentExposeQueue.exposures[i].remoteRegionIsCompleted = False;
+        nxagentExposeQueue.exposures[i].serial = 0;
+      }
+
+      nxagentExposeQueue.length = 0;
+
+      nxagentExposeSerial = 0;
+
+      nxagentExposeQueue.start = 0;
+
+      nxagentConfiguredSynchroWindow = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay), 0, 0,
+                                                           1, 1, 0, 0, InputOutput, 0, CWEventMask, &attributes);
+
+      nxagentInitRemoteExposeRegion();
+
+      nxagentExposeArrayIsInitialized = 1;
+    }
+
+    REGION_INIT(pWin -> drawable.pScreen, &temp, (BoxRec *) NULL, 1);
+
+    if (pRgn != NULL)
+    {
+      if (REGION_NUM_RECTS(pRgn) > RECTLIMIT)
+      {
+        box = *REGION_EXTENTS(pWin -> drawable.pScreen, pRgn);
+
+        REGION_EMPTY(pWin -> drawable.pScreen, pRgn);
+        REGION_INIT(pWin -> drawable.pScreen, pRgn, &box, 1);
+      }
+
+      REGION_UNION(pWin -> drawable.pScreen, &temp, &temp, pRgn);
+    }
+
+    if (other_exposed != NULL)
+    {
+      REGION_UNION(pWin -> drawable.pScreen, &temp, &temp, other_exposed);
+    }
+
+    if (REGION_NIL(&temp) == 0)
+    {
+      REGION_TRANSLATE(pWin -> drawable.pScreen, &temp,
+                           -(pWin -> drawable.x), -(pWin -> drawable.y));
+
+      if (nxagentExposeQueue.length < EXPOSED_SIZE)
+      {
+        XWindowChanges changes;
+        int index;
+
+        index = (nxagentExposeQueue.start + nxagentExposeQueue.length) % EXPOSED_SIZE;
+
+        nxagentExposeQueue.exposures[index].pWindow = pWin;
+
+        nxagentExposeQueue.exposures[index].localRegion = REGION_CREATE(pwin -> drawable.pScreen, NULL, 1);
+
+        if (nxagentOption(Rootless) && nxagentWindowPriv(pWin) &&
+                (nxagentWindowPriv(pWin) -> isMapped == 0 ||
+                     nxagentWindowPriv(pWin) -> visibilityState != VisibilityUnobscured))
+        {
+          nxagentExposeQueue.exposures[index].remoteRegion = REGION_CREATE(pwin -> drawable.pScreen, NULL, 1);
+
+          REGION_UNION(pWin -> drawable.pScreen, nxagentExposeQueue.exposures[index].remoteRegion,
+                           nxagentExposeQueue.exposures[index].remoteRegion, &temp);
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentWindowExposures: Added region to remoteRegion for window [%ld] to position [%d].\n",
+                      nxagentWindow(pWin), nxagentExposeQueue.length);
+          #endif
+        }
+        else
+        {
+          REGION_UNION(pWin -> drawable.pScreen, nxagentExposeQueue.exposures[index].localRegion,
+                           nxagentExposeQueue.exposures[index].localRegion, &temp);
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentWindowExposures: Added region to localRegion for window [%ld] to position [%d].\n",
+                      nxagentWindow(pWin), nxagentExposeQueue.length);
+          #endif
+        }
+
+        nxagentExposeSerial = (nxagentExposeSerial - 1) % EXPOSED_SIZE;
+
+        changes.x = nxagentExposeSerial;
+        changes.y = -2;
+
+        nxagentExposeQueue.exposures[index].serial = nxagentExposeSerial;
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentWindowExposures: Added region to queue with serial [%d].\n", nxagentExposeSerial);
+        #endif
+
+        /*
+         * Mark this region for sending a synchro,
+         * in nxagentFlushConfigureWindow().
+         */
+
+        nxagentExposeQueue.exposures[index].synchronize = 1;
+
+        nxagentExposeQueue.length++;
+
+        if (nxagentOption(Rootless) && nxagentWindowPriv(pWin) &&
+                (nxagentWindowPriv(pWin) -> isMapped == 0 ||
+                     nxagentWindowPriv(pWin) -> visibilityState != VisibilityUnobscured))
+        {
+          REGION_UNINIT(pWin -> drawable.pScreen, &temp);
+
+          return;
+        }
+      }
+      else
+      {
+        REGION_UNINIT(pWin -> drawable.pScreen, &temp);
+
+        #ifdef TEST
+        fprintf(stderr, "nxagentWindowExposures: WARNING! Reached maximum size of collect exposures vector.\n");
+        #endif
+
+        if ((pRgn != NULL && REGION_NOTEMPTY(pWin -> drawable.pScreen, pRgn) != 0) ||
+               (other_exposed != NULL && REGION_NOTEMPTY(pWin -> drawable.pScreen, other_exposed) != 0))
+        {
+          nxagentUnmarkExposedRegion(pWin, pRgn, other_exposed);
+
+          miWindowExposures(pWin, pRgn, other_exposed);
+        }
+
+        return;
+      }
+    }
+
+    REGION_UNINIT(pWin -> drawable.pScreen, &temp);
+  }
+
+  if ((pRgn != NULL && REGION_NOTEMPTY(pWin -> drawable.pScreen, pRgn) != 0) ||
+         (other_exposed != NULL && REGION_NOTEMPTY(pWin -> drawable.pScreen, other_exposed) != 0))
+  {
+    nxagentUnmarkExposedRegion(pWin, pRgn, other_exposed);
+
+    miWindowExposures(pWin, pRgn, other_exposed);
+  }
+
+  return;
+}
+
+#ifdef SHAPE
+static Bool nxagentRegionEqual(RegionPtr pReg1, RegionPtr pReg2)
+{
+  BoxPtr pBox1, pBox2;
+  unsigned int n1, n2;
+
+  if (pReg1 == pReg2) return True;
+
+  if (pReg1 == NullRegion || pReg2 == NullRegion) return False;
+
+  pBox1 = REGION_RECTS(pReg1);
+  n1 = REGION_NUM_RECTS(pReg1);
+
+  pBox2 = REGION_RECTS(pReg2);
+  n2 = REGION_NUM_RECTS(pReg2);
+
+  if (n1 != n2) return False;
+
+  if (pBox1 == pBox2) return True;
+
+  if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec))) return False;
+
+  return True;
+}
+
+void nxagentShapeWindow(WindowPtr pWin)
+{
+  Region reg;
+  BoxPtr pBox;
+  XRectangle rect;
+  int i;
+
+  if (NXDisplayError(nxagentDisplay) == 1)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentShapeWindow: Window at [%p][%ld].\n",
+              (void *) pWin, nxagentWindow(pWin));
+  #endif
+
+  if (!nxagentRegionEqual(nxagentWindowPriv(pWin)->boundingShape,
+                        wBoundingShape(pWin)))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentShapeWindow: Bounding shape differs.\n");
+    #endif
+
+    if (wBoundingShape(pWin))
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentShapeWindow: wBounding shape has [%ld] rects.\n",
+                  REGION_NUM_RECTS(wBoundingShape(pWin)));
+      #endif
+
+#ifdef NXAGENT_SHAPE2
+      if (!nxagentWindowPriv(pWin)->boundingShape)
+      {
+         nxagentWindowPriv(pWin)->boundingShape = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+      }
+#endif
+
+      REGION_COPY(pWin->drawable.pScreen,
+                      nxagentWindowPriv(pWin)->boundingShape, wBoundingShape(pWin));
+
+      reg = XCreateRegion();
+      pBox = REGION_RECTS(nxagentWindowPriv(pWin)->boundingShape);
+      for (i = 0;
+           i < REGION_NUM_RECTS(nxagentWindowPriv(pWin)->boundingShape);
+           i++)
+      {
+        rect.x = pBox[i].x1;
+        rect.y = pBox[i].y1;
+        rect.width = pBox[i].x2 - pBox[i].x1;
+        rect.height = pBox[i].y2 - pBox[i].y1;
+        XUnionRectWithRegion(&rect, reg, reg);
+      }
+
+#ifndef NXAGENT_SHAPE
+      XShapeCombineRegion(nxagentDisplay, nxagentWindow(pWin),
+                              ShapeBounding, 0, 0, reg, ShapeSet);
+#endif
+
+      XDestroyRegion(reg);
+    }
+    else
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentShapeWindow: wBounding shape does not exist. Removing the shape.\n");
+      #endif
+
+      REGION_EMPTY(pWin->drawable.pScreen,
+                       nxagentWindowPriv(pWin)->boundingShape);
+
+#ifndef NXAGENT_SHAPE
+      XShapeCombineMask(nxagentDisplay, nxagentWindow(pWin),
+                            ShapeBounding, 0, 0, None, ShapeSet);
+#endif
+
+    }
+  }
+
+  if (!nxagentRegionEqual(nxagentWindowPriv(pWin)->clipShape, wClipShape(pWin)))
+  {
+    #ifdef DEBUG
+    fprintf(stderr, "nxagentShapeWindow: Clip shape differs.\n");
+    #endif
+
+    if (wClipShape(pWin))
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentShapeWindow: wClip shape has [%ld] rects.\n",
+                  REGION_NUM_RECTS(wClipShape(pWin)));
+      #endif
+
+#ifdef NXAGENT_SHAPE2
+      if (!nxagentWindowPriv(pWin)->clipShape)
+      {
+        nxagentWindowPriv(pWin)->clipShape = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+      }
+#endif
+
+      REGION_COPY(pWin->drawable.pScreen,
+                  nxagentWindowPriv(pWin)->clipShape, wClipShape(pWin));
+
+      reg = XCreateRegion();
+      pBox = REGION_RECTS(nxagentWindowPriv(pWin)->clipShape);
+      for (i = 0;
+           i < REGION_NUM_RECTS(nxagentWindowPriv(pWin)->clipShape);
+           i++)
+      {
+        rect.x = pBox[i].x1;
+        rect.y = pBox[i].y1;
+        rect.width = pBox[i].x2 - pBox[i].x1;
+        rect.height = pBox[i].y2 - pBox[i].y1;
+        XUnionRectWithRegion(&rect, reg, reg);
+      }
+
+#ifndef NXAGENT_SHAPE
+      XShapeCombineRegion(nxagentDisplay, nxagentWindow(pWin),
+                              ShapeClip, 0, 0, reg, ShapeSet);
+#endif
+
+      XDestroyRegion(reg);
+    }
+    else
+    {
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentShapeWindow: wClip shape does not exist. Removing the shape.\n");
+      #endif
+
+      REGION_EMPTY(pWin->drawable.pScreen,
+                       nxagentWindowPriv(pWin)->clipShape);
+
+#ifndef NXAGENT_SHAPE
+      XShapeCombineMask(nxagentDisplay, nxagentWindow(pWin),
+                            ShapeClip, 0, 0, None, ShapeSet);
+#endif
+    }
+  }
+}
+#endif /* SHAPE */
+
+static int nxagentForceExposure(WindowPtr pWin, pointer ptr)
+{
+  RegionPtr exposedRgn;
+  BoxRec Box;
+  WindowPtr pRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+  if (pWin -> drawable.class != InputOnly)
+  {
+    Box.x1 = pWin->drawable.x;
+    Box.y1 = pWin->drawable.y;
+    Box.x2 = Box.x1 + pWin->drawable.width;
+    Box.y2 = Box.y1 + pWin->drawable.height;
+
+    exposedRgn = REGION_CREATE(pWin->drawable.pScreen, &Box, 1);
+    REGION_INTERSECT(pWin->drawable.pScreen, exposedRgn, exposedRgn, &pRoot->winSize);
+
+    if (exposedRgn != NULL && REGION_NOTEMPTY(pWin -> drawable.pScreen, exposedRgn) != 0)
+    {
+      miWindowExposures(pWin, exposedRgn, NullRegion);
+    }
+
+    REGION_DESTROY(pWin->drawable.pScreen, exposedRgn);
+  }
+
+  return WT_WALKCHILDREN;
+}
+
+void nxagentRefreshWindows(WindowPtr pWin)
+{
+  int action = 1;
+
+  TraverseTree(pWin, nxagentForceExposure, &action);
+}
+
+void nxagentUnmapWindows(void)
+{
+  int i;
+
+  if (nxagentOption(Fullscreen) == 1)
+  {
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+      if (nxagentDefaultWindows[i])
+      {
+        XUnmapWindow(nxagentDisplay, nxagentDefaultWindows[i]);
+      }
+    }
+  }
+
+  NXFlushDisplay(nxagentDisplay, NXFlushLink);
+}
+
+void nxagentMapDefaultWindows()
+{
+  int i;
+
+  for (i = 0; i < screenInfo.numScreens; i++)
+  {
+    WindowPtr pWin = WindowTable[i];
+
+    ScreenPtr pScreen = pWin -> drawable.pScreen;
+
+    MapWindow(pWin, serverClient);
+
+    if (nxagentOption(Rootless) == 0)
+    {
+      /*
+       * Show the NX splash screen.
+       */
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentMapDefaultWindows: Showing the splash window.\n");
+      #endif
+
+      nxagentShowSplashWindow(nxagentDefaultWindows[pScreen->myNum]);
+
+      /*
+       * Map the default window. Defer the mapping if the session is
+       * of shadow type. If no WM is running on the remote display,
+       * map the window soon anyway: this avoids a flickering effect
+       * on the !M logo if the shadow session is displayed from a
+       * Windows client.
+       */
+
+      if (nxagentOption(Shadow) == 0 || nxagentWMIsRunning == 0)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentMapDefaultWindows: Mapping default window id [%ld].\n",
+                    nxagentDefaultWindows[pScreen->myNum]);
+        #endif
+
+        XMapWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
+      }
+
+      /*
+       * Map and raise the input window.
+       */
+
+      XMapWindow(nxagentDisplay, nxagentInputWindows[pScreen->myNum]);
+
+      /*
+       * At reconnection the Input Window is
+       * raised in nxagentReconnectAllWindows,
+       * after the Root Window is mapped.
+       */
+
+      if (nxagentReconnectTrap == 0)
+      {
+        XRaiseWindow(nxagentDisplay, nxagentInputWindows[pScreen->myNum]);
+      }
+    }
+
+    /*
+     * Send a SetSelectionOwner request
+     * to notify of the agent start.
+     */
+
+    XSetSelectionOwner(nxagentDisplay, serverCutProperty,
+                           nxagentDefaultWindows[i], CurrentTime);
+  }
+
+  /*
+   * Map the icon window.
+   */
+
+  if (nxagentIconWindow != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
+                nxagentIconWindow);
+    #endif
+
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+
+    if (nxagentIpaq != 0)
+    {
+      XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                         DefaultScreen(nxagentDisplay));
+    }
+  }
+
+  /*
+   * Ensure that the fullscreen window gets the focus.
+   */
+
+  if (nxagentFullscreenWindow != 0)
+  {
+    XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
+                       RevertToParent, CurrentTime);
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentMapDefaultWindows: Completed mapping of default windows.\n");
+  #endif
+}
+
+Bool nxagentDisconnectAllWindows(void)
+{
+  Bool succeded = True;
+  int i;
+  WindowPtr pWin;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_WINDOW_DEBUG)
+  fprintf(stderr, "nxagentDisconnectAllWindows\n");
+  #endif
+
+  for (i = 0; i < screenInfo.numScreens; i++)
+  {
+    pWin = WindowTable[i];
+    nxagentTraverseWindow( pWin, nxagentDisconnectWindow, &succeded);
+    nxagentDefaultWindows[i] = None;
+  }
+
+  #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+  fprintf(stderr, "nxagentDisconnectAllWindows: all windows disconnected\n");
+  #endif
+
+  return succeded;
+}
+
+/*
+ * FIXME: We are giving up reconnecting those pointer
+ * that are not resource, and we are just disconnecting them.
+ * perhaps we could do better and reconnect them.
+ */
+
+void nxagentDisconnectWindow(pointer p0, XID x1, pointer p2)
+{
+  WindowPtr pWin = (WindowPtr)p0;
+  Bool*     pBool = (Bool*)p2;
+  CursorPtr pCursor = wCursor(pWin);
+  ScreenPtr pScreen = pWin -> drawable.pScreen;
+
+  if ((pCursor = wCursor(pWin)) &&
+         nxagentCursorPriv(pCursor, pScreen) &&
+           nxagentCursor(pCursor, pScreen))
+  {
+    #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG_disabled
+    char msg[] = "nxagentDisconnectWindow:";
+
+    nxagentPrintCursorInfo(pCursor, msg);
+    #endif
+
+    #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+    fprintf(stderr, "nxagentDisconnectWindow: window %p - disconnecting cursor %p ID %lx\n",
+                pWin, pCursor, nxagentCursor(pCursor, pScreen));
+    #endif
+
+    nxagentDisconnectCursor(pCursor, (XID)0, pBool);
+
+    if (*pBool == False)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentDisconnectWindow: WARNING failed disconnection of cursor at [%p]"
+                  " for window at [%p]: ignoring it.\n", (void*)pCursor, (void*)pWin);
+      #endif
+
+      *pBool = True;
+    }
+  }
+  #ifdef NXAGENT_RECONNECT_CURSOR_DEBUG
+  else if (pCursor)
+  {
+    fprintf(stderr, "nxagentDisconnectWindow: window %p - cursor %p already disconnected\n",
+                pWin, pCursor);
+  }
+  #endif
+
+  nxagentWindow(pWin) = None;
+
+  if (nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+  {
+    nxagentDestroyCorruptedResource((DrawablePtr) pWin, RT_NX_CORR_WINDOW);
+  }
+}
+
+Bool nxagentReconnectAllWindows(void *p0)
+{
+  int flexibility = *(int *) p0;
+
+  flexibility = flexibility;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_WINDOW_DEBUG)
+  fprintf(stderr, "nxagentReconnectAllWindows\n");
+  #endif
+
+  if (WindowTable[0] -> backgroundState == BackgroundPixmap &&
+          WindowTable[0] -> background.pixmap == NULL)
+  {
+    FatalError("nxagentReconnectAllWindows: correct the FIXME\n");
+  }
+
+  if (nxagentOption(Fullscreen))
+  {
+    WindowTable[0] -> origin.x = nxagentOption(RootX);
+    WindowTable[0] -> origin.y = nxagentOption(RootY);
+  }
+
+  if (!nxagentLoopOverWindows(nxagentReconnectWindow))
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentReconnectAllWindows: couldn't recreate windows\n");
+    #endif
+
+    return False;
+  }
+
+  #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+  XSync(nxagentDisplay, 0);
+  fprintf(stderr, "nxagentReconnectAllWindows: all windows recreated\n");
+  #endif
+
+  if (!nxagentLoopOverWindows(nxagentReconfigureWindow))
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentReconnectAllWindows: couldn't reconfigure windows\n");
+    #endif
+
+    return False;
+  }
+
+  /*
+   * After the Root Window has
+   * been mapped, the Input
+   * Windows is raised.
+   */
+
+  if (nxagentOption(Rootless) == 0)
+  {
+    int i;
+
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+      XRaiseWindow(nxagentDisplay, nxagentInputWindows[i]);
+    }
+  }
+
+  nxagentFlushConfigureWindow();
+
+  if (nxagentOption(Fullscreen))
+  {
+    WindowTable[0] -> origin.x = 0;
+    WindowTable[0] -> origin.y = 0;
+  }
+
+  #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  fprintf(stderr, "nxagentReconnectAllWindows: All windows reconfigured.\n");
+
+  #endif
+
+  if (nxagentInitClipboard(WindowTable[0]) == -1)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentReconnectAllWindows: WARNING! Couldn't initialize the clipboard.\n");
+    #endif
+
+    return False;
+  }
+
+  #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+
+  XSync(nxagentDisplay, 0);
+
+  fprintf(stderr, "nxagentReconnectAllWindows: Clipboard initialized.\n");
+
+  #endif
+
+  #ifdef VIEWPORT_FRAME
+
+  /*
+   * We move the viewport frames out of the way on the X server side.
+   */
+
+  if (nxagentViewportFrameLeft &&
+          nxagentViewportFrameRight &&
+              nxagentViewportFrameAbove &&
+                  nxagentViewportFrameBelow)
+  {
+    XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameLeft),
+                    -NXAGENT_FRAME_WIDTH, 0);
+    XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameRight),
+                    nxagentOption(RootWidth), 0);
+    XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameAbove),
+                    0, -NXAGENT_FRAME_WIDTH);
+    XMoveWindow(nxagentDisplay, nxagentWindow(nxagentViewportFrameBelow),
+                    0, nxagentOption(RootHeight));
+  }
+
+  #endif /* #ifdef VIEWPORT_FRAME */
+
+  return True;
+}
+
+Bool nxagentSetWindowCursors(void *p0)
+{
+  int flexibility = *(int *) p0;
+
+  flexibility = flexibility;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_WINDOW_DEBUG)
+  fprintf(stderr, "nxagentSetWindowCursors: Going to loop over the windows.\n");
+  #endif
+
+  if (!nxagentLoopOverWindows(nxagentReconfigureWindowCursor))
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentSetWindowCursors: WARNING! Couldn't configure all windows' cursors.\n");
+    #endif
+
+    return False;
+  }
+
+  #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+  fprintf(stderr, "nxagentLoopOverWindows: All cursors configured.\n");
+  #endif
+
+  nxagentReDisplayCurrentCursor();
+
+  return True;
+}
+
+static void nxagentTraverseWindow(
+  WindowPtr pWin,
+  void (*pF)(pointer, XID, pointer),
+  pointer p)
+{
+  pF(pWin, 0, p);
+
+  if (pWin -> nextSib)
+  {
+    nxagentTraverseWindow(pWin -> nextSib, pF, p);
+  }
+
+  if (pWin -> firstChild)
+  {
+    nxagentTraverseWindow(pWin -> firstChild, pF, p);
+  }
+}
+
+static Bool nxagentLoopOverWindows(void (*pF)(pointer, XID, pointer))
+{
+  int i;
+  Bool windowSuccess = True;
+  WindowPtr pWin;
+
+  for (i = 0; i < screenInfo.numScreens; i++)
+  {
+    pWin = WindowTable[i];
+    nxagentTraverseWindow(pWin, pF, &windowSuccess);
+  }
+
+  return windowSuccess;
+}
+
+static void nxagentReconnectWindow(pointer param0, XID param1, pointer data_buffer)
+{
+  WindowPtr pWin = (WindowPtr)param0;
+  Bool *pBool = (Bool*)data_buffer;
+  Visual *visual;
+  unsigned long mask;
+  XSetWindowAttributes attributes;
+  ColormapPtr pCmap;
+
+  if (!pWin || !*pBool)
+    return;
+
+  #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+  fprintf(stderr, "nxagentReconnectWindow: %p - ID %lx\n", pWin, nxagentWindow(pWin));
+  #endif
+
+  if (pWin->drawable.class == InputOnly) {
+    mask = CWEventMask;
+    visual = CopyFromParent;
+  }
+  else {
+    mask = CWEventMask | CWBackingStore;
+
+    attributes.backing_store = NotUseful;
+
+    if (pWin->optional)
+    {
+      mask |= CWBackingPlanes | CWBackingPixel;
+      attributes.backing_planes = pWin->optional->backingBitPlanes;
+      attributes.backing_pixel = pWin->optional->backingPixel;
+    }
+
+/*
+FIXME: Do we need to set save unders attribute here?
+*/
+    if (nxagentSaveUnder == True)
+    {
+      mask |= CWSaveUnder;
+      attributes.save_under = pWin->saveUnder;
+    }
+
+    if (pWin->parent) {
+        if (pWin->optional && pWin->optional->visual != wVisual(pWin->parent)) {
+        visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+        mask |= CWColormap;
+        if (pWin->optional->colormap) {
+          pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+          attributes.colormap = nxagentColormap(pCmap);
+        }
+        else
+          attributes.colormap = nxagentDefaultVisualColormap(visual);
+      }
+      else
+        visual = CopyFromParent;
+    }
+    else { /* root windows have their own colormaps at creation time */
+      visual = nxagentVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+      pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+      mask |= CWColormap;
+      attributes.colormap = nxagentColormap(pCmap);
+    }
+  }
+
+  if (mask & CWEventMask)
+  {
+    nxagentGetEventMask(pWin, (Mask*)&attributes.event_mask);
+  }
+  #ifdef WARNING
+  else
+  {
+    attributes.event_mask = NoEventMask;
+  }
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectWindow: Going to create new window.\n");
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectWindow: Recreating %swindow at %p current event mask = %lX mask & CWEventMask = %ld "
+              "event_mask = %lX\n",
+                  nxagentWindowTopLevel(pWin) ? "toplevel " : "", (void*)pWin, pWin -> eventMask,
+                      mask & CWEventMask, attributes.event_mask);
+  #endif
+
+  /*
+   * FIXME: This quick hack is intended to solve a
+   *        problem of NXWin X server for windows.
+   *        The NXWin minimize the windows moving them
+   *        out of the screen area, this behaviour
+   *        can cause problem when a rootless session
+   *        is disconnected and an apps is minimized.
+   *        It will be solved with new Xorg version of
+   *        the NXWin server.
+   */
+
+  if (nxagentOption(Rootless))
+  {
+    if (pWin -> drawable.x == -32000 && pWin -> drawable.y == -32000)
+    {
+      pWin -> drawable.x = (pWin -> drawable.pScreen -> width - pWin -> drawable.width) / 2;
+      pWin -> drawable.y = (pWin -> drawable.pScreen -> height - pWin -> drawable.height) /2;
+    }
+
+    if (pWin -> origin.x == -32000 && pWin -> origin.y == -32000)
+    {
+      pWin -> origin.x = (pWin -> drawable.pScreen -> width - pWin -> drawable.width) / 2;
+      pWin -> origin.y = (pWin -> drawable.pScreen -> height - pWin -> drawable.height) / 2;
+    }
+  }
+
+  nxagentWindow(pWin) = XCreateWindow(nxagentDisplay,
+                                      nxagentWindowParent(pWin),
+                                      pWin->origin.x -
+                                      wBorderWidth(pWin),
+                                      pWin->origin.y -
+                                      wBorderWidth(pWin),
+                                      pWin->drawable.width,
+                                      pWin->drawable.height,
+                                      pWin->borderWidth,
+                                      pWin->drawable.depth,
+                                      pWin->drawable.class,
+                                      visual,
+                                      mask,
+                                      &attributes);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentReconnectWindow: Created new window with id [%ld].\n",
+              nxagentWindowPriv(pWin)->window);
+  #endif
+
+  /*
+   * We have to set the WM_DELETE_WINDOW protocols
+   * on every top level window, because we don't know
+   * if a client handles this.
+   */
+
+  if (nxagentOption(Rootless) && (pWin != WindowTable[0]))
+  {
+    if (nxagentWindowTopLevel(pWin))
+    {
+      Atom prop = nxagentMakeAtom("WM_PROTOCOLS", strlen("WM_PROTOCOLS"), True);
+
+      XlibAtom atom = nxagentMakeAtom("WM_DELETE_WINDOW", strlen("WM_DELETE_WINDOW"), True);
+
+      XSetWMProtocols(nxagentDisplay, nxagentWindow(pWin), &atom, 1);
+
+      nxagentAddPropertyToList(prop, pWin);
+    }
+
+    nxagentExportAllProperty(pWin);
+
+    if (nxagentWindowTopLevel(pWin))
+    {
+      int ret;
+      Atom type;
+      int format;
+      unsigned long nItems, bytesLeft;
+      XSizeHints *props, hints;
+      unsigned char *data = NULL;
+
+      hints.flags = 0;
+
+      ret = GetWindowProperty(pWin,
+                                  XA_WM_NORMAL_HINTS,
+                                      0, sizeof(XSizeHints),
+                                          False, XA_WM_SIZE_HINTS,
+                                              &type, &format, &nItems, &bytesLeft, &data);
+
+      props = (XSizeHints*) data;
+
+      if (ret == Success &&
+              ((format >> 3) * nItems) == sizeof(XSizeHints) &&
+                  bytesLeft == 0 &&
+                      type == XA_WM_SIZE_HINTS)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentReconnectWindow: setting WMSizeHints on window %p [%lx - %lx].\n",
+                    (void*)pWin, pWin -> drawable.id, nxagentWindow(pWin));
+        #endif
+
+        hints = *props;
+      }
+      else
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentReconnectWindow: Failed to get property WM_NORMAL_HINTS on window %p\n",
+                    (void*)pWin);
+        #endif
+      }
+
+      hints.flags |= (USPosition | PWinGravity);
+      hints.x = pWin -> drawable.x;
+      hints.y = pWin -> drawable.y;
+      hints.win_gravity = StaticGravity;
+
+      XSetWMNormalHints(nxagentDisplay,
+                           nxagentWindow(pWin),
+                              &hints);
+    }
+  }
+
+  if (nxagentDrawableStatus((DrawablePtr) pWin) == NotSynchronized)
+  {
+    nxagentAllocateCorruptedResource((DrawablePtr) pWin, RT_NX_CORR_WINDOW);
+  }
+}
+
+static void nxagentReconfigureWindowCursor(pointer param0, XID param1, pointer data_buffer)
+{
+  WindowPtr pWin = (WindowPtr)param0;
+  Bool *pBool = (Bool*)data_buffer;
+  CursorPtr   pCursor;
+  ScreenPtr   pScreen = pWin -> drawable.pScreen;
+
+  if (!pWin || !*pBool || !(pCursor = wCursor(pWin)) ||
+          !(nxagentCursorPriv(pCursor, pScreen)))
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconfigureWindowCursor: %p - ID %lx geometry (%d,%d,%d,%d) "
+                  "cursor %p - ID %lx\n",
+                  pWin, nxagentWindow(pWin),
+                  pWin -> drawable.x,
+                  pWin -> drawable.y,
+                  pWin -> drawable.width,
+                  pWin -> drawable.height,
+                  pCursor, nxagentCursor(pCursor, pScreen));
+  #endif
+
+  if (nxagentCursor(pCursor, pScreen) == None)
+  {
+    #ifdef NXAGENT_RECONNECT_WINDOW_DEBUG
+    fprintf(stderr, "nxagentReconfigureWindowCursor: reconnecting valid cursor %lx\n",
+                (void*)pCursor);
+    #endif
+
+    nxagentReconnectCursor(pCursor, 0, pBool);
+
+    if (!*pBool)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentReconfigureWindowCursor: WARNING "
+                  "failed reconnection of cursor at [%p] for window at [%p]: ignoring it.\n",
+                      (void*)pCursor, (void*)pWin);
+      #endif
+
+      *pBool = True;
+    }
+  }
+
+  if (nxagentOption(Rootless))
+  {
+    XDefineCursor(nxagentDisplay,nxagentWindow(pWin),nxagentCursor(pCursor,pScreen));
+  }
+}
+
+static void nxagentReconfigureWindow(pointer param0, XID param1, pointer data_buffer)
+{
+  WindowPtr pWin = (WindowPtr)param0;
+  unsigned long mask = 0;
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentReconfigureWindow: pWin %p - ID %lx\n", pWin, nxagentWindow(pWin));
+  #endif
+
+  if (pWin -> drawable.class == InputOnly)
+    mask = CWWinGravity | CWEventMask | CWDontPropagate | CWOverrideRedirect | CWCursor;
+  else
+    mask = CWBackPixmap | CWBackPixel | CWBorderPixmap | CWBorderPixel |
+         CWBitGravity | CWWinGravity | CWBackingStore | CWBackingPlanes |
+         CWBackingPixel | CWOverrideRedirect | CWSaveUnder | CWEventMask |
+         CWDontPropagate | CWColormap | CWCursor;
+
+  nxagentChangeWindowAttributes(pWin, mask);
+
+#ifdef SHAPE
+  if (nxagentWindowPriv(pWin) -> boundingShape)
+  {
+    REGION_DESTROY(pWin -> drawable.pScreen,
+                   nxagentWindowPriv(pWin) -> boundingShape);
+    nxagentWindowPriv(pWin) -> boundingShape = NULL;
+  }
+
+  if (nxagentWindowPriv(pWin) -> clipShape)
+  {
+    REGION_DESTROY(pWin -> drawable.pScreen,
+                   nxagentWindowPriv(pWin) -> clipShape);
+    nxagentWindowPriv(pWin) -> clipShape = NULL;
+  }
+  nxagentShapeWindow(pWin);
+#endif
+
+  if (pWin != WindowTable[0])
+  {
+    if (pWin->realized)
+    {
+        nxagentRealizeWindow (pWin);
+    }
+    else if (pWin->mapped)
+    {
+      XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+    }
+    else if (nxagentOption(Rootless) && pWin -> overrideRedirect == 0 &&
+                 nxagentWindowTopLevel(pWin) && nxagentIsIconic(pWin))
+    {
+      MapWindow(pWin, serverClient);
+      XIconifyWindow(nxagentDisplay, nxagentWindow(pWin), pWin -> drawable.pScreen -> myNum);
+    }
+  }
+  else if (nxagentOption(Rootless) == 0)
+  {
+    /*
+     * Map the root window.
+     */
+
+    XMoveWindow(nxagentDisplay, nxagentWindow(pWin),
+                    nxagentOption(RootX), nxagentOption(RootY));
+
+    XMapWindow(nxagentDisplay, nxagentWindow(pWin));
+  }
+}
+
+Bool nxagentCheckIllegalRootMonitoring(WindowPtr pWin, Mask mask)
+{
+  Mask invalidMask = SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask;
+
+  if (nxagentOption(Rootless) &&
+        pWin == WindowTable[0] &&
+          (mask & invalidMask))
+  {
+    return True;
+  }
+
+  return False;
+}
+
+#ifdef TEST
+
+Bool nxagentCheckWindowIntegrity(WindowPtr pWin)
+{
+  Bool integrity = True;
+  XImage *image;
+  char *data;
+  int format;
+  unsigned long plane_mask = AllPlanes;
+  unsigned int width, height, length, depth;
+
+  width = pWin -> drawable.width;
+  height = pWin -> drawable.height;
+  depth = pWin -> drawable.depth;
+  format = (depth == 1) ? XYPixmap : ZPixmap;
+
+  if (width && height)
+  {
+     length = nxagentImageLength(width, height, format, 0, depth);
+     data = malloc(length);
+
+     if (data == NULL)
+     {
+       FatalError("nxagentCheckWindowIntegrity: Failed to allocate a buffer of size %d.\n", length);
+     }
+
+     memset(data, 0, length);
+
+     image = XGetImage(nxagentDisplay, nxagentWindow(pWin), 0, 0,
+                                   width, height, plane_mask, format);
+     if (image == NULL)
+     {
+       fprintf(stderr, "XGetImage: Failed.\n");
+       return False;
+     }
+
+     fbGetImage((DrawablePtr)pWin, 0, 0, width, height, format, plane_mask, data);
+
+     if (image && memcmp(image->data, data, length) != 0)
+     {
+       #ifdef TEST
+       int i;
+       char *p, *q;
+       #endif
+
+       integrity = False;
+
+       #ifdef TEST
+       for (i = 0, p = image->data, q = data; i < length; i++)
+       {
+         if (p[i] != q[i])
+         {
+           fprintf(stderr, "[%d] %d - %d !!!!!!!!!!!!!!!!!!! **************** !!!!!!!!!!!!!!!!!\n", i, p[i], q[i]);
+         }
+         else
+         {
+           fprintf(stderr, "[%d] %d - %d\n", i, p[i], q[i]);
+         }
+       }
+       #endif
+
+       #ifdef WARNING
+       fprintf(stderr, "nxagentCheckWindowIntegrity: Window %p width %d, height %d, has been realized "
+                 "but the data buffer still differs.\n", (void*) pWin, width, height);
+       fprintf(stderr, "nxagentCheckWindowIntegrity: bytes_per_line = %d byte pad %d format %d.\n",
+                 image -> bytes_per_line, nxagentImagePad(width, height, 0, depth), image->format);
+
+       fprintf(stderr, "nxagentCheckWindowIntegrity: image is corrupted!!\n");
+       #endif
+     }
+     else
+     {
+       #ifdef WARNING
+       fprintf(stderr, "nxagentCheckWindowIntegrity: Window %p has been realized "
+                   "now remote and frambuffer data are synchronized.\n", (void*) pWin);
+       #endif
+     }
+
+     if (image)
+     {
+       XDestroyImage(image);
+     }
+
+     if (data)
+     {
+       free(data);
+     }
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCheckWindowIntegrity: ignored window %p with geometry (%d,%d).\n",
+                (void*) pWin, width, height);
+    #endif
+  }
+
+  return integrity;
+}
+
+#endif
+
+Bool nxagentIsIconic(WindowPtr pWin)
+{
+  int           iReturn;
+  unsigned long ulReturnItems;
+  unsigned long ulReturnBytesLeft;
+  Atom          atomReturnType;
+  int           iReturnFormat;
+  unsigned char *pszReturnData = NULL;
+
+  if (!wUserProps (pWin))
+  {
+    return 0;
+  }
+
+  iReturn = GetWindowProperty(pWin, MakeAtom("WM_STATE", 8, False), 0, sizeof(CARD32), False,
+                              AnyPropertyType, &atomReturnType, &iReturnFormat,
+                              &ulReturnItems, &ulReturnBytesLeft, &pszReturnData);
+
+  if (iReturn == Success)
+  {
+    return (((CARD32 *)pszReturnData)[0] == IconicState);
+  }
+  else
+  {
+    return 0;
+  }
+}
+
+void nxagentSetTopLevelEventMask(pWin)
+     WindowPtr pWin;
+{
+  unsigned long mask = CWEventMask;
+  XSetWindowAttributes attributes;
+
+  if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin))
+  {
+    nxagentGetEventMask(pWin, (Mask*)&attributes.event_mask);
+
+    XChangeWindowAttributes(nxagentDisplay, nxagentWindow(pWin), mask, &attributes);
+  }
+}
+
+/*
+ * This function must return 1 if we want the
+ * exposures to be sent as the window's extents.
+ * This is actually a harmless, but useful hack,
+ * as it speeds up the window redraws considera-
+ * bly, when using a very popular WM theme.
+ */
+
+int nxagentExtentsPredicate(int total)
+{
+  #ifdef TEST
+
+  if (total == 6 || total == 11 || total == 10)
+  {
+    fprintf(stderr, "nxagentExtentsPredicate: WARNING! Returning [%d] with [%d] rectangles.\n",
+                (total == 6 || total == 11 || total == 10), total);
+  }
+
+  #endif
+
+  return (total == 6 || total == 11 || total == 10);
+}
+
+void nxagentFlushConfigureWindow(void)
+{
+  ConfiguredWindowStruct *index;
+  XWindowChanges changes;
+  int i;
+  int j;
+
+  index = nxagentConfiguredWindowList;
+
+  while (index)
+  {
+    if (index -> next == NULL)
+    {
+      break;
+    }
+
+    index = index -> next;
+  }
+
+  while (index)
+  {
+    ConfiguredWindowStruct *tmp;
+
+    WindowPtr pWin = index -> pWin;
+    unsigned int valuemask = index -> valuemask;
+
+    if (pWin && valuemask)
+    {
+      nxagentConfigureWindow(pWin, valuemask);
+    }
+
+    tmp = index;
+
+    if (index == nxagentConfiguredWindowList)
+    {
+      free(tmp);
+      break;
+    }
+
+    index = index -> prev;
+    free(tmp);
+  }
+
+  nxagentConfiguredWindowList = NULL;
+
+  for (j = 0; j < nxagentExposeQueue.length; j++)
+  {
+    i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+    if (nxagentExposeQueue.exposures[i].synchronize == 1)
+    {
+      changes.x = nxagentExposeQueue.exposures[i].serial;
+      changes.y = -2;
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentFlushConfigureWindow: Sending synch ConfigureWindow for "
+                  "index [%d] serial [%d].\n", i, nxagentExposeQueue.exposures[i].serial);
+      #endif
+
+      XConfigureWindow(nxagentDisplay, nxagentConfiguredSynchroWindow,
+                           CWX | CWY, &changes);
+
+      nxagentExposeQueue.exposures[i].synchronize = 0;
+    }
+  }
+
+  nxagentSendDeferredBackgroundExposures();
+
+  return;
+}
+
+void nxagentPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+/*
+FIXME: Do we need this here?
+
+  nxagentFlushConfigureWindow();
+*/
+
+  return;
+}
+
+void nxagentAddConfiguredWindow(WindowPtr pWin, unsigned int valuemask)
+{
+  unsigned int mask;
+
+  mask = valuemask & (CWParent | CWX | CWY | CWWidth | CWHeight |
+                   CWBorderWidth | CWStackingOrder | CW_Map | CW_Update | CW_Shape);
+
+  valuemask &= ~(CWParent | CWX | CWY | CWWidth | CWHeight | CWBorderWidth | CWStackingOrder);
+
+  if (mask & CWX &&
+          nxagentWindowPriv(pWin)->x !=
+              pWin->origin.x - wBorderWidth(pWin))
+  {
+    valuemask |= CWX;
+  }
+
+  if (mask & CWY &&
+          nxagentWindowPriv(pWin)->y !=
+              pWin->origin.y - wBorderWidth(pWin))
+  {
+    valuemask |= CWY;
+  }
+
+  if (mask & CWWidth &&
+          nxagentWindowPriv(pWin)->width !=
+              pWin->drawable.width)
+  {
+    valuemask |= CWWidth;
+  }
+
+  if (mask & CWHeight &&
+          nxagentWindowPriv(pWin)->height !=
+              pWin->drawable.height)
+  {
+    valuemask |= CWHeight;
+  }
+
+  if (mask & CWBorderWidth &&
+          nxagentWindowPriv(pWin)->borderWidth !=
+              pWin->borderWidth)
+  {
+    valuemask |= CWBorderWidth;
+  }
+
+  if (mask & CWStackingOrder &&
+          nxagentWindowPriv(pWin)->siblingAbove !=
+              nxagentWindowSiblingAbove(pWin))
+  {
+    valuemask |= CWStackingOrder;
+  }
+
+  if (nxagentConfiguredWindowList == NULL)
+  {
+    nxagentConfiguredWindowList = malloc(sizeof(ConfiguredWindowStruct));
+    nxagentConfiguredWindowList -> next = NULL;
+    nxagentConfiguredWindowList -> prev = NULL;
+
+    nxagentConfiguredWindowList -> pWin = pWin;
+  }
+  else
+  {
+    ConfiguredWindowStruct *tmp;
+
+    tmp = malloc(sizeof(ConfiguredWindowStruct));
+
+    tmp -> next = nxagentConfiguredWindowList;
+    nxagentConfiguredWindowList -> prev = tmp;
+    tmp -> prev = NULL;
+    nxagentConfiguredWindowList = tmp;
+    nxagentConfiguredWindowList -> pWin = pWin;
+  }
+
+  nxagentConfiguredWindowList -> valuemask = valuemask;
+
+  return;
+}
+
+void nxagentDeleteConfiguredWindow(WindowPtr pWin)
+{
+  ConfiguredWindowStruct *index, *previous, *tmp;
+
+  index = nxagentConfiguredWindowList;
+
+  while (index)
+  {
+    WindowPtr pDel = index -> pWin;
+
+    if (pDel == pWin)
+    {
+      if (index -> prev == NULL && index -> next == NULL)
+      {
+        free(nxagentConfiguredWindowList);
+        nxagentConfiguredWindowList = NULL;
+
+        return;
+      }
+      else if (index -> prev == NULL)
+      {
+        tmp = nxagentConfiguredWindowList;
+        index = nxagentConfiguredWindowList = tmp -> next;
+        free(tmp);
+        nxagentConfiguredWindowList -> prev = NULL;
+
+        continue;
+      }
+      else if (index -> next == NULL)
+      {
+        tmp = index;
+        index = index -> prev;
+        free(tmp);
+        index -> next = NULL;
+
+        return;
+      }
+
+      previous = index -> prev;
+      tmp = index;
+      index = index -> next;
+      previous -> next = index;
+      index -> prev = previous;
+      free(tmp);
+
+      continue;
+    }
+
+    index = index -> next;
+  }
+
+  return;
+}
+
+void nxagentEmptyBackingStoreRegion(pointer param0, XID param1, pointer data_buffer)
+{
+  WindowPtr pWin = (WindowPtr) param0;
+
+  miBSWindowPtr pBackingStore = (miBSWindowPtr)pWin->backStorage;
+
+  if (pBackingStore != NULL)
+  {
+    REGION_EMPTY(pWin -> pScreen, &pBackingStore->SavedRegion);
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentEmptyBackingStoreRegion: Emptying saved region for window at [%p].\n", (void*) pWin);
+    #endif
+
+    if (pBackingStore -> pBackingPixmap != NULL)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentEmptyBackingStoreRegion: Emptying corrupted region for drawable at [%p].\n",
+                  (void*) pBackingStore -> pBackingPixmap);
+      #endif
+
+      nxagentUnmarkCorruptedRegion((DrawablePtr) pBackingStore -> pBackingPixmap, NullRegion);
+    }
+  }
+}
+
+void nxagentEmptyAllBackingStoreRegions(void)
+{
+  if (nxagentLoopOverWindows(nxagentEmptyBackingStoreRegion) == 0)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentEmptyAllSavedRegions: Failed to empty backing store saved regions.\n");
+    #endif
+  }
+}
+
+void nxagentInitBSPixmapList(void)
+{
+  memset(nxagentBSPixmapList, 0, BSPIXMAPLIMIT * sizeof( StoringPixmapPtr));
+}
+
+int nxagentAddItemBSPixmapList(unsigned long id, PixmapPtr pPixmap, WindowPtr pWin, int bsx, int bsy)
+{
+  int i;
+
+  for (i = 0; i < BSPIXMAPLIMIT; i++)
+  {
+    if (nxagentBSPixmapList[i] == NULL)
+    {
+      nxagentBSPixmapList[i] = malloc(sizeof(StoringPixmapRec));
+
+      if (nxagentBSPixmapList[i] == NULL)
+      {
+        FatalError("nxagentAddItemBSPixmapList: Failed to allocate memory for nxagentBSPixmapList.\n");
+      }
+
+      nxagentBSPixmapList[i] -> storingPixmapId = id;
+      nxagentBSPixmapList[i] -> pStoringPixmap = pPixmap;
+      nxagentBSPixmapList[i] -> pSavedWindow = pWin;
+      nxagentBSPixmapList[i] -> backingStoreX = bsx;
+      nxagentBSPixmapList[i] -> backingStoreY = bsy;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentAddItemBSPixmapList: Added Pixmap with id [%lu] to nxagentBSPixmapList.\n", id);
+      #endif
+
+      return 1;
+    }
+
+    if (nxagentBSPixmapList[i] -> storingPixmapId == id)
+    {
+      nxagentBSPixmapList[i] -> pStoringPixmap = pPixmap;
+      nxagentBSPixmapList[i] -> pSavedWindow = pWin;
+      nxagentBSPixmapList[i] -> backingStoreX = bsx;
+      nxagentBSPixmapList[i] -> backingStoreY = bsy;
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentAddItemBSPixmapList: Updated existing item for id [%lu].\n", id);
+      #endif
+
+      return 1;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentAddItemBSPixmapList: WARNING! List item full.\n");
+  #endif
+
+  return 0;
+}
+
+int nxagentRemoveItemBSPixmapList(unsigned long pixmapId)
+{
+  int i;
+  int j;
+
+  if (pixmapId == 0 || nxagentBSPixmapList[0] == NULL)
+  {
+    return 0;
+  }
+
+  for (i = 0; i < BSPIXMAPLIMIT; i++)
+  {
+    if ((nxagentBSPixmapList[i] != NULL) &&
+            (nxagentBSPixmapList[i] -> storingPixmapId == pixmapId))
+    {
+      free(nxagentBSPixmapList[i]);
+      nxagentBSPixmapList[i] = NULL;
+
+      if (i < BSPIXMAPLIMIT - 1)
+      {
+        for (j = i; j < BSPIXMAPLIMIT -1; j++)
+        {
+          nxagentBSPixmapList[j] = nxagentBSPixmapList[j + 1];
+        }
+
+        if (nxagentBSPixmapList[j] == nxagentBSPixmapList[j - 1])
+        {
+          nxagentBSPixmapList[j] = NULL;
+        }
+      }
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentRemoveItemBSPixmapList: Removed Pixmap with id [%lu] from list.\n",
+                  pixmapId);
+      #endif
+
+      return 1;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRemoveItemBSPixmapList: WARNING! Can't remove item [%lu]: item not found.\n",
+              pixmapId);
+  #endif
+
+  return 0;
+}
+
+int nxagentEmptyBSPixmapList()
+{
+  int i;
+
+  for (i = 0; i < BSPIXMAPLIMIT; i++)
+  {
+    if (nxagentBSPixmapList[i] != NULL)
+    {
+      free(nxagentBSPixmapList[i]);
+      nxagentBSPixmapList[i] = NULL;
+    }
+  }
+
+  return 1;
+}
+
+StoringPixmapPtr nxagentFindItemBSPixmapList(unsigned long pixmapId)
+{
+  int i;
+
+  for (i = 0; i < BSPIXMAPLIMIT; i++)
+  {
+    if ((nxagentBSPixmapList[i] != NULL) &&
+            (nxagentBSPixmapList[i] -> storingPixmapId == pixmapId))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentFindItemBSPixmapList: pixmapId [%lu].\n", pixmapId);
+      fprintf(stderr, "nxagentFindItemBSPixmapList: nxagentBSPixmapList[%d] -> storingPixmapId [%lu].\n",
+                  i, nxagentBSPixmapList[i] -> storingPixmapId);
+      #endif
+
+      return nxagentBSPixmapList[i];
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentFindItemBSPixmapList: WARNING! Item not found.\n");
+  #endif
+  
+  #ifdef TEST
+  fprintf(stderr, "nxagentFindItemBSPixmapList: Pixmap with id [%lu] not found.\n",
+              pixmapId);
+  fprintf(stderr, "nxagentBSPixmapList[%d] = [%p].\n",
+              i, (void *) nxagentBSPixmapList[i]);
+  #endif
+
+  return NULL;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
new file mode 100644
index 000000000..239d558b4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -0,0 +1,300 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __Window_H__
+#define __Window_H__
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Pixmaps.h"
+
+#include "validate.h"
+
+typedef struct
+{
+  Window window;
+  int x;
+  int y;
+  unsigned int width;
+  unsigned int height;
+  unsigned int borderWidth;
+  Window siblingAbove;
+  int backingStore;
+#ifdef SHAPE
+  RegionPtr boundingShape;
+  RegionPtr clipShape;
+#endif /* SHAPE */
+
+  void *pPicture;
+
+  /*
+   * Set if the window is mapped
+   * on the remote server.
+   */
+
+  int isMapped;
+
+  /*
+   * Set if the window on the remote
+   * server is redirected by using
+   * the composite extension.
+   */
+
+  int isRedirected;
+
+  int visibilityState;
+
+  RegionPtr corruptedRegion;
+
+  int hasTransparentChildren;
+
+  int containGlyphs;
+
+  int deferredBackgroundExpose;
+
+  XID corruptedId;
+
+  PixmapPtr synchronizationBitmap;
+
+  Time corruptedTimestamp;
+
+  SplitResourcePtr splitResource;
+
+} nxagentPrivWindowRec;
+
+typedef nxagentPrivWindowRec *nxagentPrivWindowPtr;
+
+typedef struct
+{
+  unsigned long storingPixmapId;
+
+  PixmapPtr pStoringPixmap;
+
+  WindowPtr pSavedWindow;
+
+  int backingStoreX;
+
+  int backingStoreY;
+
+} StoringPixmapRec;
+
+typedef StoringPixmapRec *StoringPixmapPtr;
+
+int nxagentAddItemBSPixmapList(unsigned long, PixmapPtr, WindowPtr, int, int);
+int nxagentRemoveItemBSPixmapList(unsigned long);
+void nxagentInitBSPixmapList(void);
+int nxagentEmptyBSPixmapList(void);
+StoringPixmapPtr nxagentFindItemBSPixmapList (unsigned long);
+
+extern int nxagentWindowPrivateIndex;
+
+#define nxagentWindowPriv(pWin) \
+  ((nxagentPrivWindowPtr)((pWin)->devPrivates[nxagentWindowPrivateIndex].ptr))
+
+#define nxagentWindow(pWin) (nxagentWindowPriv(pWin)->window)
+
+/*
+ * Window is either a child of our root
+ * or a child of the root of the real X
+ * server.
+ */
+
+#define nxagentWindowParent(pWin) \
+    (nxagentOption(Rootless) ? \
+         nxagentRootlessWindowParent(pWin) : \
+             ((pWin)->parent ? \
+                 nxagentWindow((pWin)->parent) : \
+                     nxagentDefaultWindows[pWin->drawable.pScreen->myNum]))
+
+/*
+ * True if this is a top level window.
+ */
+
+#define nxagentWindowTopLevel(pWin) \
+    (pWin && (pWin -> parent == NULL || \
+         pWin->parent == nxagentRootlessWindow))
+
+#define nxagentWindowSiblingAbove(pWin) \
+  ((pWin)->prevSib ? nxagentWindow((pWin)->prevSib) : None)
+
+#define nxagentWindowSiblingBelow(pWin) \
+  ((pWin)->nextSib ? nxagentWindow((pWin)->nextSib) : None)
+
+#define nxagentWindowCorruptedRegion(pWin) \
+  (nxagentWindowPriv(pWin) -> corruptedRegion)
+
+#define nxagentWindowContainGlyphs(pWin) \
+  (nxagentWindowPriv(pWin) -> containGlyphs)
+
+#define nxagentWindowTimestamp(pWin) \
+  (nxagentWindowPriv(pWin) -> corruptedTimestamp)
+
+#define nxagentWindowIsVisible(pWin) \
+  ((pWin) -> viewable == 1 && \
+      (pWin) -> drawable.class != InputOnly && \
+          (pWin) -> visibility != VisibilityFullyObscured)
+
+#define nxagentDefaultWindowIsVisible() \
+              (nxagentVisibility != VisibilityFullyObscured)
+
+#define CWParent CWSibling
+#define CWStackingOrder CWStackMode
+
+#define CW_Map    (1 << 15)
+#define CW_Update (1 << 16)
+#define CW_Shape  (1 << 17)
+#define CW_RootlessRestack  (1 << 18)
+
+/*
+ * This force the agent to send exposures
+ * for all windows.
+ */
+
+#define nxagentRefreshScreen() \
+do\
+{\
+  nxagentRefreshWindows(WindowTable[0]);\
+} while (0)
+
+WindowPtr nxagentWindowPtr(Window window);
+
+extern Atom serverCutProperty;
+
+/*
+ * If the rectangles in an exposed region exceed
+ * the number of 4, we let the function decide if
+ * it is better to send the window extents rather
+ * than the rectangles in the region.
+ */
+
+int nxagentExtentsPredicate(int total);
+
+/*
+ * Agent's nested window procedures. Look also
+ * at Rootless.h for the rootless counterparts.
+ */
+
+Bool nxagentCreateWindow(WindowPtr pWin);
+
+Bool nxagentDestroyWindow(WindowPtr pWin);
+
+Bool nxagentPositionWindow(WindowPtr pWin, int x, int y);
+
+Bool nxagentChangeWindowAttributes(WindowPtr pWin, unsigned long mask);
+
+Bool nxagentRealizeWindow(WindowPtr pWin);
+
+Bool nxagentUnrealizeWindow(WindowPtr pWin);
+
+Bool nxagentCheckIllegalRootMonitoring(WindowPtr pWin, Mask mask);
+
+void nxagentWindowExposures(WindowPtr pWin, RegionPtr pRgn, RegionPtr other_exposed);
+
+void nxagentPaintWindowBackground(WindowPtr pWin, RegionPtr pRegion, int what);
+
+void nxagentPaintWindowBorder(WindowPtr pWin, RegionPtr pRegion, int what);
+
+void nxagentCopyWindow(WindowPtr pWin, xPoint oldOrigin, RegionPtr oldRegion);
+
+void nxagentClipNotify(WindowPtr pWin, int dx, int dy);
+
+void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib);
+
+void nxagentReparentWindow(WindowPtr pWin, WindowPtr pOldParent);
+
+void nxagentRefreshWindows(WindowPtr pWin);
+
+void nxagentSetTopLevelEventMask(WindowPtr pWin);
+
+void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn);
+
+void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift);
+
+#ifdef VIEWPORT_FRAME
+
+void nxagentUpdateViewportFrame(int x, int y, int w, int h);
+
+#else /* #ifdef VIEWPORT_FRAME */
+
+#define nxagentUpdateViewportFrame(x, y, w, h)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+void nxagentUnmapWindows(void);
+
+void nxagentMapDefaultWindows(void);
+
+Bool nxagentSetWindowCursors(void *p0);
+
+/*
+ * The ConfigureWindow procedure has not
+ * a pointer in the screen structure.
+ */
+
+void nxagentConfigureWindow(WindowPtr pWin, unsigned int mask);
+
+/*
+ * Used to track nxagent window's visibility.
+ */
+
+extern int nxagentVisibility;
+extern unsigned long nxagentVisibilityTimeout;
+extern Bool nxagentVisibilityStop;
+
+/*
+ * Return the pointer to the window given the
+ * remote id. It tries to match the id from
+ * the last matched window before iterating
+ * through the hierarchy.
+ */
+
+WindowPtr nxagentGetWindowFromID(Window id);
+
+/*
+ * Handle the shape bitmap for windows.
+ */
+
+#ifdef SHAPE
+
+void nxagentShapeWindow(WindowPtr pWin);
+
+#endif
+
+extern Window nxagentConfiguredSynchroWindow;
+extern Bool nxagentExposeArrayIsInitialized;
+
+typedef struct _ConfiguredWindow
+{
+  WindowPtr pWin;
+  struct _ConfiguredWindow *next;
+  struct _ConfiguredWindow *prev;
+  unsigned int valuemask;
+} ConfiguredWindowStruct;
+
+ConfiguredWindowStruct *nxagentConfiguredWindowList;
+
+void nxagentPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind);
+
+void nxagentFlushConfigureWindow(void);
+
+void nxagentAddConfiguredWindow(WindowPtr pWin, unsigned int valuemask);
+
+void nxagentDeleteConfiguredWindow(WindowPtr pWin);
+
+void nxagentEmptyAllBackingStoreRegions(void);
+
+#endif /* __Window_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
new file mode 100644
index 000000000..c49f1587f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
@@ -0,0 +1,2073 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include    <X11/X.h>
+#include    "scrnintstr.h"
+#include    "windowstr.h"
+#include    <X11/fonts/font.h>
+#include    "dixfontstr.h"
+#include    <X11/fonts/fontstruct.h>
+#include    "mi.h"
+#include    "regionstr.h"
+#include    "globals.h"
+#include    "gcstruct.h"
+#include    "damage.h"
+#include    "damagestr.h"
+#ifdef COMPOSITE
+#include    "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+    priv->mem = real->mem; \
+    real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+    real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+    ((a)->x1 == (b)->x1 && \
+     (a)->y1 == (b)->y1 && \
+     (a)->x2 == (b)->x2 && \
+     (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x)	ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) \
+    ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
+
+#define pixmapDamage(pPixmap)		damagePixPriv(pPixmap)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+    PixmapPtr   pPixmap;
+    
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	ScreenPtr   pScreen = pDrawable->pScreen;
+
+	pPixmap = 0;
+	if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+	    && ((WindowPtr)pDrawable)->viewable
+#endif
+	    )
+	    pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+	if (!pPixmap)
+	{
+	    damageScrPriv(pScreen);
+
+	    return &pScrPriv->pScreenDamage;
+	}
+    }
+    else
+	pPixmap = (PixmapPtr) pDrawable;
+    return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable)	(*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin)		getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable)	\
+    DamagePtr	pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin)		drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+    DamagePtr	*pPrev = (DamagePtr *) \
+	    &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+			int subWindowMode)
+#endif
+{
+    ScreenPtr	    pScreen = pDrawable->pScreen;
+    damageScrPriv(pScreen);
+    drawableDamage(pDrawable);
+    DamagePtr	    pNext;
+    RegionRec	    clippedRec;
+    RegionPtr	    pDamageRegion;
+    RegionRec	    pixClip;
+    Bool	    was_empty;
+    RegionRec	    tmpRegion;
+    BoxRec	    tmpBox;
+    int		    draw_x, draw_y;
+#ifdef COMPOSITE
+    int		    screen_x = 0, screen_y = 0;
+#endif
+
+    /* short circuit for empty regions */
+    if (!REGION_NOTEMPTY(pScreen, pRegion))
+	return;
+    
+#ifdef COMPOSITE
+    /*
+     * When drawing to a pixmap which is storing window contents,
+     * the region presented is in pixmap relative coordinates which
+     * need to be converted to screen relative coordinates
+     */
+    if (pDrawable->type != DRAWABLE_WINDOW)
+    {
+	screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+	screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+    }
+    if (screen_x || screen_y)
+        REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);
+#endif
+	
+    if (pDrawable->type == DRAWABLE_WINDOW &&
+	((WindowPtr)(pDrawable))->backingStore == NotUseful)
+    {
+	if (subWindowMode == ClipByChildren)
+	{
+	    REGION_INTERSECT(pScreen, pRegion, pRegion,
+			     &((WindowPtr)(pDrawable))->clipList);
+	}
+	else if (subWindowMode == IncludeInferiors)
+	{
+	    RegionPtr pTempRegion =
+		NotClippedByChildren((WindowPtr)(pDrawable));
+	    REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion);
+	    REGION_DESTROY(pScreen, pTempRegion);
+	}
+	/* If subWindowMode is set to an invalid value, don't perform
+	 * any drawable-based clipping. */
+    }
+        
+
+    REGION_NULL (pScreen, &clippedRec);
+    for (; pDamage; pDamage = pNext)
+    {
+	pNext = pDamage->pNext;
+	/*
+	 * Check for internal damage and don't send events
+	 */
+	if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+	{
+	    DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+			   pScrPriv->internalLevel));
+	    continue;
+	}
+	/*
+	 * Check for unrealized windows
+	 */
+	if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+	    !((WindowPtr) (pDamage->pDrawable))->realized)
+	{
+#if 0
+	    DAMAGE_DEBUG (("damage while window unrealized\n"));
+#endif
+	    continue;
+	}
+	
+	draw_x = pDamage->pDrawable->x;
+	draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+	/*
+	 * Need to move everyone to screen coordinates
+	 * XXX what about off-screen pixmaps with non-zero x/y?
+	 */
+	if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
+	{
+	    draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+	    draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+	}
+#endif
+	
+	/*
+	 * Clip against border or pixmap bounds
+	 */
+	
+	pDamageRegion = pRegion;
+	if (clip || pDamage->pDrawable != pDrawable)
+	{
+	    pDamageRegion = &clippedRec;
+	    if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+		REGION_INTERSECT (pScreen, pDamageRegion, pRegion,
+		    &((WindowPtr)(pDamage->pDrawable))->borderClip);
+	    } else {
+		BoxRec	box;
+		box.x1 = draw_x;
+		box.y1 = draw_y;
+		box.x2 = draw_x + pDamage->pDrawable->width;
+		box.y2 = draw_y + pDamage->pDrawable->height;
+		REGION_INIT(pScreen, &pixClip, &box, 1);
+		REGION_INTERSECT (pScreen, pDamageRegion, pRegion, &pixClip);
+		REGION_UNINIT(pScreen, &pixClip);
+	    }
+	    /*
+	     * Short circuit empty results
+	     */
+	    if (!REGION_NOTEMPTY(pScreen, pDamageRegion))
+		continue;
+	}
+	
+	DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+		       where,
+		       pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+		       pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+		       pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+		       pDrawable->id, pDamage->pDrawable->id));
+	
+	/*
+	 * Move region to target coordinate space
+	 */
+	if (draw_x || draw_y)
+	    REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
+	
+	switch (pDamage->damageLevel) {
+	case DamageReportRawRegion:
+	    (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+	    break;
+	case DamageReportDeltaRegion:
+	    REGION_NULL (pScreen, &tmpRegion);
+	    REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
+	    if (REGION_NOTEMPTY (pScreen, &tmpRegion))
+	    {
+		REGION_UNION(pScreen, &pDamage->damage,
+			     &pDamage->damage, pDamageRegion);
+		(*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+	    }
+	    REGION_UNINIT(pScreen, &tmpRegion);
+	    break;
+	case DamageReportBoundingBox:
+	    tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
+	    REGION_UNION(pScreen, &pDamage->damage,
+			 &pDamage->damage, pDamageRegion);
+	    if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))
+		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+	    break;
+	case DamageReportNonEmpty:
+	    was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
+	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	    if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))
+		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+	    break;
+	case DamageReportNone:
+	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	    break;
+	}
+	/*
+	 * translate original region back
+	 */
+	if (pDamageRegion == pRegion && (draw_x || draw_y))
+	    REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);
+    }
+#ifdef COMPOSITE
+    if (screen_x || screen_y)
+	REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);
+#endif
+    
+    REGION_UNINIT (pScreen, &clippedRec);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+    RegionRec	region;
+
+    REGION_INIT (pDrawable->pScreen, &region, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+    _damageDamageRegion (pDrawable, &region, TRUE, subWindowMode, where);
+#else
+    damageDamageRegion (pDrawable, &region, TRUE, subWindowMode);
+#endif
+    REGION_UNINIT (pDrawable->pScreen, &region);
+}
+
+static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void damageChangeGC(GCPtr, unsigned long);
+static void damageCopyGC(GCPtr, unsigned long, GCPtr);
+static void damageDestroyGC(GCPtr);
+static void damageChangeClip(GCPtr, int, pointer, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+GCFuncs damageGCFuncs = {
+    damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+    damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+extern GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+    ScreenPtr pScreen = pGC->pScreen;
+    damageScrPriv(pScreen);
+    damageGCPriv(pGC);
+    Bool ret;
+
+    pGC->pCompositeClip = 0;
+    unwrap (pScrPriv, pScreen, CreateGC);
+    if((ret = (*pScreen->CreateGC) (pGC))) {
+	pGCPriv->ops = NULL;
+	pGCPriv->funcs = pGC->funcs;
+	pGC->funcs = &damageGCFuncs;
+    }
+    wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+    return ret;
+}
+
+#ifdef NOTUSED
+static void
+damageWrapGC (GCPtr pGC)
+{
+    damageGCPriv(pGC);
+
+    pGCPriv->ops = NULL;
+    pGCPriv->funcs = pGC->funcs;
+    pGC->funcs = &damageGCFuncs;
+}
+
+static void
+damageUnwrapGC (GCPtr pGC)
+{
+    damageGCPriv(pGC);
+
+    pGC->funcs = pGCPriv->funcs;
+    if (pGCPriv->ops)
+	pGC->ops = pGCPriv->ops;
+}
+#endif
+
+#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
+    damageGCPriv(pGC);  \
+    GCFuncs *oldFuncs = pGC->funcs; \
+    unwrap(pGCPriv, pGC, funcs);  \
+    unwrap(pGCPriv, pGC, ops); \
+
+#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
+    wrap(pGCPriv, pGC, funcs, oldFuncs); \
+    wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+    damageGCPriv(pGC); \
+    unwrap(pGCPriv, pGC, funcs); \
+    if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+    wrap(pGCPriv, pGC, funcs, &damageGCFuncs);  \
+    if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr         pGC,
+		 unsigned long changes,
+		 DrawablePtr   pDrawable)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+    pGCPriv->ops = pGC->ops;  /* just so it's not NULL */
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageDestroyGC(GCPtr pGC)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->DestroyGC)(pGC);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageChangeGC (GCPtr		pGC,
+		unsigned long   mask)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ChangeGC) (pGC, mask);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyGC (GCPtr	    pGCSrc,
+	      unsigned long mask,
+	      GCPtr	    pGCDst)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
+    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+    DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+damageChangeClip (GCPtr	    pGC,
+		  int	    type,
+		  pointer   pvalue,
+		  int	    nrects)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+    DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (* pGC->funcs->DestroyClip)(pGC);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+    BoxPtr extents = &pGC->pCompositeClip->extents;\
+    if(box.x1 < extents->x1) box.x1 = extents->x1; \
+    if(box.x2 > extents->x2) box.x2 = extents->x2; \
+    if(box.y1 < extents->y1) box.y1 = extents->y1; \
+    if(box.y2 > extents->y2) box.y2 = extents->y2; \
+    }
+
+#define TRANSLATE_BOX(box, pDrawable) { \
+    box.x1 += pDrawable->x; \
+    box.x2 += pDrawable->x; \
+    box.y1 += pDrawable->y; \
+    box.y2 += pDrawable->y; \
+    }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+    TRANSLATE_BOX(box, pDrawable); \
+    TRIM_BOX(box, pGC); \
+    }
+
+#define BOX_NOT_EMPTY(box) \
+    (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g)	(getDrawableDamage(d) && \
+				 (!g->pCompositeClip ||\
+				  REGION_NOTEMPTY(d->pScreen, \
+						  g->pCompositeClip)))
+
+#ifdef RENDER
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+    BoxPtr extents = &pDst->pCompositeClip->extents;\
+    if(box.x1 < extents->x1) box.x1 = extents->x1; \
+    if(box.x2 > extents->x2) box.x2 = extents->x2; \
+    if(box.y1 < extents->y1) box.y1 = extents->y1; \
+    if(box.y2 > extents->y2) box.y2 = extents->y2; \
+    }
+    
+#define checkPictureDamage(p)	(getDrawableDamage(p->pDrawable) && \
+				 REGION_NOTEMPTY(pScreen, p->pCompositeClip))
+
+static void
+damageComposite (CARD8      op,
+		   PicturePtr pSrc,
+		   PicturePtr pMask,
+		   PicturePtr pDst,
+		   INT16      xSrc,
+		   INT16      ySrc,
+		   INT16      xMask,
+		   INT16      yMask,
+		   INT16      xDst,
+		   INT16      yDst,
+		   CARD16     width,
+		   CARD16     height)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    damageScrPriv(pScreen);
+
+    if (checkPictureDamage (pDst))
+    {
+	BoxRec	box;
+
+	box.x1 = xDst + pDst->pDrawable->x;
+	box.y1 = yDst + pDst->pDrawable->y;
+	box.x2 = box.x1 + width;
+	box.y2 = box.y1 + height;
+	TRIM_PICTURE_BOX(box, pDst);
+	if (BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+    }
+    unwrap (pScrPriv, ps, Composite);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+    wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (CARD8		op,
+		PicturePtr	pSrc,
+		PicturePtr	pDst,
+		PictFormatPtr	maskFormat,
+		INT16		xSrc,
+		INT16		ySrc,
+		int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    damageScrPriv(pScreen);
+
+    if (checkPictureDamage (pDst))
+    {
+	int		nlistTmp = nlist;
+	GlyphListPtr	listTmp = list;
+	GlyphPtr	*glyphsTmp = glyphs;
+	int		x, y;
+	int		n;
+	GlyphPtr	glyph;
+	BoxRec		box;
+	int		x1, y1, x2, y2;
+
+	box.x1 = 32767;
+	box.y1 = 32767;
+	box.x2 = -32767;
+	box.y2 = -32767;
+	x = pDst->pDrawable->x;
+	y = pDst->pDrawable->y;
+	while (nlistTmp--)
+	{
+	    x += listTmp->xOff;
+	    y += listTmp->yOff;
+	    n = listTmp->len;
+	    while (n--)
+	    {
+		glyph = *glyphsTmp++;
+		x1 = x - glyph->info.x;
+		y1 = y - glyph->info.y;
+		x2 = x1 + glyph->info.width;
+		y2 = y1 + glyph->info.height;
+		if (x1 < box.x1)
+		    box.x1 = x1;
+		if (y1 < box.y1)
+		    box.y1 = y1;
+		if (x2 > box.x2)
+		    box.x2 = x2;
+		if (y2 > box.y2)
+		    box.y2 = y2;
+		x += glyph->info.xOff;
+		y += glyph->info.yOff;
+	    }
+	    listTmp++;
+	}
+	TRIM_PICTURE_BOX (box, pDst);
+	if (BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+    }
+    unwrap (pScrPriv, ps, Glyphs);
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+    wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+		GC	    *pGC,
+		int	    npt,
+		DDXPointPtr ppt,
+		int	    *pwidth,
+		int	    fSorted)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	int	    nptTmp = npt;
+	DDXPointPtr pptTmp = ppt;
+	int	    *pwidthTmp = pwidth;
+	BoxRec	    box;
+
+	box.x1 = pptTmp->x;
+	box.x2 = box.x1 + *pwidthTmp;
+	box.y2 = box.y1 = pptTmp->y;
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   pwidthTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   if(box.x2 < (pptTmp->x + *pwidthTmp))
+		box.x2 = pptTmp->x + *pwidthTmp;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.y2++;
+
+        if(!pGC->miTranslate) {
+           TRANSLATE_BOX(box, pDrawable);
+        }
+        TRIM_BOX(box, pGC); 
+
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    
+    (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr  pDrawable,
+	       GCPtr	    pGC,
+	       char	    *pcharsrc,
+	       DDXPointPtr  ppt,
+	       int	    *pwidth,
+	       int	    npt,
+	       int	    fSorted)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	DDXPointPtr pptTmp = ppt;
+	int	    *pwidthTmp = pwidth;
+	int	    nptTmp = npt;
+	BoxRec	    box;
+
+	box.x1 = pptTmp->x;
+	box.x2 = box.x1 + *pwidthTmp;
+	box.y2 = box.y1 = pptTmp->y;
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   pwidthTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   if(box.x2 < (pptTmp->x + *pwidthTmp))
+		box.x2 = pptTmp->x + *pwidthTmp;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.y2++;
+
+        if(!pGC->miTranslate) {
+           TRANSLATE_BOX(box, pDrawable);
+        }
+        TRIM_BOX(box, pGC); 
+
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr  pDrawable,
+	       GCPtr	    pGC,
+	       int	    depth,
+	       int	    x,
+	       int	    y,
+	       int	    w,
+	       int	    h,
+	       int	    leftPad,
+	       int	    format,
+	       char	    *pImage)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if (checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = x + pDrawable->x;
+	box.x2 = box.x1 + w;
+	box.y1 = y + pDrawable->y;
+	box.y2 = box.y1 + h;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+		leftPad, format, pImage);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr   pSrc,
+	       DrawablePtr  pDst,
+	       GC	    *pGC,
+	       int	    srcx,
+	       int	    srcy,
+	       int	    width,
+	       int	    height,
+	       int	    dstx,
+	       int	    dsty)
+{
+    RegionPtr ret;
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+    
+    /* The driver will only call SourceValidate() when pSrc != pDst,
+     * but the software sprite (misprite.c) always need to know when a
+     * drawable is copied so it can remove the sprite. See #1030. */
+    if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+	pSrc->type == DRAWABLE_WINDOW &&
+	((WindowPtr)pSrc)->viewable)
+    {
+	(*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+    }
+    
+    if (checkGCDamage (pDst, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = dstx + pDst->x;
+	box.x2 = box.x1 + width;
+	box.y1 = dsty + pDst->y;
+	box.y2 = box.y1 + height;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDst, &box, pGC->subWindowMode);
+    }
+
+    ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+            pGC, srcx, srcy, width, height, dstx, dsty);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+    return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr	pSrc,
+		DrawablePtr	pDst,
+		GCPtr		pGC,
+		int		srcx,
+		int		srcy,
+		int		width,
+		int		height,
+		int		dstx,
+		int		dsty,
+		unsigned long	bitPlane)
+{
+    RegionPtr ret;
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+    /* The driver will only call SourceValidate() when pSrc != pDst,
+     * but the software sprite (misprite.c) always need to know when a
+     * drawable is copied so it can remove the sprite. See #1030. */
+    if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+	pSrc->type == DRAWABLE_WINDOW &&
+	((WindowPtr)pSrc)->viewable)
+    {
+        (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+    }
+
+    if (checkGCDamage (pDst, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = dstx + pDst->x;
+	box.x2 = box.x1 + width;
+	box.y1 = dsty + pDst->y;
+	box.y2 = box.y1 + height;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDst, &box, pGC->subWindowMode);
+    }
+
+    ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+	       pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+    return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    mode,
+		int	    npt,
+		xPoint	    *ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	box;
+	int	nptTmp = npt;
+	xPoint	*pptTmp = ppt;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	/* this could be slow if the points were spread out */
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    mode,
+		int	    npt,
+		DDXPointPtr ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	int	    nptTmp = npt;
+	DDXPointPtr pptTmp = ppt;
+	BoxRec	    box;
+	int	    extra = pGC->lineWidth >> 1;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	if(nptTmp > 1) 
+	{
+	   if(pGC->joinStyle == JoinMiter)
+		extra = 6 * pGC->lineWidth;
+	   else if(pGC->capStyle == CapProjecting)
+		extra = pGC->lineWidth;
+        }
+
+	if(mode == CoordModePrevious) 
+	{
+	   int x = box.x1;
+	   int y = box.y1;
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		x += pptTmp->x;
+		y += pptTmp->y;
+		if(box.x1 > x) box.x1 = x;
+		else if(box.x2 < x) box.x2 = x;
+		if(box.y1 > y) box.y1 = y;
+		else if(box.y2 < y) box.y2 = y;
+	    }
+	}
+	else 
+	{
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+		else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+		if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+		else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		nSeg,
+		  xSegment	*pSeg)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nSeg && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	int	    extra = pGC->lineWidth;
+	int	    nsegTmp = nSeg;
+	xSegment    *pSegTmp = pSeg;
+
+        if(pGC->capStyle != CapProjecting)
+	   extra >>= 1;
+
+	if(pSegTmp->x2 > pSegTmp->x1) {
+	    box.x1 = pSegTmp->x1;
+	    box.x2 = pSegTmp->x2;
+	} else {
+	    box.x2 = pSegTmp->x1;
+	    box.x1 = pSegTmp->x2;
+	}
+
+	if(pSegTmp->y2 > pSegTmp->y1) {
+	    box.y1 = pSegTmp->y1;
+	    box.y2 = pSegTmp->y2;
+	} else {
+	    box.y2 = pSegTmp->y1;
+	    box.y1 = pSegTmp->y2;
+	}
+
+	while(--nsegTmp) 
+	{
+	    pSegTmp++;
+	    if(pSegTmp->x2 > pSegTmp->x1) 
+	    {
+		if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+		if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+	    }
+	    else 
+	    {
+		if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+		if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+	    }
+	    if(pSegTmp->y2 > pSegTmp->y1) 
+	    {
+		if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+		if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+	    }
+	    else
+	    {
+		if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+		if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr  pDrawable,
+		    GCPtr        pGC,
+		    int	         nRects,
+		    xRectangle  *pRects)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nRects && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	int	    offset1, offset2, offset3;
+	int	    nRectsTmp = nRects;
+	xRectangle  *pRectsTmp = pRects;
+
+	offset2 = pGC->lineWidth;
+	if(!offset2) offset2 = 1;
+	offset1 = offset2 >> 1;
+	offset3 = offset2 - offset1;
+
+	while(nRectsTmp--)
+	{
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y - offset1;
+	    box.x2 = box.x1 + pRectsTmp->width + offset2;
+	    box.y2 = box.y1 + offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y + offset3;
+	    box.x2 = box.x1 + offset2;
+	    box.y2 = box.y1 + pRectsTmp->height - offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+	    box.y1 = pRectsTmp->y + offset3;
+	    box.x2 = box.x1 + offset2;
+	    box.y2 = box.y1 + pRectsTmp->height - offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+	    box.x2 = box.x1 + pRectsTmp->width + offset2;
+	    box.y2 = box.y1 + offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    pRectsTmp++;
+	}
+    }
+    (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr   pDrawable,
+	      GCPtr	    pGC,
+	      int	    nArcs,
+	      xArc	    *pArcs)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nArcs && checkGCDamage (pDrawable, pGC))
+    {
+	int	extra = pGC->lineWidth >> 1;
+	BoxRec	box;
+	int	nArcsTmp = nArcs;
+	xArc	*pArcsTmp = pArcs;
+
+	box.x1 = pArcsTmp->x;
+	box.x2 = box.x1 + pArcsTmp->width;
+	box.y1 = pArcsTmp->y;
+	box.y2 = box.y1 + pArcsTmp->height;
+
+	while(--nArcsTmp) 
+	{
+	    pArcsTmp++;
+	    if(box.x1 > pArcsTmp->x)
+		box.x1 = pArcsTmp->x;
+	    if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+		box.x2 = pArcsTmp->x + pArcsTmp->width;
+	    if(box.y1 > pArcsTmp->y) 
+		box.y1 = pArcsTmp->y;
+	    if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+		box.y2 = pArcsTmp->y + pArcsTmp->height;
+        }
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		shape,
+		  int		mode,
+		  int		npt,
+		  DDXPointPtr	ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt > 2 && checkGCDamage (pDrawable, pGC))
+    {
+	DDXPointPtr pptTmp = ppt;
+	int	    nptTmp = npt;
+	BoxRec	    box;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	if(mode != CoordModeOrigin) 
+	{
+	   int x = box.x1;
+	   int y = box.y1;
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		x += pptTmp->x;
+		y += pptTmp->y;
+		if(box.x1 > x) box.x1 = x;
+		else if(box.x2 < x) box.x2 = x;
+		if(box.y1 > y) box.y1 = y;
+		else if(box.y2 < y) box.y2 = y;
+	    }
+	}
+	else 
+	{
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+		else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+		if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+		else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    
+    (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr	pDrawable,
+		   GCPtr	pGC,
+		   int		nRects,
+		   xRectangle	*pRects)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if (nRects && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	xRectangle  *pRectsTmp = pRects;
+	int	    nRectsTmp = nRects;
+
+	box.x1 = pRectsTmp->x;
+	box.x2 = box.x1 + pRectsTmp->width;
+	box.y1 = pRectsTmp->y;
+	box.y2 = box.y1 + pRectsTmp->height;
+
+	while(--nRectsTmp) 
+	{
+	    pRectsTmp++;
+	    if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+	    if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+		box.x2 = pRectsTmp->x + pRectsTmp->width;
+	    if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+	    if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+		box.y2 = pRectsTmp->y + pRectsTmp->height;
+	}
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		nArcs,
+		  xArc		*pArcs)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nArcs && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	box;
+	int	nArcsTmp = nArcs;
+	xArc	*pArcsTmp = pArcs;
+
+	box.x1 = pArcsTmp->x;
+	box.x2 = box.x1 + pArcsTmp->width;
+	box.y1 = pArcsTmp->y;
+	box.y2 = box.y1 + pArcsTmp->height;
+
+	while(--nArcsTmp) 
+	{
+	    pArcsTmp++;
+	    if(box.x1 > pArcsTmp->x)
+		box.x1 = pArcsTmp->x;
+	    if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+		box.x2 = pArcsTmp->x + pArcsTmp->width;
+	    if(box.y1 > pArcsTmp->y)
+		box.y1 = pArcsTmp->y;
+	    if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+		box.y2 = pArcsTmp->y + pArcsTmp->height;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function.  Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr	pDrawable,
+		   FontPtr	font,
+		   int		x,
+		   int		y,
+		   unsigned int	n,
+		   CharInfoPtr	*charinfo,
+		   Bool		imageblt,
+		   int		subWindowMode)
+{
+    ExtentInfoRec   extents;
+    BoxRec	    box;
+
+    QueryGlyphExtents(font, charinfo, n, &extents);
+    if (imageblt)
+    {
+	if (extents.overallWidth > extents.overallRight)
+	    extents.overallRight = extents.overallWidth;
+	if (extents.overallWidth < extents.overallLeft)
+	    extents.overallLeft = extents.overallWidth;
+	if (extents.overallLeft > 0)
+	    extents.overallLeft = 0;
+	if (extents.fontAscent > extents.overallAscent)
+	    extents.overallAscent = extents.fontAscent;
+	if (extents.fontDescent > extents.overallDescent)
+	    extents.overallDescent = extents.fontDescent;
+    }
+    box.x1 = x + extents.overallLeft;
+    box.y1 = y - extents.overallAscent;
+    box.x2 = x + extents.overallRight;
+    box.y2 = y + extents.overallDescent;
+    damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8   0
+#define TT_IMAGE8  1
+#define TT_POLY16  2
+#define TT_IMAGE16 3
+
+static int 
+damageText (DrawablePtr	    pDrawable,
+	    GCPtr	    pGC,
+	    int		    x,
+	    int		    y,
+	    unsigned long   count,
+	    char	    *chars,
+	    FontEncoding    fontEncoding,
+	    Bool	    textType)
+{
+    CharInfoPtr	    *charinfo;
+    CharInfoPtr	    *info;
+    unsigned long   i;
+    unsigned int    n;
+    int		    w;
+    Bool	    imageblt;
+
+    imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+    charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
+    if (!charinfo)
+	return x;
+
+    GetGlyphs(pGC->font, count, (unsigned char *)chars,
+	      fontEncoding, &i, charinfo);
+    n = (unsigned int)i;
+    w = 0;
+    if (!imageblt)
+	for (info = charinfo; i--; info++)
+	    w += (*info)->metrics.characterWidth;
+
+    if (n != 0) {
+	damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+			   charinfo, imageblt, pGC->subWindowMode);
+
+#ifndef NXAGENT_SERVER
+
+	if (imageblt)
+	    (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+				       FONTGLYPHS(pGC->font));
+	else
+	    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+				      FONTGLYPHS(pGC->font));
+#endif
+
+    }
+    DEALLOCATE_LOCAL(charinfo);
+    return x + w;
+}
+
+#ifndef NXAGENT_SERVER
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    x,
+		int	    y,
+		int	    count,
+		char	    *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_POLY8);
+    else
+	x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static int
+damagePolyText16(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 unsigned short	*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_POLY16);
+    else
+	x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static void
+damageImageText8(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 char		*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_IMAGE8);
+    else
+	(*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		x,
+		  int		y,
+		  int		count,
+		  unsigned short *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_IMAGE16);
+    else
+	(*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#else /* #ifndef NXAGENT_SERVER */
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    x,
+		int	    y,
+		int	    count,
+		char	    *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_POLY8);
+
+    x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static int
+damagePolyText16(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 unsigned short	*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_POLY16);
+
+    x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static void
+damageImageText8(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 char		*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_IMAGE8);
+
+    (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		x,
+		  int		y,
+		  int		count,
+		  unsigned short *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_IMAGE16);
+
+    (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#endif /* #ifndef NXAGENT_SERVER */
+
+static void
+damageImageGlyphBlt(DrawablePtr	    pDrawable,
+		    GCPtr	    pGC,
+		    int		    x,
+		    int		    y,
+		    unsigned int    nglyph,
+		    CharInfoPtr	    *ppci,
+		    pointer	    pglyphBase)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+		       nglyph, ppci, TRUE, pGC->subWindowMode);
+    (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+					ppci, pglyphBase);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr	pDrawable,
+		   GCPtr	pGC,
+		   int		x,
+		   int		y,
+		   unsigned int	nglyph,
+		   CharInfoPtr	*ppci,
+		   pointer	pglyphBase)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+		       nglyph, ppci, FALSE, pGC->subWindowMode);
+    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+				ppci, pglyphBase);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr		pGC,
+		 PixmapPtr	pBitMap,
+		 DrawablePtr	pDrawable,
+		 int		dx,
+		 int		dy,
+		 int		xOrg,
+		 int		yOrg)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if(checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec box;
+
+        box.x1 = xOrg;
+        box.y1 = yOrg;
+
+        if(!pGC->miTranslate) {
+           box.x1 += pDrawable->x;          
+           box.y1 += pDrawable->y;          
+        }
+
+	box.x2 = box.x1 + dx;
+	box.y2 = box.y1 + dy;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+    while (*pPrev)
+    {
+	if (*pPrev == pDamage)
+	{
+	    *pPrev = pDamage->pNext;
+	    return;
+	}
+	pPrev = &(*pPrev)->pNext;
+    }
+#if DAMAGE_VALIDATE_ENABLE
+    ErrorF ("Damage not on list\n");
+    abort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+    DamagePtr	pOld;
+
+    for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+	if (pOld == pDamage) {
+	    ErrorF ("Damage already on list\n");
+	    abort ();
+	}
+#endif
+    pDamage->pNext = *pPrev;
+    *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if (pPixmap->refcnt == 1)
+    {
+	DamagePtr	*pPrev = getPixmapDamageRef (pPixmap);
+	DamagePtr	pDamage;
+
+	while ((pDamage = *pPrev))
+	{
+	    damageRemoveDamage (pPrev, pDamage);
+	    if (!pDamage->isWindow)
+		DamageDestroy (pDamage);
+	}
+    }
+    unwrap (pScrPriv, pScreen, DestroyPixmap);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+    return TRUE;
+}
+
+static void
+damagePaintWindow(WindowPtr pWindow,
+		  RegionPtr prgn,
+		  int	    what)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    /*
+     * Painting background none doesn't actually *do* anything, so
+     * no damage is recorded
+     */
+    if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
+	getWindowDamage (pWindow))
+	damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+    if(what == PW_BACKGROUND) {
+	unwrap (pScrPriv, pScreen, PaintWindowBackground);
+	(*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+	wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+    } else {
+	unwrap (pScrPriv, pScreen, PaintWindowBorder);
+	(*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+	wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+    }
+}
+
+
+static void
+damageCopyWindow(WindowPtr	pWindow,
+		 DDXPointRec	ptOldOrg,
+		 RegionPtr	prgnSrc)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if (getWindowDamage (pWindow))
+    {
+	int dx = pWindow->drawable.x - ptOldOrg.x;
+	int dy = pWindow->drawable.y - ptOldOrg.y;
+	
+	/*
+	 * The region comes in source relative, but the damage occurs
+	 * at the destination location.  Translate back and forth.
+	 */
+	REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
+	damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
+	REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
+    }
+    unwrap (pScrPriv, pScreen, CopyWindow);
+    (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+    wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+GCOps damageGCOps = {
+    damageFillSpans, damageSetSpans,
+    damagePutImage, damageCopyArea,
+    damageCopyPlane, damagePolyPoint,
+    damagePolylines, damagePolySegment,
+    damagePolyRectangle, damagePolyArc,
+    damageFillPolygon, damagePolyFillRect,
+    damagePolyFillArc, damagePolyText8,
+    damagePolyText16, damageImageText8,
+    damageImageText16, damageImageGlyphBlt,
+    damagePolyGlyphBlt, damagePushPixels,
+#ifdef NEED_LINEHELPER
+    NULL,
+#endif
+    {NULL}		/* devPrivate */
+};
+
+static void
+damageRestoreAreas (PixmapPtr	pPixmap,
+		    RegionPtr	prgn,
+		    int		xorg,
+		    int		yorg,
+		    WindowPtr	pWindow)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+    unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+    (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+						xorg, yorg, pWindow);
+    wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+			     damageRestoreAreas);
+}
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	PixmapPtr   pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+	DamagePtr   *pPrev = getPixmapDamageRef(pOldPixmap);
+	
+	while (pDamage)
+	{
+	    damageRemoveDamage (pPrev, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+    unwrap (pScrPriv, pScreen, SetWindowPixmap);
+    (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	DamagePtr   *pPrev = getPixmapDamageRef(pPixmap);
+	
+	while (pDamage)
+	{
+	    damageInsertDamage (pPrev, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    Bool	ret;
+    damageScrPriv(pScreen);
+
+    while ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	DamageUnregister (&pWindow->drawable, pDamage);
+	DamageDestroy (pDamage);
+    }
+    unwrap (pScrPriv, pScreen, DestroyWindow);
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    return ret;
+}
+
+static Bool
+damageCloseScreen (int i, ScreenPtr pScreen)
+{
+    damageScrPriv(pScreen);
+
+    unwrap (pScrPriv, pScreen, DestroyPixmap);
+    unwrap (pScrPriv, pScreen, CreateGC);
+    unwrap (pScrPriv, pScreen, PaintWindowBackground);
+    unwrap (pScrPriv, pScreen, PaintWindowBorder);
+    unwrap (pScrPriv, pScreen, CopyWindow);
+    unwrap (pScrPriv, pScreen, CloseScreen);
+    unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+    xfree (pScrPriv);
+    return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+int damageScrPrivateIndex;
+int damagePixPrivateIndex;
+int damageGCPrivateIndex;
+int damageWinPrivateIndex;
+int damageGeneration;
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+    DamageScrPrivPtr	pScrPriv;
+#ifdef RENDER
+    PictureScreenPtr	ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+    if (damageGeneration != serverGeneration)
+    {
+	damageScrPrivateIndex = AllocateScreenPrivateIndex ();
+	if (damageScrPrivateIndex == -1)
+	    return FALSE;
+	damageGCPrivateIndex = AllocateGCPrivateIndex ();
+	if (damageGCPrivateIndex == -1)
+	    return FALSE;
+	damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
+	if (damagePixPrivateIndex == -1)
+	    return FALSE;
+	damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+	if (damageWinPrivateIndex == -1)
+	    return FALSE;
+	damageGeneration = serverGeneration;
+    }
+    if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
+	return TRUE;
+
+    if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
+	return FALSE;
+    if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
+	return FALSE;
+    if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+	return FALSE;
+
+    pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
+    if (!pScrPriv)
+	return FALSE;
+
+#ifdef COMPOSITE
+    /* This is a kludge to ensure wrapping order with the composite wrapper.
+     * If it's done from compinit.c, then DamageSetup may be called before the
+     * extension init phase, so that cw will be higher in the wrapping chain and
+     * rewrite drawables before damage gets to it, causing confusion.
+     */
+    if (!noCompositeExtension)
+	miInitializeCompositeWrapper (pScreen);
+#endif
+	
+    pScrPriv->internalLevel = 0;
+    pScrPriv->pScreenDamage = 0;
+
+    wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+    wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+    wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+    wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+    wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+    wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+    wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+			     damageRestoreAreas);
+#ifdef RENDER
+    if (ps) {
+	wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+	wrap (pScrPriv, ps, Composite, damageComposite);
+    }
+#endif
+
+    pScreen->devPrivates[damageScrPrivateIndex].ptr = (pointer) pScrPriv;
+    return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc  damageReport,
+	      DamageDestroyFunc	damageDestroy,
+	      DamageReportLevel	damageLevel,
+	      Bool		isInternal,
+	      ScreenPtr		pScreen,
+	      void		*closure)
+{
+    DamagePtr	pDamage;
+
+    pDamage = xalloc (sizeof (DamageRec));
+    if (!pDamage)
+	return 0;
+    pDamage->pNext = 0;
+    pDamage->pNextWin = 0;
+    REGION_NULL(pScreen, &pDamage->damage);
+    
+    pDamage->damageLevel = damageLevel;
+    pDamage->isInternal = isInternal;
+    pDamage->closure = closure;
+    pDamage->isWindow = FALSE;
+    pDamage->pDrawable = 0;
+
+    pDamage->damageReport = damageReport;
+    pDamage->damageDestroy = damageDestroy;
+    return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+		DamagePtr   pDamage)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+	DamagePtr   pOld;
+	
+	for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+	    if (pOld == pDamage) {
+		ErrorF ("Damage already on window list\n");
+		abort ();
+	    }
+#endif
+	pDamage->pNextWin = *pPrev;
+	*pPrev = pDamage;
+	pDamage->isWindow = TRUE;
+    }
+    else
+	pDamage->isWindow = FALSE;
+    pDamage->pDrawable = pDrawable;
+    damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+    damageScrPriv (pScreen);
+
+    pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr	    pDrawable,
+		  DamagePtr	    pDamage)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+	int	found = 0;
+#endif
+
+	while (*pPrev)
+	{
+	    if (*pPrev == pDamage)
+	    {
+		*pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+		found = 1;
+#endif
+		break;
+	    }
+	    pPrev = &(*pPrev)->pNextWin;
+	}
+#if DAMAGE_VALIDATE_ENABLE
+	if (!found) {
+	    ErrorF ("Damage not on window list\n");
+	    abort ();
+	}
+#endif
+    }
+    pDamage->pDrawable = 0;
+    damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr    pDamage)
+{
+    if (pDamage->damageDestroy)
+	(*pDamage->damageDestroy) (pDamage, pDamage->closure);
+    REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
+    xfree (pDamage);
+}
+
+Bool
+DamageSubtract (DamagePtr	    pDamage,
+		const RegionPtr	    pRegion)
+{
+    RegionPtr	pClip;
+    RegionRec	pixmapClip;
+    DrawablePtr	pDrawable = pDamage->pDrawable;
+    
+    REGION_SUBTRACT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pRegion);
+    if (pDrawable)
+    {
+	if (pDrawable->type == DRAWABLE_WINDOW)
+	    pClip = &((WindowPtr) pDrawable)->borderClip;
+	else
+	{
+	    BoxRec  box;
+
+	    box.x1 = pDrawable->x;
+	    box.y1 = pDrawable->y;
+	    box.x2 = pDrawable->x + pDrawable->width;
+	    box.y2 = pDrawable->y + pDrawable->height;
+	    REGION_INIT (pDrawable->pScreen, &pixmapClip, &box, 1);
+	    pClip = &pixmapClip;
+	}
+	REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
+	REGION_INTERSECT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pClip);
+	REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
+	if (pDrawable->type != DRAWABLE_WINDOW)
+	    REGION_UNINIT(pDrawable->pScreen, &pixmapClip);
+    }
+    return REGION_NOTEMPTY (pDrawable->pScreen, &pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr	    pDamage)
+{
+    REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr		    pDamage)
+{
+    return &pDamage->damage;
+}
+
+void
+DamageDamageRegion (DrawablePtr	pDrawable,
+		    RegionPtr	pRegion)
+{
+    damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
new file mode 100644
index 000000000..c49f1587f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
@@ -0,0 +1,2073 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include    <X11/X.h>
+#include    "scrnintstr.h"
+#include    "windowstr.h"
+#include    <X11/fonts/font.h>
+#include    "dixfontstr.h"
+#include    <X11/fonts/fontstruct.h>
+#include    "mi.h"
+#include    "regionstr.h"
+#include    "globals.h"
+#include    "gcstruct.h"
+#include    "damage.h"
+#include    "damagestr.h"
+#ifdef COMPOSITE
+#include    "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+    priv->mem = real->mem; \
+    real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+    real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+    ((a)->x1 == (b)->x1 && \
+     (a)->y1 == (b)->y1 && \
+     (a)->x2 == (b)->x2 && \
+     (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x)	ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) \
+    ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
+
+#define pixmapDamage(pPixmap)		damagePixPriv(pPixmap)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+    PixmapPtr   pPixmap;
+    
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	ScreenPtr   pScreen = pDrawable->pScreen;
+
+	pPixmap = 0;
+	if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+	    && ((WindowPtr)pDrawable)->viewable
+#endif
+	    )
+	    pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+	if (!pPixmap)
+	{
+	    damageScrPriv(pScreen);
+
+	    return &pScrPriv->pScreenDamage;
+	}
+    }
+    else
+	pPixmap = (PixmapPtr) pDrawable;
+    return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable)	(*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin)		getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable)	\
+    DamagePtr	pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin)		drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+    DamagePtr	*pPrev = (DamagePtr *) \
+	    &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+			int subWindowMode)
+#endif
+{
+    ScreenPtr	    pScreen = pDrawable->pScreen;
+    damageScrPriv(pScreen);
+    drawableDamage(pDrawable);
+    DamagePtr	    pNext;
+    RegionRec	    clippedRec;
+    RegionPtr	    pDamageRegion;
+    RegionRec	    pixClip;
+    Bool	    was_empty;
+    RegionRec	    tmpRegion;
+    BoxRec	    tmpBox;
+    int		    draw_x, draw_y;
+#ifdef COMPOSITE
+    int		    screen_x = 0, screen_y = 0;
+#endif
+
+    /* short circuit for empty regions */
+    if (!REGION_NOTEMPTY(pScreen, pRegion))
+	return;
+    
+#ifdef COMPOSITE
+    /*
+     * When drawing to a pixmap which is storing window contents,
+     * the region presented is in pixmap relative coordinates which
+     * need to be converted to screen relative coordinates
+     */
+    if (pDrawable->type != DRAWABLE_WINDOW)
+    {
+	screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+	screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+    }
+    if (screen_x || screen_y)
+        REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);
+#endif
+	
+    if (pDrawable->type == DRAWABLE_WINDOW &&
+	((WindowPtr)(pDrawable))->backingStore == NotUseful)
+    {
+	if (subWindowMode == ClipByChildren)
+	{
+	    REGION_INTERSECT(pScreen, pRegion, pRegion,
+			     &((WindowPtr)(pDrawable))->clipList);
+	}
+	else if (subWindowMode == IncludeInferiors)
+	{
+	    RegionPtr pTempRegion =
+		NotClippedByChildren((WindowPtr)(pDrawable));
+	    REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion);
+	    REGION_DESTROY(pScreen, pTempRegion);
+	}
+	/* If subWindowMode is set to an invalid value, don't perform
+	 * any drawable-based clipping. */
+    }
+        
+
+    REGION_NULL (pScreen, &clippedRec);
+    for (; pDamage; pDamage = pNext)
+    {
+	pNext = pDamage->pNext;
+	/*
+	 * Check for internal damage and don't send events
+	 */
+	if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+	{
+	    DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+			   pScrPriv->internalLevel));
+	    continue;
+	}
+	/*
+	 * Check for unrealized windows
+	 */
+	if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+	    !((WindowPtr) (pDamage->pDrawable))->realized)
+	{
+#if 0
+	    DAMAGE_DEBUG (("damage while window unrealized\n"));
+#endif
+	    continue;
+	}
+	
+	draw_x = pDamage->pDrawable->x;
+	draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+	/*
+	 * Need to move everyone to screen coordinates
+	 * XXX what about off-screen pixmaps with non-zero x/y?
+	 */
+	if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
+	{
+	    draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+	    draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+	}
+#endif
+	
+	/*
+	 * Clip against border or pixmap bounds
+	 */
+	
+	pDamageRegion = pRegion;
+	if (clip || pDamage->pDrawable != pDrawable)
+	{
+	    pDamageRegion = &clippedRec;
+	    if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+		REGION_INTERSECT (pScreen, pDamageRegion, pRegion,
+		    &((WindowPtr)(pDamage->pDrawable))->borderClip);
+	    } else {
+		BoxRec	box;
+		box.x1 = draw_x;
+		box.y1 = draw_y;
+		box.x2 = draw_x + pDamage->pDrawable->width;
+		box.y2 = draw_y + pDamage->pDrawable->height;
+		REGION_INIT(pScreen, &pixClip, &box, 1);
+		REGION_INTERSECT (pScreen, pDamageRegion, pRegion, &pixClip);
+		REGION_UNINIT(pScreen, &pixClip);
+	    }
+	    /*
+	     * Short circuit empty results
+	     */
+	    if (!REGION_NOTEMPTY(pScreen, pDamageRegion))
+		continue;
+	}
+	
+	DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+		       where,
+		       pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+		       pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+		       pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+		       pDrawable->id, pDamage->pDrawable->id));
+	
+	/*
+	 * Move region to target coordinate space
+	 */
+	if (draw_x || draw_y)
+	    REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
+	
+	switch (pDamage->damageLevel) {
+	case DamageReportRawRegion:
+	    (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+	    break;
+	case DamageReportDeltaRegion:
+	    REGION_NULL (pScreen, &tmpRegion);
+	    REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
+	    if (REGION_NOTEMPTY (pScreen, &tmpRegion))
+	    {
+		REGION_UNION(pScreen, &pDamage->damage,
+			     &pDamage->damage, pDamageRegion);
+		(*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+	    }
+	    REGION_UNINIT(pScreen, &tmpRegion);
+	    break;
+	case DamageReportBoundingBox:
+	    tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
+	    REGION_UNION(pScreen, &pDamage->damage,
+			 &pDamage->damage, pDamageRegion);
+	    if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))
+		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+	    break;
+	case DamageReportNonEmpty:
+	    was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
+	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	    if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))
+		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+	    break;
+	case DamageReportNone:
+	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	    break;
+	}
+	/*
+	 * translate original region back
+	 */
+	if (pDamageRegion == pRegion && (draw_x || draw_y))
+	    REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);
+    }
+#ifdef COMPOSITE
+    if (screen_x || screen_y)
+	REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);
+#endif
+    
+    REGION_UNINIT (pScreen, &clippedRec);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+    RegionRec	region;
+
+    REGION_INIT (pDrawable->pScreen, &region, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+    _damageDamageRegion (pDrawable, &region, TRUE, subWindowMode, where);
+#else
+    damageDamageRegion (pDrawable, &region, TRUE, subWindowMode);
+#endif
+    REGION_UNINIT (pDrawable->pScreen, &region);
+}
+
+static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void damageChangeGC(GCPtr, unsigned long);
+static void damageCopyGC(GCPtr, unsigned long, GCPtr);
+static void damageDestroyGC(GCPtr);
+static void damageChangeClip(GCPtr, int, pointer, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+GCFuncs damageGCFuncs = {
+    damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+    damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+extern GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+    ScreenPtr pScreen = pGC->pScreen;
+    damageScrPriv(pScreen);
+    damageGCPriv(pGC);
+    Bool ret;
+
+    pGC->pCompositeClip = 0;
+    unwrap (pScrPriv, pScreen, CreateGC);
+    if((ret = (*pScreen->CreateGC) (pGC))) {
+	pGCPriv->ops = NULL;
+	pGCPriv->funcs = pGC->funcs;
+	pGC->funcs = &damageGCFuncs;
+    }
+    wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+    return ret;
+}
+
+#ifdef NOTUSED
+static void
+damageWrapGC (GCPtr pGC)
+{
+    damageGCPriv(pGC);
+
+    pGCPriv->ops = NULL;
+    pGCPriv->funcs = pGC->funcs;
+    pGC->funcs = &damageGCFuncs;
+}
+
+static void
+damageUnwrapGC (GCPtr pGC)
+{
+    damageGCPriv(pGC);
+
+    pGC->funcs = pGCPriv->funcs;
+    if (pGCPriv->ops)
+	pGC->ops = pGCPriv->ops;
+}
+#endif
+
+#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
+    damageGCPriv(pGC);  \
+    GCFuncs *oldFuncs = pGC->funcs; \
+    unwrap(pGCPriv, pGC, funcs);  \
+    unwrap(pGCPriv, pGC, ops); \
+
+#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
+    wrap(pGCPriv, pGC, funcs, oldFuncs); \
+    wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+    damageGCPriv(pGC); \
+    unwrap(pGCPriv, pGC, funcs); \
+    if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+    wrap(pGCPriv, pGC, funcs, &damageGCFuncs);  \
+    if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr         pGC,
+		 unsigned long changes,
+		 DrawablePtr   pDrawable)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+    pGCPriv->ops = pGC->ops;  /* just so it's not NULL */
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageDestroyGC(GCPtr pGC)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->DestroyGC)(pGC);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageChangeGC (GCPtr		pGC,
+		unsigned long   mask)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ChangeGC) (pGC, mask);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyGC (GCPtr	    pGCSrc,
+	      unsigned long mask,
+	      GCPtr	    pGCDst)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
+    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+    DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+damageChangeClip (GCPtr	    pGC,
+		  int	    type,
+		  pointer   pvalue,
+		  int	    nrects)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+    DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (* pGC->funcs->DestroyClip)(pGC);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+    BoxPtr extents = &pGC->pCompositeClip->extents;\
+    if(box.x1 < extents->x1) box.x1 = extents->x1; \
+    if(box.x2 > extents->x2) box.x2 = extents->x2; \
+    if(box.y1 < extents->y1) box.y1 = extents->y1; \
+    if(box.y2 > extents->y2) box.y2 = extents->y2; \
+    }
+
+#define TRANSLATE_BOX(box, pDrawable) { \
+    box.x1 += pDrawable->x; \
+    box.x2 += pDrawable->x; \
+    box.y1 += pDrawable->y; \
+    box.y2 += pDrawable->y; \
+    }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+    TRANSLATE_BOX(box, pDrawable); \
+    TRIM_BOX(box, pGC); \
+    }
+
+#define BOX_NOT_EMPTY(box) \
+    (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g)	(getDrawableDamage(d) && \
+				 (!g->pCompositeClip ||\
+				  REGION_NOTEMPTY(d->pScreen, \
+						  g->pCompositeClip)))
+
+#ifdef RENDER
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+    BoxPtr extents = &pDst->pCompositeClip->extents;\
+    if(box.x1 < extents->x1) box.x1 = extents->x1; \
+    if(box.x2 > extents->x2) box.x2 = extents->x2; \
+    if(box.y1 < extents->y1) box.y1 = extents->y1; \
+    if(box.y2 > extents->y2) box.y2 = extents->y2; \
+    }
+    
+#define checkPictureDamage(p)	(getDrawableDamage(p->pDrawable) && \
+				 REGION_NOTEMPTY(pScreen, p->pCompositeClip))
+
+static void
+damageComposite (CARD8      op,
+		   PicturePtr pSrc,
+		   PicturePtr pMask,
+		   PicturePtr pDst,
+		   INT16      xSrc,
+		   INT16      ySrc,
+		   INT16      xMask,
+		   INT16      yMask,
+		   INT16      xDst,
+		   INT16      yDst,
+		   CARD16     width,
+		   CARD16     height)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    damageScrPriv(pScreen);
+
+    if (checkPictureDamage (pDst))
+    {
+	BoxRec	box;
+
+	box.x1 = xDst + pDst->pDrawable->x;
+	box.y1 = yDst + pDst->pDrawable->y;
+	box.x2 = box.x1 + width;
+	box.y2 = box.y1 + height;
+	TRIM_PICTURE_BOX(box, pDst);
+	if (BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+    }
+    unwrap (pScrPriv, ps, Composite);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+    wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (CARD8		op,
+		PicturePtr	pSrc,
+		PicturePtr	pDst,
+		PictFormatPtr	maskFormat,
+		INT16		xSrc,
+		INT16		ySrc,
+		int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    damageScrPriv(pScreen);
+
+    if (checkPictureDamage (pDst))
+    {
+	int		nlistTmp = nlist;
+	GlyphListPtr	listTmp = list;
+	GlyphPtr	*glyphsTmp = glyphs;
+	int		x, y;
+	int		n;
+	GlyphPtr	glyph;
+	BoxRec		box;
+	int		x1, y1, x2, y2;
+
+	box.x1 = 32767;
+	box.y1 = 32767;
+	box.x2 = -32767;
+	box.y2 = -32767;
+	x = pDst->pDrawable->x;
+	y = pDst->pDrawable->y;
+	while (nlistTmp--)
+	{
+	    x += listTmp->xOff;
+	    y += listTmp->yOff;
+	    n = listTmp->len;
+	    while (n--)
+	    {
+		glyph = *glyphsTmp++;
+		x1 = x - glyph->info.x;
+		y1 = y - glyph->info.y;
+		x2 = x1 + glyph->info.width;
+		y2 = y1 + glyph->info.height;
+		if (x1 < box.x1)
+		    box.x1 = x1;
+		if (y1 < box.y1)
+		    box.y1 = y1;
+		if (x2 > box.x2)
+		    box.x2 = x2;
+		if (y2 > box.y2)
+		    box.y2 = y2;
+		x += glyph->info.xOff;
+		y += glyph->info.yOff;
+	    }
+	    listTmp++;
+	}
+	TRIM_PICTURE_BOX (box, pDst);
+	if (BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+    }
+    unwrap (pScrPriv, ps, Glyphs);
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+    wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+		GC	    *pGC,
+		int	    npt,
+		DDXPointPtr ppt,
+		int	    *pwidth,
+		int	    fSorted)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	int	    nptTmp = npt;
+	DDXPointPtr pptTmp = ppt;
+	int	    *pwidthTmp = pwidth;
+	BoxRec	    box;
+
+	box.x1 = pptTmp->x;
+	box.x2 = box.x1 + *pwidthTmp;
+	box.y2 = box.y1 = pptTmp->y;
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   pwidthTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   if(box.x2 < (pptTmp->x + *pwidthTmp))
+		box.x2 = pptTmp->x + *pwidthTmp;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.y2++;
+
+        if(!pGC->miTranslate) {
+           TRANSLATE_BOX(box, pDrawable);
+        }
+        TRIM_BOX(box, pGC); 
+
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    
+    (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr  pDrawable,
+	       GCPtr	    pGC,
+	       char	    *pcharsrc,
+	       DDXPointPtr  ppt,
+	       int	    *pwidth,
+	       int	    npt,
+	       int	    fSorted)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	DDXPointPtr pptTmp = ppt;
+	int	    *pwidthTmp = pwidth;
+	int	    nptTmp = npt;
+	BoxRec	    box;
+
+	box.x1 = pptTmp->x;
+	box.x2 = box.x1 + *pwidthTmp;
+	box.y2 = box.y1 = pptTmp->y;
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   pwidthTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   if(box.x2 < (pptTmp->x + *pwidthTmp))
+		box.x2 = pptTmp->x + *pwidthTmp;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.y2++;
+
+        if(!pGC->miTranslate) {
+           TRANSLATE_BOX(box, pDrawable);
+        }
+        TRIM_BOX(box, pGC); 
+
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr  pDrawable,
+	       GCPtr	    pGC,
+	       int	    depth,
+	       int	    x,
+	       int	    y,
+	       int	    w,
+	       int	    h,
+	       int	    leftPad,
+	       int	    format,
+	       char	    *pImage)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if (checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = x + pDrawable->x;
+	box.x2 = box.x1 + w;
+	box.y1 = y + pDrawable->y;
+	box.y2 = box.y1 + h;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+		leftPad, format, pImage);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr   pSrc,
+	       DrawablePtr  pDst,
+	       GC	    *pGC,
+	       int	    srcx,
+	       int	    srcy,
+	       int	    width,
+	       int	    height,
+	       int	    dstx,
+	       int	    dsty)
+{
+    RegionPtr ret;
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+    
+    /* The driver will only call SourceValidate() when pSrc != pDst,
+     * but the software sprite (misprite.c) always need to know when a
+     * drawable is copied so it can remove the sprite. See #1030. */
+    if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+	pSrc->type == DRAWABLE_WINDOW &&
+	((WindowPtr)pSrc)->viewable)
+    {
+	(*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+    }
+    
+    if (checkGCDamage (pDst, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = dstx + pDst->x;
+	box.x2 = box.x1 + width;
+	box.y1 = dsty + pDst->y;
+	box.y2 = box.y1 + height;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDst, &box, pGC->subWindowMode);
+    }
+
+    ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+            pGC, srcx, srcy, width, height, dstx, dsty);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+    return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr	pSrc,
+		DrawablePtr	pDst,
+		GCPtr		pGC,
+		int		srcx,
+		int		srcy,
+		int		width,
+		int		height,
+		int		dstx,
+		int		dsty,
+		unsigned long	bitPlane)
+{
+    RegionPtr ret;
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+    /* The driver will only call SourceValidate() when pSrc != pDst,
+     * but the software sprite (misprite.c) always need to know when a
+     * drawable is copied so it can remove the sprite. See #1030. */
+    if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+	pSrc->type == DRAWABLE_WINDOW &&
+	((WindowPtr)pSrc)->viewable)
+    {
+        (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+    }
+
+    if (checkGCDamage (pDst, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = dstx + pDst->x;
+	box.x2 = box.x1 + width;
+	box.y1 = dsty + pDst->y;
+	box.y2 = box.y1 + height;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDst, &box, pGC->subWindowMode);
+    }
+
+    ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+	       pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+    return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    mode,
+		int	    npt,
+		xPoint	    *ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	box;
+	int	nptTmp = npt;
+	xPoint	*pptTmp = ppt;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	/* this could be slow if the points were spread out */
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    mode,
+		int	    npt,
+		DDXPointPtr ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	int	    nptTmp = npt;
+	DDXPointPtr pptTmp = ppt;
+	BoxRec	    box;
+	int	    extra = pGC->lineWidth >> 1;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	if(nptTmp > 1) 
+	{
+	   if(pGC->joinStyle == JoinMiter)
+		extra = 6 * pGC->lineWidth;
+	   else if(pGC->capStyle == CapProjecting)
+		extra = pGC->lineWidth;
+        }
+
+	if(mode == CoordModePrevious) 
+	{
+	   int x = box.x1;
+	   int y = box.y1;
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		x += pptTmp->x;
+		y += pptTmp->y;
+		if(box.x1 > x) box.x1 = x;
+		else if(box.x2 < x) box.x2 = x;
+		if(box.y1 > y) box.y1 = y;
+		else if(box.y2 < y) box.y2 = y;
+	    }
+	}
+	else 
+	{
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+		else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+		if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+		else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		nSeg,
+		  xSegment	*pSeg)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nSeg && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	int	    extra = pGC->lineWidth;
+	int	    nsegTmp = nSeg;
+	xSegment    *pSegTmp = pSeg;
+
+        if(pGC->capStyle != CapProjecting)
+	   extra >>= 1;
+
+	if(pSegTmp->x2 > pSegTmp->x1) {
+	    box.x1 = pSegTmp->x1;
+	    box.x2 = pSegTmp->x2;
+	} else {
+	    box.x2 = pSegTmp->x1;
+	    box.x1 = pSegTmp->x2;
+	}
+
+	if(pSegTmp->y2 > pSegTmp->y1) {
+	    box.y1 = pSegTmp->y1;
+	    box.y2 = pSegTmp->y2;
+	} else {
+	    box.y2 = pSegTmp->y1;
+	    box.y1 = pSegTmp->y2;
+	}
+
+	while(--nsegTmp) 
+	{
+	    pSegTmp++;
+	    if(pSegTmp->x2 > pSegTmp->x1) 
+	    {
+		if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+		if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+	    }
+	    else 
+	    {
+		if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+		if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+	    }
+	    if(pSegTmp->y2 > pSegTmp->y1) 
+	    {
+		if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+		if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+	    }
+	    else
+	    {
+		if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+		if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr  pDrawable,
+		    GCPtr        pGC,
+		    int	         nRects,
+		    xRectangle  *pRects)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nRects && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	int	    offset1, offset2, offset3;
+	int	    nRectsTmp = nRects;
+	xRectangle  *pRectsTmp = pRects;
+
+	offset2 = pGC->lineWidth;
+	if(!offset2) offset2 = 1;
+	offset1 = offset2 >> 1;
+	offset3 = offset2 - offset1;
+
+	while(nRectsTmp--)
+	{
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y - offset1;
+	    box.x2 = box.x1 + pRectsTmp->width + offset2;
+	    box.y2 = box.y1 + offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y + offset3;
+	    box.x2 = box.x1 + offset2;
+	    box.y2 = box.y1 + pRectsTmp->height - offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+	    box.y1 = pRectsTmp->y + offset3;
+	    box.x2 = box.x1 + offset2;
+	    box.y2 = box.y1 + pRectsTmp->height - offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+	    box.x2 = box.x1 + pRectsTmp->width + offset2;
+	    box.y2 = box.y1 + offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    pRectsTmp++;
+	}
+    }
+    (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr   pDrawable,
+	      GCPtr	    pGC,
+	      int	    nArcs,
+	      xArc	    *pArcs)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nArcs && checkGCDamage (pDrawable, pGC))
+    {
+	int	extra = pGC->lineWidth >> 1;
+	BoxRec	box;
+	int	nArcsTmp = nArcs;
+	xArc	*pArcsTmp = pArcs;
+
+	box.x1 = pArcsTmp->x;
+	box.x2 = box.x1 + pArcsTmp->width;
+	box.y1 = pArcsTmp->y;
+	box.y2 = box.y1 + pArcsTmp->height;
+
+	while(--nArcsTmp) 
+	{
+	    pArcsTmp++;
+	    if(box.x1 > pArcsTmp->x)
+		box.x1 = pArcsTmp->x;
+	    if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+		box.x2 = pArcsTmp->x + pArcsTmp->width;
+	    if(box.y1 > pArcsTmp->y) 
+		box.y1 = pArcsTmp->y;
+	    if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+		box.y2 = pArcsTmp->y + pArcsTmp->height;
+        }
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		shape,
+		  int		mode,
+		  int		npt,
+		  DDXPointPtr	ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt > 2 && checkGCDamage (pDrawable, pGC))
+    {
+	DDXPointPtr pptTmp = ppt;
+	int	    nptTmp = npt;
+	BoxRec	    box;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	if(mode != CoordModeOrigin) 
+	{
+	   int x = box.x1;
+	   int y = box.y1;
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		x += pptTmp->x;
+		y += pptTmp->y;
+		if(box.x1 > x) box.x1 = x;
+		else if(box.x2 < x) box.x2 = x;
+		if(box.y1 > y) box.y1 = y;
+		else if(box.y2 < y) box.y2 = y;
+	    }
+	}
+	else 
+	{
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+		else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+		if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+		else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    
+    (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr	pDrawable,
+		   GCPtr	pGC,
+		   int		nRects,
+		   xRectangle	*pRects)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if (nRects && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	xRectangle  *pRectsTmp = pRects;
+	int	    nRectsTmp = nRects;
+
+	box.x1 = pRectsTmp->x;
+	box.x2 = box.x1 + pRectsTmp->width;
+	box.y1 = pRectsTmp->y;
+	box.y2 = box.y1 + pRectsTmp->height;
+
+	while(--nRectsTmp) 
+	{
+	    pRectsTmp++;
+	    if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+	    if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+		box.x2 = pRectsTmp->x + pRectsTmp->width;
+	    if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+	    if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+		box.y2 = pRectsTmp->y + pRectsTmp->height;
+	}
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		nArcs,
+		  xArc		*pArcs)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nArcs && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	box;
+	int	nArcsTmp = nArcs;
+	xArc	*pArcsTmp = pArcs;
+
+	box.x1 = pArcsTmp->x;
+	box.x2 = box.x1 + pArcsTmp->width;
+	box.y1 = pArcsTmp->y;
+	box.y2 = box.y1 + pArcsTmp->height;
+
+	while(--nArcsTmp) 
+	{
+	    pArcsTmp++;
+	    if(box.x1 > pArcsTmp->x)
+		box.x1 = pArcsTmp->x;
+	    if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+		box.x2 = pArcsTmp->x + pArcsTmp->width;
+	    if(box.y1 > pArcsTmp->y)
+		box.y1 = pArcsTmp->y;
+	    if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+		box.y2 = pArcsTmp->y + pArcsTmp->height;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function.  Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr	pDrawable,
+		   FontPtr	font,
+		   int		x,
+		   int		y,
+		   unsigned int	n,
+		   CharInfoPtr	*charinfo,
+		   Bool		imageblt,
+		   int		subWindowMode)
+{
+    ExtentInfoRec   extents;
+    BoxRec	    box;
+
+    QueryGlyphExtents(font, charinfo, n, &extents);
+    if (imageblt)
+    {
+	if (extents.overallWidth > extents.overallRight)
+	    extents.overallRight = extents.overallWidth;
+	if (extents.overallWidth < extents.overallLeft)
+	    extents.overallLeft = extents.overallWidth;
+	if (extents.overallLeft > 0)
+	    extents.overallLeft = 0;
+	if (extents.fontAscent > extents.overallAscent)
+	    extents.overallAscent = extents.fontAscent;
+	if (extents.fontDescent > extents.overallDescent)
+	    extents.overallDescent = extents.fontDescent;
+    }
+    box.x1 = x + extents.overallLeft;
+    box.y1 = y - extents.overallAscent;
+    box.x2 = x + extents.overallRight;
+    box.y2 = y + extents.overallDescent;
+    damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8   0
+#define TT_IMAGE8  1
+#define TT_POLY16  2
+#define TT_IMAGE16 3
+
+static int 
+damageText (DrawablePtr	    pDrawable,
+	    GCPtr	    pGC,
+	    int		    x,
+	    int		    y,
+	    unsigned long   count,
+	    char	    *chars,
+	    FontEncoding    fontEncoding,
+	    Bool	    textType)
+{
+    CharInfoPtr	    *charinfo;
+    CharInfoPtr	    *info;
+    unsigned long   i;
+    unsigned int    n;
+    int		    w;
+    Bool	    imageblt;
+
+    imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+    charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
+    if (!charinfo)
+	return x;
+
+    GetGlyphs(pGC->font, count, (unsigned char *)chars,
+	      fontEncoding, &i, charinfo);
+    n = (unsigned int)i;
+    w = 0;
+    if (!imageblt)
+	for (info = charinfo; i--; info++)
+	    w += (*info)->metrics.characterWidth;
+
+    if (n != 0) {
+	damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+			   charinfo, imageblt, pGC->subWindowMode);
+
+#ifndef NXAGENT_SERVER
+
+	if (imageblt)
+	    (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+				       FONTGLYPHS(pGC->font));
+	else
+	    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+				      FONTGLYPHS(pGC->font));
+#endif
+
+    }
+    DEALLOCATE_LOCAL(charinfo);
+    return x + w;
+}
+
+#ifndef NXAGENT_SERVER
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    x,
+		int	    y,
+		int	    count,
+		char	    *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_POLY8);
+    else
+	x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static int
+damagePolyText16(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 unsigned short	*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_POLY16);
+    else
+	x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static void
+damageImageText8(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 char		*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_IMAGE8);
+    else
+	(*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		x,
+		  int		y,
+		  int		count,
+		  unsigned short *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_IMAGE16);
+    else
+	(*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#else /* #ifndef NXAGENT_SERVER */
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    x,
+		int	    y,
+		int	    count,
+		char	    *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_POLY8);
+
+    x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static int
+damagePolyText16(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 unsigned short	*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_POLY16);
+
+    x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static void
+damageImageText8(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 char		*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_IMAGE8);
+
+    (*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		x,
+		  int		y,
+		  int		count,
+		  unsigned short *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_IMAGE16);
+
+    (*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+#endif /* #ifndef NXAGENT_SERVER */
+
+static void
+damageImageGlyphBlt(DrawablePtr	    pDrawable,
+		    GCPtr	    pGC,
+		    int		    x,
+		    int		    y,
+		    unsigned int    nglyph,
+		    CharInfoPtr	    *ppci,
+		    pointer	    pglyphBase)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+		       nglyph, ppci, TRUE, pGC->subWindowMode);
+    (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+					ppci, pglyphBase);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr	pDrawable,
+		   GCPtr	pGC,
+		   int		x,
+		   int		y,
+		   unsigned int	nglyph,
+		   CharInfoPtr	*ppci,
+		   pointer	pglyphBase)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+		       nglyph, ppci, FALSE, pGC->subWindowMode);
+    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+				ppci, pglyphBase);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr		pGC,
+		 PixmapPtr	pBitMap,
+		 DrawablePtr	pDrawable,
+		 int		dx,
+		 int		dy,
+		 int		xOrg,
+		 int		yOrg)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if(checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec box;
+
+        box.x1 = xOrg;
+        box.y1 = yOrg;
+
+        if(!pGC->miTranslate) {
+           box.x1 += pDrawable->x;          
+           box.y1 += pDrawable->y;          
+        }
+
+	box.x2 = box.x1 + dx;
+	box.y2 = box.y1 + dy;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+    while (*pPrev)
+    {
+	if (*pPrev == pDamage)
+	{
+	    *pPrev = pDamage->pNext;
+	    return;
+	}
+	pPrev = &(*pPrev)->pNext;
+    }
+#if DAMAGE_VALIDATE_ENABLE
+    ErrorF ("Damage not on list\n");
+    abort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+    DamagePtr	pOld;
+
+    for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+	if (pOld == pDamage) {
+	    ErrorF ("Damage already on list\n");
+	    abort ();
+	}
+#endif
+    pDamage->pNext = *pPrev;
+    *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if (pPixmap->refcnt == 1)
+    {
+	DamagePtr	*pPrev = getPixmapDamageRef (pPixmap);
+	DamagePtr	pDamage;
+
+	while ((pDamage = *pPrev))
+	{
+	    damageRemoveDamage (pPrev, pDamage);
+	    if (!pDamage->isWindow)
+		DamageDestroy (pDamage);
+	}
+    }
+    unwrap (pScrPriv, pScreen, DestroyPixmap);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+    return TRUE;
+}
+
+static void
+damagePaintWindow(WindowPtr pWindow,
+		  RegionPtr prgn,
+		  int	    what)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    /*
+     * Painting background none doesn't actually *do* anything, so
+     * no damage is recorded
+     */
+    if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
+	getWindowDamage (pWindow))
+	damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+    if(what == PW_BACKGROUND) {
+	unwrap (pScrPriv, pScreen, PaintWindowBackground);
+	(*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+	wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+    } else {
+	unwrap (pScrPriv, pScreen, PaintWindowBorder);
+	(*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+	wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+    }
+}
+
+
+static void
+damageCopyWindow(WindowPtr	pWindow,
+		 DDXPointRec	ptOldOrg,
+		 RegionPtr	prgnSrc)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if (getWindowDamage (pWindow))
+    {
+	int dx = pWindow->drawable.x - ptOldOrg.x;
+	int dy = pWindow->drawable.y - ptOldOrg.y;
+	
+	/*
+	 * The region comes in source relative, but the damage occurs
+	 * at the destination location.  Translate back and forth.
+	 */
+	REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
+	damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
+	REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
+    }
+    unwrap (pScrPriv, pScreen, CopyWindow);
+    (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+    wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+GCOps damageGCOps = {
+    damageFillSpans, damageSetSpans,
+    damagePutImage, damageCopyArea,
+    damageCopyPlane, damagePolyPoint,
+    damagePolylines, damagePolySegment,
+    damagePolyRectangle, damagePolyArc,
+    damageFillPolygon, damagePolyFillRect,
+    damagePolyFillArc, damagePolyText8,
+    damagePolyText16, damageImageText8,
+    damageImageText16, damageImageGlyphBlt,
+    damagePolyGlyphBlt, damagePushPixels,
+#ifdef NEED_LINEHELPER
+    NULL,
+#endif
+    {NULL}		/* devPrivate */
+};
+
+static void
+damageRestoreAreas (PixmapPtr	pPixmap,
+		    RegionPtr	prgn,
+		    int		xorg,
+		    int		yorg,
+		    WindowPtr	pWindow)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+    unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+    (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+						xorg, yorg, pWindow);
+    wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+			     damageRestoreAreas);
+}
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	PixmapPtr   pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+	DamagePtr   *pPrev = getPixmapDamageRef(pOldPixmap);
+	
+	while (pDamage)
+	{
+	    damageRemoveDamage (pPrev, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+    unwrap (pScrPriv, pScreen, SetWindowPixmap);
+    (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	DamagePtr   *pPrev = getPixmapDamageRef(pPixmap);
+	
+	while (pDamage)
+	{
+	    damageInsertDamage (pPrev, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    Bool	ret;
+    damageScrPriv(pScreen);
+
+    while ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	DamageUnregister (&pWindow->drawable, pDamage);
+	DamageDestroy (pDamage);
+    }
+    unwrap (pScrPriv, pScreen, DestroyWindow);
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    return ret;
+}
+
+static Bool
+damageCloseScreen (int i, ScreenPtr pScreen)
+{
+    damageScrPriv(pScreen);
+
+    unwrap (pScrPriv, pScreen, DestroyPixmap);
+    unwrap (pScrPriv, pScreen, CreateGC);
+    unwrap (pScrPriv, pScreen, PaintWindowBackground);
+    unwrap (pScrPriv, pScreen, PaintWindowBorder);
+    unwrap (pScrPriv, pScreen, CopyWindow);
+    unwrap (pScrPriv, pScreen, CloseScreen);
+    unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+    xfree (pScrPriv);
+    return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+int damageScrPrivateIndex;
+int damagePixPrivateIndex;
+int damageGCPrivateIndex;
+int damageWinPrivateIndex;
+int damageGeneration;
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+    DamageScrPrivPtr	pScrPriv;
+#ifdef RENDER
+    PictureScreenPtr	ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+    if (damageGeneration != serverGeneration)
+    {
+	damageScrPrivateIndex = AllocateScreenPrivateIndex ();
+	if (damageScrPrivateIndex == -1)
+	    return FALSE;
+	damageGCPrivateIndex = AllocateGCPrivateIndex ();
+	if (damageGCPrivateIndex == -1)
+	    return FALSE;
+	damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
+	if (damagePixPrivateIndex == -1)
+	    return FALSE;
+	damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+	if (damageWinPrivateIndex == -1)
+	    return FALSE;
+	damageGeneration = serverGeneration;
+    }
+    if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
+	return TRUE;
+
+    if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
+	return FALSE;
+    if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
+	return FALSE;
+    if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+	return FALSE;
+
+    pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
+    if (!pScrPriv)
+	return FALSE;
+
+#ifdef COMPOSITE
+    /* This is a kludge to ensure wrapping order with the composite wrapper.
+     * If it's done from compinit.c, then DamageSetup may be called before the
+     * extension init phase, so that cw will be higher in the wrapping chain and
+     * rewrite drawables before damage gets to it, causing confusion.
+     */
+    if (!noCompositeExtension)
+	miInitializeCompositeWrapper (pScreen);
+#endif
+	
+    pScrPriv->internalLevel = 0;
+    pScrPriv->pScreenDamage = 0;
+
+    wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+    wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+    wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+    wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+    wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+    wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+    wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+			     damageRestoreAreas);
+#ifdef RENDER
+    if (ps) {
+	wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+	wrap (pScrPriv, ps, Composite, damageComposite);
+    }
+#endif
+
+    pScreen->devPrivates[damageScrPrivateIndex].ptr = (pointer) pScrPriv;
+    return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc  damageReport,
+	      DamageDestroyFunc	damageDestroy,
+	      DamageReportLevel	damageLevel,
+	      Bool		isInternal,
+	      ScreenPtr		pScreen,
+	      void		*closure)
+{
+    DamagePtr	pDamage;
+
+    pDamage = xalloc (sizeof (DamageRec));
+    if (!pDamage)
+	return 0;
+    pDamage->pNext = 0;
+    pDamage->pNextWin = 0;
+    REGION_NULL(pScreen, &pDamage->damage);
+    
+    pDamage->damageLevel = damageLevel;
+    pDamage->isInternal = isInternal;
+    pDamage->closure = closure;
+    pDamage->isWindow = FALSE;
+    pDamage->pDrawable = 0;
+
+    pDamage->damageReport = damageReport;
+    pDamage->damageDestroy = damageDestroy;
+    return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+		DamagePtr   pDamage)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+	DamagePtr   pOld;
+	
+	for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+	    if (pOld == pDamage) {
+		ErrorF ("Damage already on window list\n");
+		abort ();
+	    }
+#endif
+	pDamage->pNextWin = *pPrev;
+	*pPrev = pDamage;
+	pDamage->isWindow = TRUE;
+    }
+    else
+	pDamage->isWindow = FALSE;
+    pDamage->pDrawable = pDrawable;
+    damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+    damageScrPriv (pScreen);
+
+    pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr	    pDrawable,
+		  DamagePtr	    pDamage)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+	int	found = 0;
+#endif
+
+	while (*pPrev)
+	{
+	    if (*pPrev == pDamage)
+	    {
+		*pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+		found = 1;
+#endif
+		break;
+	    }
+	    pPrev = &(*pPrev)->pNextWin;
+	}
+#if DAMAGE_VALIDATE_ENABLE
+	if (!found) {
+	    ErrorF ("Damage not on window list\n");
+	    abort ();
+	}
+#endif
+    }
+    pDamage->pDrawable = 0;
+    damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr    pDamage)
+{
+    if (pDamage->damageDestroy)
+	(*pDamage->damageDestroy) (pDamage, pDamage->closure);
+    REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
+    xfree (pDamage);
+}
+
+Bool
+DamageSubtract (DamagePtr	    pDamage,
+		const RegionPtr	    pRegion)
+{
+    RegionPtr	pClip;
+    RegionRec	pixmapClip;
+    DrawablePtr	pDrawable = pDamage->pDrawable;
+    
+    REGION_SUBTRACT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pRegion);
+    if (pDrawable)
+    {
+	if (pDrawable->type == DRAWABLE_WINDOW)
+	    pClip = &((WindowPtr) pDrawable)->borderClip;
+	else
+	{
+	    BoxRec  box;
+
+	    box.x1 = pDrawable->x;
+	    box.y1 = pDrawable->y;
+	    box.x2 = pDrawable->x + pDrawable->width;
+	    box.y2 = pDrawable->y + pDrawable->height;
+	    REGION_INIT (pDrawable->pScreen, &pixmapClip, &box, 1);
+	    pClip = &pixmapClip;
+	}
+	REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
+	REGION_INTERSECT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pClip);
+	REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
+	if (pDrawable->type != DRAWABLE_WINDOW)
+	    REGION_UNINIT(pDrawable->pScreen, &pixmapClip);
+    }
+    return REGION_NOTEMPTY (pDrawable->pScreen, &pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr	    pDamage)
+{
+    REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr		    pDamage)
+{
+    return &pDamage->damage;
+}
+
+void
+DamageDamageRegion (DrawablePtr	pDrawable,
+		    RegionPtr	pRegion)
+{
+    damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original
new file mode 100644
index 000000000..286728cd1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.X.original
@@ -0,0 +1,1966 @@
+/*
+ * $Id: damage.c,v 1.19 2005/10/06 21:55:41 anholt Exp $
+ *
+ * Copyright © 2003 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include    <X11/X.h>
+#include    "scrnintstr.h"
+#include    "windowstr.h"
+#include    <X11/fonts/font.h>
+#include    "dixfontstr.h"
+#include    <X11/fonts/fontstruct.h>
+#include    "mi.h"
+#include    "regionstr.h"
+#include    "globals.h"
+#include    "gcstruct.h"
+#include    "damage.h"
+#include    "damagestr.h"
+#ifdef COMPOSITE
+#include    "cw.h"
+#endif
+
+#define wrap(priv, real, mem, func) {\
+    priv->mem = real->mem; \
+    real->mem = func; \
+}
+
+#define unwrap(priv, real, mem) {\
+    real->mem = priv->mem; \
+}
+
+#define BOX_SAME(a,b) \
+    ((a)->x1 == (b)->x1 && \
+     (a)->y1 == (b)->y1 && \
+     (a)->x2 == (b)->x2 && \
+     (a)->y2 == (b)->y2)
+
+#define DAMAGE_VALIDATE_ENABLE 0
+#define DAMAGE_DEBUG_ENABLE 0
+#if DAMAGE_DEBUG_ENABLE
+#define DAMAGE_DEBUG(x)	ErrorF x
+#else
+#define DAMAGE_DEBUG(x)
+#endif
+
+#define getPixmapDamageRef(pPixmap) \
+    ((DamagePtr *) &(pPixmap->devPrivates[damagePixPrivateIndex].ptr))
+
+#define pixmapDamage(pPixmap)		damagePixPriv(pPixmap)
+
+static DamagePtr *
+getDrawableDamageRef (DrawablePtr pDrawable)
+{
+    PixmapPtr   pPixmap;
+    
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	ScreenPtr   pScreen = pDrawable->pScreen;
+
+	pPixmap = 0;
+	if (pScreen->GetWindowPixmap
+#ifdef ROOTLESS_WORKAROUND
+	    && ((WindowPtr)pDrawable)->viewable
+#endif
+	    )
+	    pPixmap = (*pScreen->GetWindowPixmap) ((WindowPtr)pDrawable);
+
+	if (!pPixmap)
+	{
+	    damageScrPriv(pScreen);
+
+	    return &pScrPriv->pScreenDamage;
+	}
+    }
+    else
+	pPixmap = (PixmapPtr) pDrawable;
+    return getPixmapDamageRef (pPixmap);
+}
+
+#define getDrawableDamage(pDrawable)	(*getDrawableDamageRef (pDrawable))
+#define getWindowDamage(pWin)		getDrawableDamage(&(pWin)->drawable)
+
+#define drawableDamage(pDrawable)	\
+    DamagePtr	pDamage = getDrawableDamage(pDrawable)
+
+#define windowDamage(pWin)		drawableDamage(&(pWin)->drawable)
+
+#define winDamageRef(pWindow) \
+    DamagePtr	*pPrev = (DamagePtr *) \
+	    &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+
+#if DAMAGE_DEBUG_ENABLE
+static void
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
+#define damageDamageRegion(d,r,c,m) _damageDamageRegion(d,r,c,m,__FUNCTION__)
+#else
+static void
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
+			int subWindowMode)
+#endif
+{
+    ScreenPtr	    pScreen = pDrawable->pScreen;
+    damageScrPriv(pScreen);
+    drawableDamage(pDrawable);
+    DamagePtr	    pNext;
+    RegionRec	    clippedRec;
+    RegionPtr	    pDamageRegion;
+    RegionRec	    pixClip;
+    Bool	    was_empty;
+    RegionRec	    tmpRegion;
+    BoxRec	    tmpBox;
+    int		    draw_x, draw_y;
+#ifdef COMPOSITE
+    int		    screen_x = 0, screen_y = 0;
+#endif
+
+    /* short circuit for empty regions */
+    if (!REGION_NOTEMPTY(pScreen, pRegion))
+	return;
+    
+#ifdef COMPOSITE
+    /*
+     * When drawing to a pixmap which is storing window contents,
+     * the region presented is in pixmap relative coordinates which
+     * need to be converted to screen relative coordinates
+     */
+    if (pDrawable->type != DRAWABLE_WINDOW)
+    {
+	screen_x = ((PixmapPtr) pDrawable)->screen_x - pDrawable->x;
+	screen_y = ((PixmapPtr) pDrawable)->screen_y - pDrawable->y;
+    }
+    if (screen_x || screen_y)
+        REGION_TRANSLATE (pScreen, pRegion, screen_x, screen_y);
+#endif
+	
+    if (pDrawable->type == DRAWABLE_WINDOW &&
+	((WindowPtr)(pDrawable))->backingStore == NotUseful)
+    {
+	if (subWindowMode == ClipByChildren)
+	{
+	    REGION_INTERSECT(pScreen, pRegion, pRegion,
+			     &((WindowPtr)(pDrawable))->clipList);
+	}
+	else if (subWindowMode == IncludeInferiors)
+	{
+	    RegionPtr pTempRegion =
+		NotClippedByChildren((WindowPtr)(pDrawable));
+	    REGION_INTERSECT(pScreen, pRegion, pRegion, pTempRegion);
+	    REGION_DESTROY(pScreen, pTempRegion);
+	}
+	/* If subWindowMode is set to an invalid value, don't perform
+	 * any drawable-based clipping. */
+    }
+        
+
+    REGION_NULL (pScreen, &clippedRec);
+    for (; pDamage; pDamage = pNext)
+    {
+	pNext = pDamage->pNext;
+	/*
+	 * Check for internal damage and don't send events
+	 */
+	if (pScrPriv->internalLevel > 0 && !pDamage->isInternal)
+	{
+	    DAMAGE_DEBUG (("non internal damage, skipping at %d\n",
+			   pScrPriv->internalLevel));
+	    continue;
+	}
+	/*
+	 * Check for unrealized windows
+	 */
+	if (pDamage->pDrawable->type == DRAWABLE_WINDOW &&
+	    !((WindowPtr) (pDamage->pDrawable))->realized)
+	{
+#if 0
+	    DAMAGE_DEBUG (("damage while window unrealized\n"));
+#endif
+	    continue;
+	}
+	
+	draw_x = pDamage->pDrawable->x;
+	draw_y = pDamage->pDrawable->y;
+#ifdef COMPOSITE
+	/*
+	 * Need to move everyone to screen coordinates
+	 * XXX what about off-screen pixmaps with non-zero x/y?
+	 */
+	if (pDamage->pDrawable->type != DRAWABLE_WINDOW)
+	{
+	    draw_x += ((PixmapPtr) pDamage->pDrawable)->screen_x;
+	    draw_y += ((PixmapPtr) pDamage->pDrawable)->screen_y;
+	}
+#endif
+	
+	/*
+	 * Clip against border or pixmap bounds
+	 */
+	
+	pDamageRegion = pRegion;
+	if (clip || pDamage->pDrawable != pDrawable)
+	{
+	    pDamageRegion = &clippedRec;
+	    if (pDamage->pDrawable->type == DRAWABLE_WINDOW) {
+		REGION_INTERSECT (pScreen, pDamageRegion, pRegion,
+		    &((WindowPtr)(pDamage->pDrawable))->borderClip);
+	    } else {
+		BoxRec	box;
+		box.x1 = draw_x;
+		box.y1 = draw_y;
+		box.x2 = draw_x + pDamage->pDrawable->width;
+		box.y2 = draw_y + pDamage->pDrawable->height;
+		REGION_INIT(pScreen, &pixClip, &box, 1);
+		REGION_INTERSECT (pScreen, pDamageRegion, pRegion, &pixClip);
+		REGION_UNINIT(pScreen, &pixClip);
+	    }
+	    /*
+	     * Short circuit empty results
+	     */
+	    if (!REGION_NOTEMPTY(pScreen, pDamageRegion))
+		continue;
+	}
+	
+	DAMAGE_DEBUG (("%s %d x %d +%d +%d (target 0x%lx monitor 0x%lx)\n",
+		       where,
+		       pDamageRegion->extents.x2 - pDamageRegion->extents.x1,
+		       pDamageRegion->extents.y2 - pDamageRegion->extents.y1,
+		       pDamageRegion->extents.x1, pDamageRegion->extents.y1,
+		       pDrawable->id, pDamage->pDrawable->id));
+	
+	/*
+	 * Move region to target coordinate space
+	 */
+	if (draw_x || draw_y)
+	    REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
+	
+	switch (pDamage->damageLevel) {
+	case DamageReportRawRegion:
+	    (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+	    break;
+	case DamageReportDeltaRegion:
+	    REGION_NULL (pScreen, &tmpRegion);
+	    REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
+	    if (REGION_NOTEMPTY (pScreen, &tmpRegion))
+	    {
+		REGION_UNION(pScreen, &pDamage->damage,
+			     &pDamage->damage, pDamageRegion);
+		(*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+	    }
+	    REGION_UNINIT(pScreen, &tmpRegion);
+	    break;
+	case DamageReportBoundingBox:
+	    tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
+	    REGION_UNION(pScreen, &pDamage->damage,
+			 &pDamage->damage, pDamageRegion);
+	    if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))
+		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+	    break;
+	case DamageReportNonEmpty:
+	    was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
+	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	    if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))
+		(*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
+	    break;
+	case DamageReportNone:
+	    REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	    break;
+	}
+	/*
+	 * translate original region back
+	 */
+	if (pDamageRegion == pRegion && (draw_x || draw_y))
+	    REGION_TRANSLATE (pScreen, pDamageRegion, draw_x, draw_y);
+    }
+#ifdef COMPOSITE
+    if (screen_x || screen_y)
+	REGION_TRANSLATE (pScreen, pRegion, -screen_x, -screen_y);
+#endif
+    
+    REGION_UNINIT (pScreen, &clippedRec);
+}
+
+#if DAMAGE_DEBUG_ENABLE
+#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
+static void
+_damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode, const char *where)
+#else
+static void
+damageDamageBox (DrawablePtr pDrawable, BoxPtr pBox, int subWindowMode)
+#endif
+{
+    RegionRec	region;
+
+    REGION_INIT (pDrawable->pScreen, &region, pBox, 1);
+#if DAMAGE_DEBUG_ENABLE
+    _damageDamageRegion (pDrawable, &region, TRUE, subWindowMode, where);
+#else
+    damageDamageRegion (pDrawable, &region, TRUE, subWindowMode);
+#endif
+    REGION_UNINIT (pDrawable->pScreen, &region);
+}
+
+static void damageValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void damageChangeGC(GCPtr, unsigned long);
+static void damageCopyGC(GCPtr, unsigned long, GCPtr);
+static void damageDestroyGC(GCPtr);
+static void damageChangeClip(GCPtr, int, pointer, int);
+static void damageDestroyClip(GCPtr);
+static void damageCopyClip(GCPtr, GCPtr);
+
+GCFuncs damageGCFuncs = {
+    damageValidateGC, damageChangeGC, damageCopyGC, damageDestroyGC,
+    damageChangeClip, damageDestroyClip, damageCopyClip
+};
+
+extern GCOps damageGCOps;
+
+static Bool
+damageCreateGC(GCPtr pGC)
+{
+    ScreenPtr pScreen = pGC->pScreen;
+    damageScrPriv(pScreen);
+    damageGCPriv(pGC);
+    Bool ret;
+
+    pGC->pCompositeClip = 0;
+    unwrap (pScrPriv, pScreen, CreateGC);
+    if((ret = (*pScreen->CreateGC) (pGC))) {
+	pGCPriv->ops = NULL;
+	pGCPriv->funcs = pGC->funcs;
+	pGC->funcs = &damageGCFuncs;
+    }
+    wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+
+    return ret;
+}
+
+#ifdef NOTUSED
+static void
+damageWrapGC (GCPtr pGC)
+{
+    damageGCPriv(pGC);
+
+    pGCPriv->ops = NULL;
+    pGCPriv->funcs = pGC->funcs;
+    pGC->funcs = &damageGCFuncs;
+}
+
+static void
+damageUnwrapGC (GCPtr pGC)
+{
+    damageGCPriv(pGC);
+
+    pGC->funcs = pGCPriv->funcs;
+    if (pGCPriv->ops)
+	pGC->ops = pGCPriv->ops;
+}
+#endif
+
+#define DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable) \
+    damageGCPriv(pGC);  \
+    GCFuncs *oldFuncs = pGC->funcs; \
+    unwrap(pGCPriv, pGC, funcs);  \
+    unwrap(pGCPriv, pGC, ops); \
+
+#define DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable) \
+    wrap(pGCPriv, pGC, funcs, oldFuncs); \
+    wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+#define DAMAGE_GC_FUNC_PROLOGUE(pGC) \
+    damageGCPriv(pGC); \
+    unwrap(pGCPriv, pGC, funcs); \
+    if (pGCPriv->ops) unwrap(pGCPriv, pGC, ops)
+
+#define DAMAGE_GC_FUNC_EPILOGUE(pGC) \
+    wrap(pGCPriv, pGC, funcs, &damageGCFuncs);  \
+    if (pGCPriv->ops) wrap(pGCPriv, pGC, ops, &damageGCOps)
+
+static void
+damageValidateGC(GCPtr         pGC,
+		 unsigned long changes,
+		 DrawablePtr   pDrawable)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+    pGCPriv->ops = pGC->ops;  /* just so it's not NULL */
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageDestroyGC(GCPtr pGC)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->DestroyGC)(pGC);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageChangeGC (GCPtr		pGC,
+		unsigned long   mask)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ChangeGC) (pGC, mask);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyGC (GCPtr	    pGCSrc,
+	      unsigned long mask,
+	      GCPtr	    pGCDst)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGCDst);
+    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+    DAMAGE_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+damageChangeClip (GCPtr	    pGC,
+		  int	    type,
+		  pointer   pvalue,
+		  int	    nrects)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+damageCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pgcDst);
+    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+    DAMAGE_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+damageDestroyClip(GCPtr pGC)
+{
+    DAMAGE_GC_FUNC_PROLOGUE (pGC);
+    (* pGC->funcs->DestroyClip)(pGC);
+    DAMAGE_GC_FUNC_EPILOGUE (pGC);
+}
+
+#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \
+    BoxPtr extents = &pGC->pCompositeClip->extents;\
+    if(box.x1 < extents->x1) box.x1 = extents->x1; \
+    if(box.x2 > extents->x2) box.x2 = extents->x2; \
+    if(box.y1 < extents->y1) box.y1 = extents->y1; \
+    if(box.y2 > extents->y2) box.y2 = extents->y2; \
+    }
+
+#define TRANSLATE_BOX(box, pDrawable) { \
+    box.x1 += pDrawable->x; \
+    box.x2 += pDrawable->x; \
+    box.y1 += pDrawable->y; \
+    box.y2 += pDrawable->y; \
+    }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \
+    TRANSLATE_BOX(box, pDrawable); \
+    TRIM_BOX(box, pGC); \
+    }
+
+#define BOX_NOT_EMPTY(box) \
+    (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+#define checkGCDamage(d,g)	(getDrawableDamage(d) && \
+				 (!g->pCompositeClip ||\
+				  REGION_NOTEMPTY(d->pScreen, \
+						  g->pCompositeClip)))
+
+#ifdef RENDER
+
+#define TRIM_PICTURE_BOX(box, pDst) { \
+    BoxPtr extents = &pDst->pCompositeClip->extents;\
+    if(box.x1 < extents->x1) box.x1 = extents->x1; \
+    if(box.x2 > extents->x2) box.x2 = extents->x2; \
+    if(box.y1 < extents->y1) box.y1 = extents->y1; \
+    if(box.y2 > extents->y2) box.y2 = extents->y2; \
+    }
+    
+#define checkPictureDamage(p)	(getDrawableDamage(p->pDrawable) && \
+				 REGION_NOTEMPTY(pScreen, p->pCompositeClip))
+
+static void
+damageComposite (CARD8      op,
+		   PicturePtr pSrc,
+		   PicturePtr pMask,
+		   PicturePtr pDst,
+		   INT16      xSrc,
+		   INT16      ySrc,
+		   INT16      xMask,
+		   INT16      yMask,
+		   INT16      xDst,
+		   INT16      yDst,
+		   CARD16     width,
+		   CARD16     height)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    damageScrPriv(pScreen);
+
+    if (checkPictureDamage (pDst))
+    {
+	BoxRec	box;
+
+	box.x1 = xDst + pDst->pDrawable->x;
+	box.y1 = yDst + pDst->pDrawable->y;
+	box.x2 = box.x1 + width;
+	box.y2 = box.y1 + height;
+	TRIM_PICTURE_BOX(box, pDst);
+	if (BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+    }
+    unwrap (pScrPriv, ps, Composite);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+    wrap (pScrPriv, ps, Composite, damageComposite);
+}
+
+static void
+damageGlyphs (CARD8		op,
+		PicturePtr	pSrc,
+		PicturePtr	pDst,
+		PictFormatPtr	maskFormat,
+		INT16		xSrc,
+		INT16		ySrc,
+		int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    damageScrPriv(pScreen);
+
+    if (checkPictureDamage (pDst))
+    {
+	int		nlistTmp = nlist;
+	GlyphListPtr	listTmp = list;
+	GlyphPtr	*glyphsTmp = glyphs;
+	int		x, y;
+	int		n;
+	GlyphPtr	glyph;
+	BoxRec		box;
+	int		x1, y1, x2, y2;
+
+	box.x1 = 32767;
+	box.y1 = 32767;
+	box.x2 = -32767;
+	box.y2 = -32767;
+	x = pDst->pDrawable->x;
+	y = pDst->pDrawable->y;
+	while (nlistTmp--)
+	{
+	    x += listTmp->xOff;
+	    y += listTmp->yOff;
+	    n = listTmp->len;
+	    while (n--)
+	    {
+		glyph = *glyphsTmp++;
+		x1 = x - glyph->info.x;
+		y1 = y - glyph->info.y;
+		x2 = x1 + glyph->info.width;
+		y2 = y1 + glyph->info.height;
+		if (x1 < box.x1)
+		    box.x1 = x1;
+		if (y1 < box.y1)
+		    box.y1 = y1;
+		if (x2 > box.x2)
+		    box.x2 = x2;
+		if (y2 > box.y2)
+		    box.y2 = y2;
+		x += glyph->info.xOff;
+		y += glyph->info.yOff;
+	    }
+	    listTmp++;
+	}
+	TRIM_PICTURE_BOX (box, pDst);
+	if (BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDst->pDrawable, &box, pDst->subWindowMode);
+    }
+    unwrap (pScrPriv, ps, Glyphs);
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+    wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+}
+#endif
+
+/**********************************************************/
+
+
+static void
+damageFillSpans(DrawablePtr pDrawable,
+		GC	    *pGC,
+		int	    npt,
+		DDXPointPtr ppt,
+		int	    *pwidth,
+		int	    fSorted)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	int	    nptTmp = npt;
+	DDXPointPtr pptTmp = ppt;
+	int	    *pwidthTmp = pwidth;
+	BoxRec	    box;
+
+	box.x1 = pptTmp->x;
+	box.x2 = box.x1 + *pwidthTmp;
+	box.y2 = box.y1 = pptTmp->y;
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   pwidthTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   if(box.x2 < (pptTmp->x + *pwidthTmp))
+		box.x2 = pptTmp->x + *pwidthTmp;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.y2++;
+
+        if(!pGC->miTranslate) {
+           TRANSLATE_BOX(box, pDrawable);
+        }
+        TRIM_BOX(box, pGC); 
+
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    
+    (*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageSetSpans(DrawablePtr  pDrawable,
+	       GCPtr	    pGC,
+	       char	    *pcharsrc,
+	       DDXPointPtr  ppt,
+	       int	    *pwidth,
+	       int	    npt,
+	       int	    fSorted)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	DDXPointPtr pptTmp = ppt;
+	int	    *pwidthTmp = pwidth;
+	int	    nptTmp = npt;
+	BoxRec	    box;
+
+	box.x1 = pptTmp->x;
+	box.x2 = box.x1 + *pwidthTmp;
+	box.y2 = box.y1 = pptTmp->y;
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   pwidthTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   if(box.x2 < (pptTmp->x + *pwidthTmp))
+		box.x2 = pptTmp->x + *pwidthTmp;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.y2++;
+
+        if(!pGC->miTranslate) {
+           TRANSLATE_BOX(box, pDrawable);
+        }
+        TRIM_BOX(box, pGC); 
+
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePutImage(DrawablePtr  pDrawable,
+	       GCPtr	    pGC,
+	       int	    depth,
+	       int	    x,
+	       int	    y,
+	       int	    w,
+	       int	    h,
+	       int	    leftPad,
+	       int	    format,
+	       char	    *pImage)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if (checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = x + pDrawable->x;
+	box.x2 = box.x1 + w;
+	box.y1 = y + pDrawable->y;
+	box.y2 = box.y1 + h;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+		leftPad, format, pImage);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static RegionPtr
+damageCopyArea(DrawablePtr   pSrc,
+	       DrawablePtr  pDst,
+	       GC	    *pGC,
+	       int	    srcx,
+	       int	    srcy,
+	       int	    width,
+	       int	    height,
+	       int	    dstx,
+	       int	    dsty)
+{
+    RegionPtr ret;
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+    
+    /* The driver will only call SourceValidate() when pSrc != pDst,
+     * but the software sprite (misprite.c) always need to know when a
+     * drawable is copied so it can remove the sprite. See #1030. */
+    if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+	pSrc->type == DRAWABLE_WINDOW &&
+	((WindowPtr)pSrc)->viewable)
+    {
+	(*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+    }
+    
+    if (checkGCDamage (pDst, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = dstx + pDst->x;
+	box.x2 = box.x1 + width;
+	box.y1 = dsty + pDst->y;
+	box.y2 = box.y1 + height;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDst, &box, pGC->subWindowMode);
+    }
+
+    ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+            pGC, srcx, srcy, width, height, dstx, dsty);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+    return ret;
+}
+
+static RegionPtr
+damageCopyPlane(DrawablePtr	pSrc,
+		DrawablePtr	pDst,
+		GCPtr		pGC,
+		int		srcx,
+		int		srcy,
+		int		width,
+		int		height,
+		int		dstx,
+		int		dsty,
+		unsigned long	bitPlane)
+{
+    RegionPtr ret;
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDst);
+
+    /* The driver will only call SourceValidate() when pSrc != pDst,
+     * but the software sprite (misprite.c) always need to know when a
+     * drawable is copied so it can remove the sprite. See #1030. */
+    if ((pSrc == pDst) && pSrc->pScreen->SourceValidate &&
+	pSrc->type == DRAWABLE_WINDOW &&
+	((WindowPtr)pSrc)->viewable)
+    {
+        (*pSrc->pScreen->SourceValidate) (pSrc, srcx, srcy, width, height);
+    }
+
+    if (checkGCDamage (pDst, pGC))
+    {
+	BoxRec box;
+
+	box.x1 = dstx + pDst->x;
+	box.x2 = box.x1 + width;
+	box.y1 = dsty + pDst->y;
+	box.y2 = box.y1 + height;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDst, &box, pGC->subWindowMode);
+    }
+
+    ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+	       pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
+    return ret;
+}
+
+static void
+damagePolyPoint(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    mode,
+		int	    npt,
+		xPoint	    *ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	box;
+	int	nptTmp = npt;
+	xPoint	*pptTmp = ppt;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	/* this could be slow if the points were spread out */
+
+	while(--nptTmp) 
+	{
+	   pptTmp++;
+	   if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+	   else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+	   if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+	   else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	}
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolylines(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    mode,
+		int	    npt,
+		DDXPointPtr ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt && checkGCDamage (pDrawable, pGC))
+    {
+	int	    nptTmp = npt;
+	DDXPointPtr pptTmp = ppt;
+	BoxRec	    box;
+	int	    extra = pGC->lineWidth >> 1;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	if(nptTmp > 1) 
+	{
+	   if(pGC->joinStyle == JoinMiter)
+		extra = 6 * pGC->lineWidth;
+	   else if(pGC->capStyle == CapProjecting)
+		extra = pGC->lineWidth;
+        }
+
+	if(mode == CoordModePrevious) 
+	{
+	   int x = box.x1;
+	   int y = box.y1;
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		x += pptTmp->x;
+		y += pptTmp->y;
+		if(box.x1 > x) box.x1 = x;
+		else if(box.x2 < x) box.x2 = x;
+		if(box.y1 > y) box.y1 = y;
+		else if(box.y2 < y) box.y2 = y;
+	    }
+	}
+	else 
+	{
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+		else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+		if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+		else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolySegment(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		nSeg,
+		  xSegment	*pSeg)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nSeg && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	int	    extra = pGC->lineWidth;
+	int	    nsegTmp = nSeg;
+	xSegment    *pSegTmp = pSeg;
+
+        if(pGC->capStyle != CapProjecting)
+	   extra >>= 1;
+
+	if(pSegTmp->x2 > pSegTmp->x1) {
+	    box.x1 = pSegTmp->x1;
+	    box.x2 = pSegTmp->x2;
+	} else {
+	    box.x2 = pSegTmp->x1;
+	    box.x1 = pSegTmp->x2;
+	}
+
+	if(pSegTmp->y2 > pSegTmp->y1) {
+	    box.y1 = pSegTmp->y1;
+	    box.y2 = pSegTmp->y2;
+	} else {
+	    box.y2 = pSegTmp->y1;
+	    box.y1 = pSegTmp->y2;
+	}
+
+	while(--nsegTmp) 
+	{
+	    pSegTmp++;
+	    if(pSegTmp->x2 > pSegTmp->x1) 
+	    {
+		if(pSegTmp->x1 < box.x1) box.x1 = pSegTmp->x1;
+		if(pSegTmp->x2 > box.x2) box.x2 = pSegTmp->x2;
+	    }
+	    else 
+	    {
+		if(pSegTmp->x2 < box.x1) box.x1 = pSegTmp->x2;
+		if(pSegTmp->x1 > box.x2) box.x2 = pSegTmp->x1;
+	    }
+	    if(pSegTmp->y2 > pSegTmp->y1) 
+	    {
+		if(pSegTmp->y1 < box.y1) box.y1 = pSegTmp->y1;
+		if(pSegTmp->y2 > box.y2) box.y2 = pSegTmp->y2;
+	    }
+	    else
+	    {
+		if(pSegTmp->y2 < box.y1) box.y1 = pSegTmp->y2;
+		if(pSegTmp->y1 > box.y2) box.y2 = pSegTmp->y1;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyRectangle(DrawablePtr  pDrawable,
+		    GCPtr        pGC,
+		    int	         nRects,
+		    xRectangle  *pRects)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nRects && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	int	    offset1, offset2, offset3;
+	int	    nRectsTmp = nRects;
+	xRectangle  *pRectsTmp = pRects;
+
+	offset2 = pGC->lineWidth;
+	if(!offset2) offset2 = 1;
+	offset1 = offset2 >> 1;
+	offset3 = offset2 - offset1;
+
+	while(nRectsTmp--)
+	{
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y - offset1;
+	    box.x2 = box.x1 + pRectsTmp->width + offset2;
+	    box.y2 = box.y1 + offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y + offset3;
+	    box.x2 = box.x1 + offset2;
+	    box.y2 = box.y1 + pRectsTmp->height - offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x + pRectsTmp->width - offset1;
+	    box.y1 = pRectsTmp->y + offset3;
+	    box.x2 = box.x1 + offset2;
+	    box.y2 = box.y1 + pRectsTmp->height - offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    box.x1 = pRectsTmp->x - offset1;
+	    box.y1 = pRectsTmp->y + pRectsTmp->height - offset1;
+	    box.x2 = box.x1 + pRectsTmp->width + offset2;
+	    box.y2 = box.y1 + offset2;
+	    TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	    if(BOX_NOT_EMPTY(box))
+		damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+
+	    pRectsTmp++;
+	}
+    }
+    (*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyArc(DrawablePtr   pDrawable,
+	      GCPtr	    pGC,
+	      int	    nArcs,
+	      xArc	    *pArcs)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nArcs && checkGCDamage (pDrawable, pGC))
+    {
+	int	extra = pGC->lineWidth >> 1;
+	BoxRec	box;
+	int	nArcsTmp = nArcs;
+	xArc	*pArcsTmp = pArcs;
+
+	box.x1 = pArcsTmp->x;
+	box.x2 = box.x1 + pArcsTmp->width;
+	box.y1 = pArcsTmp->y;
+	box.y2 = box.y1 + pArcsTmp->height;
+
+	while(--nArcsTmp) 
+	{
+	    pArcsTmp++;
+	    if(box.x1 > pArcsTmp->x)
+		box.x1 = pArcsTmp->x;
+	    if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+		box.x2 = pArcsTmp->x + pArcsTmp->width;
+	    if(box.y1 > pArcsTmp->y) 
+		box.y1 = pArcsTmp->y;
+	    if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+		box.y2 = pArcsTmp->y + pArcsTmp->height;
+        }
+
+	if(extra) 
+	{
+	   box.x1 -= extra;
+	   box.x2 += extra;
+	   box.y1 -= extra;
+	   box.y2 += extra;
+        }
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageFillPolygon(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		shape,
+		  int		mode,
+		  int		npt,
+		  DDXPointPtr	ppt)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (npt > 2 && checkGCDamage (pDrawable, pGC))
+    {
+	DDXPointPtr pptTmp = ppt;
+	int	    nptTmp = npt;
+	BoxRec	    box;
+
+	box.x2 = box.x1 = pptTmp->x;
+	box.y2 = box.y1 = pptTmp->y;
+
+	if(mode != CoordModeOrigin) 
+	{
+	   int x = box.x1;
+	   int y = box.y1;
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		x += pptTmp->x;
+		y += pptTmp->y;
+		if(box.x1 > x) box.x1 = x;
+		else if(box.x2 < x) box.x2 = x;
+		if(box.y1 > y) box.y1 = y;
+		else if(box.y2 < y) box.y2 = y;
+	    }
+	}
+	else 
+	{
+	   while(--nptTmp) 
+	   {
+		pptTmp++;
+		if(box.x1 > pptTmp->x) box.x1 = pptTmp->x;
+		else if(box.x2 < pptTmp->x) box.x2 = pptTmp->x;
+		if(box.y1 > pptTmp->y) box.y1 = pptTmp->y;
+		else if(box.y2 < pptTmp->y) box.y2 = pptTmp->y;
+	    }
+	}
+
+	box.x2++;
+	box.y2++;
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    
+    (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillRect(DrawablePtr	pDrawable,
+		   GCPtr	pGC,
+		   int		nRects,
+		   xRectangle	*pRects)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if (nRects && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	    box;
+	xRectangle  *pRectsTmp = pRects;
+	int	    nRectsTmp = nRects;
+
+	box.x1 = pRectsTmp->x;
+	box.x2 = box.x1 + pRectsTmp->width;
+	box.y1 = pRectsTmp->y;
+	box.y2 = box.y1 + pRectsTmp->height;
+
+	while(--nRectsTmp) 
+	{
+	    pRectsTmp++;
+	    if(box.x1 > pRectsTmp->x) box.x1 = pRectsTmp->x;
+	    if(box.x2 < (pRectsTmp->x + pRectsTmp->width))
+		box.x2 = pRectsTmp->x + pRectsTmp->width;
+	    if(box.y1 > pRectsTmp->y) box.y1 = pRectsTmp->y;
+	    if(box.y2 < (pRectsTmp->y + pRectsTmp->height))
+		box.y2 = pRectsTmp->y + pRectsTmp->height;
+	}
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	    damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damagePolyFillArc(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		nArcs,
+		  xArc		*pArcs)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (nArcs && checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec	box;
+	int	nArcsTmp = nArcs;
+	xArc	*pArcsTmp = pArcs;
+
+	box.x1 = pArcsTmp->x;
+	box.x2 = box.x1 + pArcsTmp->width;
+	box.y1 = pArcsTmp->y;
+	box.y2 = box.y1 + pArcsTmp->height;
+
+	while(--nArcsTmp) 
+	{
+	    pArcsTmp++;
+	    if(box.x1 > pArcsTmp->x)
+		box.x1 = pArcsTmp->x;
+	    if(box.x2 < (pArcsTmp->x + pArcsTmp->width))
+		box.x2 = pArcsTmp->x + pArcsTmp->width;
+	    if(box.y1 > pArcsTmp->y)
+		box.y1 = pArcsTmp->y;
+	    if(box.y2 < (pArcsTmp->y + pArcsTmp->height))
+		box.y2 = pArcsTmp->y + pArcsTmp->height;
+        }
+
+	TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+/*
+ * general Poly/Image text function.  Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static void
+damageDamageChars (DrawablePtr	pDrawable,
+		   FontPtr	font,
+		   int		x,
+		   int		y,
+		   unsigned int	n,
+		   CharInfoPtr	*charinfo,
+		   Bool		imageblt,
+		   int		subWindowMode)
+{
+    ExtentInfoRec   extents;
+    BoxRec	    box;
+
+    QueryGlyphExtents(font, charinfo, n, &extents);
+    if (imageblt)
+    {
+	if (extents.overallWidth > extents.overallRight)
+	    extents.overallRight = extents.overallWidth;
+	if (extents.overallWidth < extents.overallLeft)
+	    extents.overallLeft = extents.overallWidth;
+	if (extents.overallLeft > 0)
+	    extents.overallLeft = 0;
+	if (extents.fontAscent > extents.overallAscent)
+	    extents.overallAscent = extents.fontAscent;
+	if (extents.fontDescent > extents.overallDescent)
+	    extents.overallDescent = extents.fontDescent;
+    }
+    box.x1 = x + extents.overallLeft;
+    box.y1 = y - extents.overallAscent;
+    box.x2 = x + extents.overallRight;
+    box.y2 = y + extents.overallDescent;
+    damageDamageBox (pDrawable, &box, subWindowMode);
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8   0
+#define TT_IMAGE8  1
+#define TT_POLY16  2
+#define TT_IMAGE16 3
+
+static int 
+damageText (DrawablePtr	    pDrawable,
+	    GCPtr	    pGC,
+	    int		    x,
+	    int		    y,
+	    unsigned long   count,
+	    char	    *chars,
+	    FontEncoding    fontEncoding,
+	    Bool	    textType)
+{
+    CharInfoPtr	    *charinfo;
+    CharInfoPtr	    *info;
+    unsigned long   i;
+    unsigned int    n;
+    int		    w;
+    Bool	    imageblt;
+
+    imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+    charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
+    if (!charinfo)
+	return x;
+
+    GetGlyphs(pGC->font, count, (unsigned char *)chars,
+	      fontEncoding, &i, charinfo);
+    n = (unsigned int)i;
+    w = 0;
+    if (!imageblt)
+	for (info = charinfo; i--; info++)
+	    w += (*info)->metrics.characterWidth;
+
+    if (n != 0) {
+	damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y, n,
+			   charinfo, imageblt, pGC->subWindowMode);
+	if (imageblt)
+	    (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+				       FONTGLYPHS(pGC->font));
+	else
+	    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, n, charinfo,
+				      FONTGLYPHS(pGC->font));
+    }
+    DEALLOCATE_LOCAL(charinfo);
+    return x + w;
+}
+
+static int
+damagePolyText8(DrawablePtr pDrawable,
+		GCPtr	    pGC,
+		int	    x,
+		int	    y,
+		int	    count,
+		char	    *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	x = damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_POLY8);
+    else
+	x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static int
+damagePolyText16(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 unsigned short	*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	x = damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_POLY16);
+    else
+	x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+    return x;
+}
+
+static void
+damageImageText8(DrawablePtr	pDrawable,
+		 GCPtr		pGC,
+		 int		x,
+		 int		y,
+		 int		count,
+		 char		*chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, chars,
+		    Linear8Bit, TT_IMAGE8);
+    else
+	(*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageImageText16(DrawablePtr	pDrawable,
+		  GCPtr		pGC,
+		  int		x,
+		  int		y,
+		  int		count,
+		  unsigned short *chars)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+
+    if (checkGCDamage (pDrawable, pGC))
+	damageText (pDrawable, pGC, x, y, (unsigned long) count, (char *) chars,
+		    FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit,
+		    TT_IMAGE16);
+    else
+	(*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+
+static void
+damageImageGlyphBlt(DrawablePtr	    pDrawable,
+		    GCPtr	    pGC,
+		    int		    x,
+		    int		    y,
+		    unsigned int    nglyph,
+		    CharInfoPtr	    *ppci,
+		    pointer	    pglyphBase)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+		       nglyph, ppci, TRUE, pGC->subWindowMode);
+    (*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+					ppci, pglyphBase);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePolyGlyphBlt(DrawablePtr	pDrawable,
+		   GCPtr	pGC,
+		   int		x,
+		   int		y,
+		   unsigned int	nglyph,
+		   CharInfoPtr	*ppci,
+		   pointer	pglyphBase)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    damageDamageChars (pDrawable, pGC->font, x + pDrawable->x, y + pDrawable->y,
+		       nglyph, ppci, FALSE, pGC->subWindowMode);
+    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+				ppci, pglyphBase);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damagePushPixels(GCPtr		pGC,
+		 PixmapPtr	pBitMap,
+		 DrawablePtr	pDrawable,
+		 int		dx,
+		 int		dy,
+		 int		xOrg,
+		 int		yOrg)
+{
+    DAMAGE_GC_OP_PROLOGUE(pGC, pDrawable);
+    if(checkGCDamage (pDrawable, pGC))
+    {
+	BoxRec box;
+
+        box.x1 = xOrg;
+        box.y1 = yOrg;
+
+        if(!pGC->miTranslate) {
+           box.x1 += pDrawable->x;          
+           box.y1 += pDrawable->y;          
+        }
+
+	box.x2 = box.x1 + dx;
+	box.y2 = box.y1 + dy;
+
+	TRIM_BOX(box, pGC);
+	if(BOX_NOT_EMPTY(box))
+	   damageDamageBox (pDrawable, &box, pGC->subWindowMode);
+    }
+    (*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+    DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
+}
+
+static void
+damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+    while (*pPrev)
+    {
+	if (*pPrev == pDamage)
+	{
+	    *pPrev = pDamage->pNext;
+	    return;
+	}
+	pPrev = &(*pPrev)->pNext;
+    }
+#if DAMAGE_VALIDATE_ENABLE
+    ErrorF ("Damage not on list\n");
+    abort ();
+#endif
+}
+
+static void
+damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
+{
+#if DAMAGE_VALIDATE_ENABLE
+    DamagePtr	pOld;
+
+    for (pOld = *pPrev; pOld; pOld = pOld->pNext)
+	if (pOld == pDamage) {
+	    ErrorF ("Damage already on list\n");
+	    abort ();
+	}
+#endif
+    pDamage->pNext = *pPrev;
+    *pPrev = pDamage;
+}
+
+static Bool
+damageDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	pScreen = pPixmap->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if (pPixmap->refcnt == 1)
+    {
+	DamagePtr	*pPrev = getPixmapDamageRef (pPixmap);
+	DamagePtr	pDamage;
+
+	while ((pDamage = *pPrev))
+	{
+	    damageRemoveDamage (pPrev, pDamage);
+	    if (!pDamage->isWindow)
+		DamageDestroy (pDamage);
+	}
+    }
+    unwrap (pScrPriv, pScreen, DestroyPixmap);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+    return TRUE;
+}
+
+static void
+damagePaintWindow(WindowPtr pWindow,
+		  RegionPtr prgn,
+		  int	    what)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    /*
+     * Painting background none doesn't actually *do* anything, so
+     * no damage is recorded
+     */
+    if ((what != PW_BACKGROUND || pWindow->backgroundState != None) &&
+	getWindowDamage (pWindow))
+	damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+    if(what == PW_BACKGROUND) {
+	unwrap (pScrPriv, pScreen, PaintWindowBackground);
+	(*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+	wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+    } else {
+	unwrap (pScrPriv, pScreen, PaintWindowBorder);
+	(*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+	wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+    }
+}
+
+
+static void
+damageCopyWindow(WindowPtr	pWindow,
+		 DDXPointRec	ptOldOrg,
+		 RegionPtr	prgnSrc)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if (getWindowDamage (pWindow))
+    {
+	int dx = pWindow->drawable.x - ptOldOrg.x;
+	int dy = pWindow->drawable.y - ptOldOrg.y;
+	
+	/*
+	 * The region comes in source relative, but the damage occurs
+	 * at the destination location.  Translate back and forth.
+	 */
+	REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
+	damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE, -1);
+	REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
+    }
+    unwrap (pScrPriv, pScreen, CopyWindow);
+    (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+    wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+}
+
+GCOps damageGCOps = {
+    damageFillSpans, damageSetSpans,
+    damagePutImage, damageCopyArea,
+    damageCopyPlane, damagePolyPoint,
+    damagePolylines, damagePolySegment,
+    damagePolyRectangle, damagePolyArc,
+    damageFillPolygon, damagePolyFillRect,
+    damagePolyFillArc, damagePolyText8,
+    damagePolyText16, damageImageText8,
+    damageImageText16, damageImageGlyphBlt,
+    damagePolyGlyphBlt, damagePushPixels,
+#ifdef NEED_LINEHELPER
+    NULL,
+#endif
+    {NULL}		/* devPrivate */
+};
+
+static void
+damageRestoreAreas (PixmapPtr	pPixmap,
+		    RegionPtr	prgn,
+		    int		xorg,
+		    int		yorg,
+		    WindowPtr	pWindow)
+{
+    ScreenPtr pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    damageDamageRegion (&pWindow->drawable, prgn, FALSE, -1);
+    unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+    (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
+						xorg, yorg, pWindow);
+    wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+			     damageRestoreAreas);
+}
+
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	PixmapPtr   pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+	DamagePtr   *pPrev = getPixmapDamageRef(pOldPixmap);
+	
+	while (pDamage)
+	{
+	    damageRemoveDamage (pPrev, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+    unwrap (pScrPriv, pScreen, SetWindowPixmap);
+    (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	DamagePtr   *pPrev = getPixmapDamageRef(pPixmap);
+	
+	while (pDamage)
+	{
+	    damageInsertDamage (pPrev, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    Bool	ret;
+    damageScrPriv(pScreen);
+
+    while ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	DamageUnregister (&pWindow->drawable, pDamage);
+	DamageDestroy (pDamage);
+    }
+    unwrap (pScrPriv, pScreen, DestroyWindow);
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    return ret;
+}
+
+static Bool
+damageCloseScreen (int i, ScreenPtr pScreen)
+{
+    damageScrPriv(pScreen);
+
+    unwrap (pScrPriv, pScreen, DestroyPixmap);
+    unwrap (pScrPriv, pScreen, CreateGC);
+    unwrap (pScrPriv, pScreen, PaintWindowBackground);
+    unwrap (pScrPriv, pScreen, PaintWindowBorder);
+    unwrap (pScrPriv, pScreen, CopyWindow);
+    unwrap (pScrPriv, pScreen, CloseScreen);
+    unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
+    xfree (pScrPriv);
+    return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+int damageScrPrivateIndex;
+int damagePixPrivateIndex;
+int damageGCPrivateIndex;
+int damageWinPrivateIndex;
+int damageGeneration;
+
+Bool
+DamageSetup (ScreenPtr pScreen)
+{
+    DamageScrPrivPtr	pScrPriv;
+#ifdef RENDER
+    PictureScreenPtr	ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+    if (damageGeneration != serverGeneration)
+    {
+	damageScrPrivateIndex = AllocateScreenPrivateIndex ();
+	if (damageScrPrivateIndex == -1)
+	    return FALSE;
+	damageGCPrivateIndex = AllocateGCPrivateIndex ();
+	if (damageGCPrivateIndex == -1)
+	    return FALSE;
+	damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
+	if (damagePixPrivateIndex == -1)
+	    return FALSE;
+	damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+	if (damageWinPrivateIndex == -1)
+	    return FALSE;
+	damageGeneration = serverGeneration;
+    }
+    if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
+	return TRUE;
+
+    if (!AllocateGCPrivate (pScreen, damageGCPrivateIndex, sizeof (DamageGCPrivRec)))
+	return FALSE;
+    if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
+	return FALSE;
+    if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+	return FALSE;
+
+    pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
+    if (!pScrPriv)
+	return FALSE;
+
+#ifdef COMPOSITE
+    /* This is a kludge to ensure wrapping order with the composite wrapper.
+     * If it's done from compinit.c, then DamageSetup may be called before the
+     * extension init phase, so that cw will be higher in the wrapping chain and
+     * rewrite drawables before damage gets to it, causing confusion.
+     */
+    if (!noCompositeExtension)
+	miInitializeCompositeWrapper (pScreen);
+#endif
+	
+    pScrPriv->internalLevel = 0;
+    pScrPriv->pScreenDamage = 0;
+
+    wrap (pScrPriv, pScreen, DestroyPixmap, damageDestroyPixmap);
+    wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
+    wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
+    wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+    wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
+    wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
+    wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
+			     damageRestoreAreas);
+#ifdef RENDER
+    if (ps) {
+	wrap (pScrPriv, ps, Glyphs, damageGlyphs);
+	wrap (pScrPriv, ps, Composite, damageComposite);
+    }
+#endif
+
+    pScreen->devPrivates[damageScrPrivateIndex].ptr = (pointer) pScrPriv;
+    return TRUE;
+}
+
+DamagePtr
+DamageCreate (DamageReportFunc  damageReport,
+	      DamageDestroyFunc	damageDestroy,
+	      DamageReportLevel	damageLevel,
+	      Bool		isInternal,
+	      ScreenPtr		pScreen,
+	      void		*closure)
+{
+    DamagePtr	pDamage;
+
+    pDamage = xalloc (sizeof (DamageRec));
+    if (!pDamage)
+	return 0;
+    pDamage->pNext = 0;
+    pDamage->pNextWin = 0;
+    REGION_NULL(pScreen, &pDamage->damage);
+    
+    pDamage->damageLevel = damageLevel;
+    pDamage->isInternal = isInternal;
+    pDamage->closure = closure;
+    pDamage->isWindow = FALSE;
+    pDamage->pDrawable = 0;
+
+    pDamage->damageReport = damageReport;
+    pDamage->damageDestroy = damageDestroy;
+    return pDamage;
+}
+
+void
+DamageRegister (DrawablePtr pDrawable,
+		DamagePtr   pDamage)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef(pWindow);
+
+#if DAMAGE_VALIDATE_ENABLE
+	DamagePtr   pOld;
+	
+	for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
+	    if (pOld == pDamage) {
+		ErrorF ("Damage already on window list\n");
+		abort ();
+	    }
+#endif
+	pDamage->pNextWin = *pPrev;
+	*pPrev = pDamage;
+	pDamage->isWindow = TRUE;
+    }
+    else
+	pDamage->isWindow = FALSE;
+    pDamage->pDrawable = pDrawable;
+    damageInsertDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDrawInternal (ScreenPtr pScreen, Bool enable)
+{
+    damageScrPriv (pScreen);
+
+    pScrPriv->internalLevel += enable ? 1 : -1;
+}
+
+void
+DamageUnregister (DrawablePtr	    pDrawable,
+		  DamagePtr	    pDamage)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef (pWindow);
+#if DAMAGE_VALIDATE_ENABLE
+	int	found = 0;
+#endif
+
+	while (*pPrev)
+	{
+	    if (*pPrev == pDamage)
+	    {
+		*pPrev = pDamage->pNextWin;
+#if DAMAGE_VALIDATE_ENABLE
+		found = 1;
+#endif
+		break;
+	    }
+	    pPrev = &(*pPrev)->pNextWin;
+	}
+#if DAMAGE_VALIDATE_ENABLE
+	if (!found) {
+	    ErrorF ("Damage not on window list\n");
+	    abort ();
+	}
+#endif
+    }
+    pDamage->pDrawable = 0;
+    damageRemoveDamage (getDrawableDamageRef (pDrawable), pDamage);
+}
+
+void
+DamageDestroy (DamagePtr    pDamage)
+{
+    if (pDamage->damageDestroy)
+	(*pDamage->damageDestroy) (pDamage, pDamage->closure);
+    REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
+    xfree (pDamage);
+}
+
+Bool
+DamageSubtract (DamagePtr	    pDamage,
+		const RegionPtr	    pRegion)
+{
+    RegionPtr	pClip;
+    RegionRec	pixmapClip;
+    DrawablePtr	pDrawable = pDamage->pDrawable;
+    
+    REGION_SUBTRACT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pRegion);
+    if (pDrawable)
+    {
+	if (pDrawable->type == DRAWABLE_WINDOW)
+	    pClip = &((WindowPtr) pDrawable)->borderClip;
+	else
+	{
+	    BoxRec  box;
+
+	    box.x1 = pDrawable->x;
+	    box.y1 = pDrawable->y;
+	    box.x2 = pDrawable->x + pDrawable->width;
+	    box.y2 = pDrawable->y + pDrawable->height;
+	    REGION_INIT (pDrawable->pScreen, &pixmapClip, &box, 1);
+	    pClip = &pixmapClip;
+	}
+	REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
+	REGION_INTERSECT (pDrawable->pScreen, &pDamage->damage, &pDamage->damage, pClip);
+	REGION_TRANSLATE (pDrawable->pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
+	if (pDrawable->type != DRAWABLE_WINDOW)
+	    REGION_UNINIT(pDrawable->pScreen, &pixmapClip);
+    }
+    return REGION_NOTEMPTY (pDrawable->pScreen, &pDamage->damage);
+}
+
+void
+DamageEmpty (DamagePtr	    pDamage)
+{
+    REGION_EMPTY (pDamage->pDrawable->pScreen, &pDamage->damage);
+}
+
+RegionPtr
+DamageRegion (DamagePtr		    pDamage)
+{
+    return &pDamage->damage;
+}
+
+void
+DamageDamageRegion (DrawablePtr	pDrawable,
+		    RegionPtr	pRegion)
+{
+    damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
new file mode 100644
index 000000000..845c6cfb9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -0,0 +1,4670 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dispatch.c,v 1.13 2005/09/13 01:33:19 daniels Exp $ */
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.32 2003/11/10 18:21:45 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#ifdef __sun
+#define False 0
+#define True 1
+#endif
+
+#define GC XlibGC
+#include <X11/Xlib.h>
+#undef GC
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#endif
+
+#include "Atoms.h"
+#include "Splash.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Reconnect.h"
+#include "Millis.h"
+#include "Font.h"
+#include "Shadow.h"
+#include "Handlers.h"
+#include "Keyboard.h"
+
+const int nxagentMaxFontNames = 10000;
+
+char dispatchExceptionAtReset = DE_RESET;
+
+/*
+ * This allows the agent to exit if no
+ * client is connected within a timeout.
+ */
+
+int nxagentClients = 0;
+
+void nxagentWaitDisplay(void);
+
+void nxagentListRemoteFonts(const char *, int);
+
+unsigned int nxagentWMtimeout = 0;
+Bool         nxagentWMPassed  = 0;
+
+/*
+ * Timeouts based on screen saver time.
+ */
+
+int nxagentAutoDisconnectTimeout = 0;
+
+#ifdef LBX
+#include "../../lbx/lbxserve.h"
+#endif
+
+#include "Xatom.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  WATCH
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef  BLOCKS
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+#ifdef VIEWPORT_FRAME
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+                                   (pWin) == nxagentViewportFrameRight || \
+                                       (pWin) == nxagentViewportFrameAbove || \
+                                           (pWin) == nxagentViewportFrameBelow)
+
+#else
+
+#define IsViewportFrame(pWin) (0)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int	nClients;	/* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue;   /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+    (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+    checkForInput[0] = c0;
+    checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+    TimeStamp systime;
+
+    /* To avoid time running backwards, we must call GetTimeInMillis before
+     * calling ProcessInputEvents.
+     */
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] != *checkForInput[1])
+	ProcessInputEvents();
+    if (CompareTimeStamps(systime, currentTime) == LATER)
+	currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+    TimeStamp systime;
+
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] == *checkForInput[1])
+	currentTime = systime;
+}
+
+void
+InitSelections()
+{
+    if (CurrentSelections)
+	xfree(CurrentSelections);
+    CurrentSelections = (Selection *)NULL;
+    NumCurrentSelections = 0;
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+      Selection *newsels;
+      newsels = (Selection *)xalloc(2 * sizeof(Selection));
+      if (!newsels)
+        return;
+      NumCurrentSelections += 2;
+      CurrentSelections = newsels;
+
+      CurrentSelections[0].selection = XA_PRIMARY;
+      CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[0].window = WindowTable[0]->drawable.id;
+      CurrentSelections[0].pWin = NULL;
+      CurrentSelections[0].client = NullClient;
+
+      CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
+      CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[1].window = WindowTable[0]->drawable.id;
+      CurrentSelections[1].pWin = NULL;
+      CurrentSelections[1].client = NullClient;
+    }
+#endif
+
+}
+
+void 
+FlushClientCaches(XID id)
+{
+    int i;
+    register ClientPtr client;
+
+    client = clients[CLIENT_ID(id)];
+    if (client == NullClient)
+        return ;
+    for (i=0; i<currentMaxClients; i++)
+    {
+	client = clients[i];
+        if (client != NullClient)
+	{
+            if (client->lastDrawableID == id)
+	    {
+		client->lastDrawableID = WindowTable[0]->drawable.id;
+		client->lastDrawable = (DrawablePtr)WindowTable[0];
+	    }
+            else if (client->lastGCID == id)
+	    {
+                client->lastGCID = INVALID;
+		client->lastGC = (GCPtr)NULL;
+	    }
+	}
+    }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
+#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
+
+Bool	    SmartScheduleDisable = FALSE;
+long	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long	    SmartScheduleTime;
+ClientPtr   SmartLastClient;
+int	    SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int         SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long	    SmartLastPrint;
+#endif
+
+void        Dispatch(void);
+void        InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+    ClientPtr	pClient;
+    int		i;
+    int		client;
+    int		bestPrio, best = 0;
+    int		bestRobin, robin;
+    long	now = SmartScheduleTime;
+    long	idle;
+
+    bestPrio = -0x7fffffff;
+    bestRobin = 0;
+    idle = 2 * SmartScheduleSlice;
+    for (i = 0; i < nready; i++)
+    {
+	client = clientReady[i];
+	pClient = clients[client];
+	/* Praise clients which are idle */
+	if ((now - pClient->smart_check_tick) >= idle)
+	{
+	    if (pClient->smart_priority < 0)
+		pClient->smart_priority++;
+	}
+	pClient->smart_check_tick = now;
+	
+	/* check priority to select best client */
+	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+	if (pClient->smart_priority > bestPrio ||
+	    (pClient->smart_priority == bestPrio && robin > bestRobin))
+	{
+	    bestPrio = pClient->smart_priority;
+	    bestRobin = robin;
+	    best = client;
+	}
+#ifdef SMART_DEBUG
+	if ((now - SmartLastPrint) >= 5000)
+	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+    }
+#ifdef SMART_DEBUG
+    if ((now - SmartLastPrint) >= 5000)
+    {
+	fprintf (stderr, " use %2d\n", best);
+	SmartLastPrint = now;
+    }
+#endif
+    pClient = clients[best];
+    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+    /*
+     * Set current client pointer
+     */
+    if (SmartLastClient != pClient)
+    {
+	pClient->smart_start_tick = now;
+	SmartLastClient = pClient;
+    }
+    /*
+     * Adjust slice
+     */
+    if (nready == 1)
+    {
+	/*
+	 * If it's been a long time since another client
+	 * has run, bump the slice up to get maximal
+	 * performance from a single client
+	 */
+	if ((now - pClient->smart_start_tick) > 1000 &&
+	    SmartScheduleSlice < SmartScheduleMaxSlice)
+	{
+	    SmartScheduleSlice += SmartScheduleInterval;
+	}
+    }
+    else
+    {
+	SmartScheduleSlice = SmartScheduleInterval;
+    }
+    return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+    register int        *clientReady;     /* array of request ready clients */
+    register int	result;
+    register ClientPtr	client;
+    register int	nready;
+    register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+    long			start_tick;
+#endif
+
+    unsigned long currentDispatch = 0;
+
+    nextFreeClientID = 1;
+    InitSelections();
+    nClients = 0;
+
+    /*
+     * The agent initialization was successfully
+     * completed. We can now handle our clients.
+     */
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+
+      nxagentSessionState = SESSION_UP;
+    }
+
+    #ifdef XKB
+
+    nxagentInitXkbWrapper();
+
+    nxagentTuneXkbWrapper();
+
+    #endif
+
+    #ifdef NXAGENT_ONSTART
+
+    /*
+     * Set NX_WM property (used by NX client to identify
+     * the agent's window) three seconds since the first
+     * client connects.
+     */
+
+    nxagentWMtimeout = GetTimeInMillis() + 3000;
+
+    #endif
+
+    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+    if (!clientReady)
+	return;
+
+  #ifdef WATCH
+
+  fprintf(stderr, "Dispatch: Watchpoint 12.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#3      1		352 bits (0 KB) ->	236 bits (0 KB) ->	352/1 -> 236/1	= 1.492:1
+#14     1		256 bits (0 KB) ->	101 bits (0 KB) ->	256/1 -> 101/1	= 2.535:1
+#16     1		256 bits (0 KB) ->	26 bits (0 KB) ->	256/1 -> 26/1	= 9.846:1
+#20     2	2	12256 bits (1 KB) ->	56 bits (0 KB) ->	6128/1 -> 28/1	= 218.857:1
+#43     1		256 bits (0 KB) ->	45 bits (0 KB) ->	256/1 -> 45/1	= 5.689:1
+#47     2	2	42304 bits (5 KB) ->	49 bits (0 KB) ->	21152/1 -> 24/1	= 863.347:1
+#98     1		256 bits (0 KB) ->	34 bits (0 KB) ->	256/1 -> 34/1	= 7.529:1
+*/
+
+  sleep(30);
+
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
+              dispatchException);
+
+  fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
+              dispatchExceptionAtReset);
+  #endif
+
+  if (!(dispatchException & DE_TERMINATE))
+    dispatchException = 0;
+
+    while (!dispatchException)
+    {
+        if (*icheck[0] != *icheck[1])
+	{
+	    ProcessInputEvents();
+	    FlushIfCriticalOutputPending();
+	}
+
+        /*
+         * Ensure we remove the splash after the timeout.
+         * Initializing clientReady[0] to -1 will tell
+         * WaitForSomething() to yield control after the
+         * timeout set in clientReady[1].
+         */
+
+        clientReady[0] = 0;
+
+        if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
+        {
+          #ifdef TEST
+          fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
+                      NXAGENT_WAKEUP);
+          #endif
+
+          clientReady[0] = -1;
+          clientReady[1] = NXAGENT_WAKEUP;
+        }
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[End dispatch]\n");
+        #endif
+
+	nready = WaitForSomething(clientReady);
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[Begin dispatch]\n");
+        #endif
+
+        #ifdef TEST
+        fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
+                    nready);
+        #endif
+        
+        #ifdef NXAGENT_ONSTART
+
+        currentDispatch = GetTimeInMillis();
+
+        /*
+         * If the timeout is expired set the
+         * selection informing the NX client
+         * that the agent is ready.
+         */
+
+         if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
+         {
+           nxagentRemoveSplashWindow(NULL);
+         }
+
+         nxagentClients = nClients;
+
+         #endif
+
+#ifdef SMART_SCHEDULE
+	if (nready && !SmartScheduleDisable)
+	{
+	    clientReady[0] = SmartScheduleClient (clientReady, nready);
+	    nready = 1;
+	}
+#endif
+       /***************** 
+	*  Handle events in round robin fashion, doing input between 
+	*  each round 
+	*****************/
+
+	while (!dispatchException && (--nready >= 0))
+	{
+	    client = clients[clientReady[nready]];
+	    if (! client)
+	    {
+		/* KillClient can cause this to happen */
+		continue;
+	    }
+	    /* GrabServer activation can cause this to be true */
+	    if (grabState == GrabKickout)
+	    {
+		grabState = GrabActive;
+		break;
+	    }
+	    isItTimeToYield = FALSE;
+ 
+            requestingClient = client;
+#ifdef SMART_SCHEDULE
+	    start_tick = SmartScheduleTime;
+#endif
+	    while (!isItTimeToYield)
+	    {
+	        if (*icheck[0] != *icheck[1])
+		{
+		    ProcessInputEvents();
+		    FlushIfCriticalOutputPending();
+		}
+#ifdef SMART_SCHEDULE
+		if (!SmartScheduleDisable && 
+		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+		{
+		    /* Penalize clients which consume ticks */
+		    if (client->smart_priority > SMART_MIN_PRIORITY)
+			client->smart_priority--;
+		    break;
+		}
+#endif
+		/* now, finally, deal with client requests */
+
+                #ifdef TEST
+                fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
+                            client->index);
+                #endif
+
+	        result = ReadRequestFromClient(client);
+	        if (result <= 0) 
+	        {
+		    if (result < 0)
+			CloseDownClient(client);
+		    break;
+	        }
+#ifdef NXAGENT_SERVER
+
+                #ifdef TEST
+
+                else
+                {
+
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
+                                      client->req_len << 2, client->index);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
+                                  nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
+                                      client->index);
+                    }
+                }
+
+                #endif
+#endif
+
+		client->sequence++;
+#ifdef DEBUG
+		if (client->requestLogIndex == MAX_REQUEST_LOG)
+		    client->requestLogIndex = 0;
+		client->requestLog[client->requestLogIndex] = MAJOROP;
+		client->requestLogIndex++;
+#endif
+		if (result > (maxBigRequestSize << 2))
+		    result = BadLength;
+		else
+#ifdef NXAGENT_SERVER
+                {
+                    result = (* client->requestVector[MAJOROP])(client);
+
+                    #ifdef TEST
+
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d] result [%d].\n", MAJOROP,
+                                      *((char *) client->requestBuffer + 1), client->req_len << 2,
+                                          client->index, result);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
+                                  "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
+                                      client->req_len << 2, client->index, result);
+                    }
+
+                    #endif
+
+                    /*
+                     * Can set isItTimeToYield to force
+                     * the dispatcher to pay attention
+                     * to another client.
+                     */
+
+                    nxagentDispatchHandler(client, client->req_len << 2, 0);
+                }
+#else
+		    result = (* client->requestVector[MAJOROP])(client);
+#endif
+
+		if (result != Success) 
+		{
+		    if (client->noClientException != Success)
+                        CloseDownClient(client);
+                    else
+		        SendErrorToClient(client, MAJOROP,
+					  MinorOpcodeOfRequest(client),
+					  client->errorValue, result);
+		    break;
+	        }
+#ifdef DAMAGEEXT
+		FlushIfCriticalOutputPending ();
+#endif
+	    }
+	    FlushAllOutput();
+#ifdef SMART_SCHEDULE
+	    client = clients[clientReady[nready]];
+	    if (client)
+		client->smart_stop_tick = SmartScheduleTime;
+#endif
+	    requestingClient = NULL;
+	}
+	dispatchException &= ~DE_PRIORITYCHANGE;
+    }
+#if defined(DDXBEFORERESET)
+    ddxBeforeReset ();
+#endif
+    if ((dispatchException & DE_RESET) && 
+            (serverGeneration > nxagentMaxAllowedResets))
+    {
+        dispatchException &= ~DE_RESET;
+        dispatchException |= DE_TERMINATE;
+
+        fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+    }
+
+    nxagentResetAtomMap();
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      /*
+       * The session is terminating. Force an I/O
+       * error on the display and wait until the
+       * NX transport is gone.
+       */
+  
+      fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
+
+      nxagentWaitDisplay();
+
+      fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
+    }
+
+    if (nxagentOption(Shadow) == 1)
+    {
+      NXShadowDestroy();
+    }
+
+    KillAllClients();
+    DEALLOCATE_LOCAL(clientReady);
+    dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+int
+ProcBadRequest(ClientPtr client)
+{
+    return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+    register WindowPtr pParent, pWin;
+    REQUEST(xCreateWindowReq);
+    int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+    
+    LEGAL_NEW_RESOURCE(stuff->wid, client);
+    if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+						    SecurityWriteAccess)))
+        return BadWindow;
+    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+    if (Ones(stuff->mask) != len)
+        return BadLength;
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+			      stuff->y, stuff->width, stuff->height, 
+			      stuff->borderWidth, stuff->class,
+			      stuff->mask, (XID *) &stuff[1], 
+			      (int)stuff->depth, 
+			      client, stuff->visual, &result);
+    if (pWin)
+    {
+	Mask mask = pWin->eventMask;
+
+	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+	    return BadAlloc;
+	pWin->eventMask = mask;
+    }
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeWindowAttributesReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+    if (len != Ones(stuff->valueMask))
+        return BadLength;
+    result =  ChangeWindowAttributes(pWin, 
+				  stuff->valueMask, 
+				  (XID *) &stuff[1], 
+				  client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+    xGetWindowAttributesReply wa;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    GetWindowAttributes(pWin, client, &wa);
+    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+    return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->parent)
+	FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    DestroySubwindows(pWin, client);
+    return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeSaveSetReq);
+    register int result;
+		  
+    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+        return BadMatch;
+    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+    {
+        result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->mode;
+	return( BadValue );
+    }
+}
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+    register WindowPtr pWin, pParent;
+    REQUEST(xReparentWindowReq);
+    register int result;
+
+    REQUEST_SIZE_MATCH(xReparentWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    if (!nxagentWMPassed)
+    {
+      nxagentRemoveSplashWindow(pWin);
+    }
+
+    pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+					      SecurityWriteAccess);
+    if (!pParent)
+        return(BadWindow);
+    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+    {
+        if ((pWin->backgroundState == ParentRelative) &&
+            (pParent->drawable.depth != pWin->drawable.depth))
+            return BadMatch;
+	if ((pWin->drawable.class != InputOnly) &&
+	    (pParent->drawable.class == InputOnly))
+	    return BadMatch;
+        result =  ReparentWindow(pWin, pParent, 
+			 (short)stuff->x, (short)stuff->y, client);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else 
+        return (BadMatch);
+}
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapWindow(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapSubwindows(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapWindow(pWin, FALSE);
+           /* update cache to say it is mapped */
+
+    return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapSubwindows(pWin);
+    return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xConfigureWindowReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+    if (Ones((Mask)stuff->mask) != len)
+        return BadLength;
+    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
+			      client);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xCirculateWindowReq);
+
+    REQUEST_SIZE_MATCH(xCirculateWindowReq);
+    if ((stuff->direction != RaiseLowest) &&
+	(stuff->direction != LowerHighest))
+    {
+	client->errorValue = stuff->direction;
+        return BadValue;
+    }
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    CirculateWindow(pWin, (int)stuff->direction, client);
+    return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+    register DrawablePtr pDraw;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+    rep->type = X_Reply;
+    rep->length = 0;
+    rep->sequenceNumber = client->sequence;
+    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+    rep->depth = pDraw->depth;
+    rep->width = pDraw->width;
+    rep->height = pDraw->height;
+
+    /* XXX - Because the pixmap-implementation of the multibuffer extension 
+     *       may have the buffer-id's drawable resource value be a pointer
+     *       to the buffer's window instead of the buffer itself
+     *       (this happens if the buffer is the displayed buffer),
+     *       we also have to check that the id matches before we can
+     *       truly say that it is a DRAWABLE_WINDOW.
+     */
+
+    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+    {
+        register WindowPtr pWin = (WindowPtr)pDraw;
+	rep->x = pWin->origin.x - wBorderWidth (pWin);
+	rep->y = pWin->origin.y - wBorderWidth (pWin);
+	rep->borderWidth = pWin->borderWidth;
+    }
+    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+    {
+	rep->x = rep->y = rep->borderWidth = 0;
+    }
+
+    return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+    xGetGeometryReply rep;
+    int status;
+
+    if ((status = GetGeometry(client, &rep)) != Success)
+	return status;
+
+    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+    return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+    xQueryTreeReply reply;
+    int numChildren = 0;
+    register WindowPtr pChild, pWin, pHead;
+    Window  *childIDs = (Window *)NULL;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    reply.type = X_Reply;
+    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+    reply.sequenceNumber = client->sequence;
+    if (pWin->parent)
+	reply.parent = pWin->parent->drawable.id;
+    else
+        reply.parent = (Window)None;
+    pHead = RealChildHead(pWin);
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+      if (!IsViewportFrame(pChild))
+      {
+	numChildren++;
+      }
+    }
+    if (numChildren)
+    {
+	int curChild = 0;
+
+	childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+	if (!childIDs)
+	    return BadAlloc;
+	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+        {
+          if (!IsViewportFrame(pChild))
+          {
+	    childIDs[curChild++] = pChild->drawable.id;
+          }
+        }
+    }
+    
+    reply.nChildren = numChildren;
+    reply.length = (numChildren * sizeof(Window)) >> 2;
+    
+    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+    if (numChildren)
+    {
+    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+	DEALLOCATE_LOCAL(childIDs);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+    Atom atom;
+    char *tchar;
+    REQUEST(xInternAtomReq);
+
+    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+    {
+	client->errorValue = stuff->onlyIfExists;
+        return(BadValue);
+    }
+    tchar = (char *) &stuff[1];
+    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+    if (atom != BAD_RESOURCE)
+    {
+	xInternAtomReply reply;
+	reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+	reply.atom = atom;
+	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+	return(client->noClientException);
+    }
+    else
+	return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+    char *str;
+    xGetAtomNameReply reply;
+    int len;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if ( (str = NameForAtom(stuff->id)) )
+    {
+	len = strlen(str);
+	reply.type = X_Reply;
+	reply.length = (len + 3) >> 2;
+	reply.sequenceNumber = client->sequence;
+	reply.nameLength = len;
+	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+	(void)WriteToClient(client, len, str);
+	return(client->noClientException);
+    }
+    else 
+    { 
+	client->errorValue = stuff->id;
+	return (BadAtom);
+    }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+    WindowPtr pWin;
+    TimeStamp time;
+    REQUEST(xSetSelectionOwnerReq);
+
+    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+    UpdateCurrentTime();
+    time = ClientTimeToServerTime(stuff->time);
+
+    /* If the client's time stamp is in the future relative to the server's
+	time stamp, do not set the selection, just return success. */
+    if (CompareTimeStamps(time, currentTime) == LATER)
+    	return Success;
+    if (stuff->window != None)
+    {
+        pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					       SecurityReadAccess);
+        if (!pWin)
+            return(BadWindow);
+    }
+    else
+        pWin = (WindowPtr)None;
+    if (ValidAtom(stuff->selection))
+    {
+	int i = 0;
+
+	/*
+	 * First, see if the selection is already set... 
+	 */
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) 
+            i++;
+        if (i < NumCurrentSelections)
+        {        
+	    xEvent event;
+
+	    /* If the timestamp in client's request is in the past relative
+		to the time stamp indicating the last time the owner of the
+		selection was set, do not set the selection, just return 
+		success. */
+            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+		== EARLIER)
+		return Success;
+	    if (CurrentSelections[i].client &&
+		(!pWin || (CurrentSelections[i].client != client)))
+	    {
+		event.u.u.type = SelectionClear;
+		event.u.selectionClear.time = time.milliseconds;
+		event.u.selectionClear.window = CurrentSelections[i].window;
+		event.u.selectionClear.atom = CurrentSelections[i].selection;
+		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+				NoEventMask, NoEventMask /* CantBeFiltered */,
+				NullGrab);
+	    }
+	}
+	else
+	{
+	    /*
+	     * It doesn't exist, so add it...
+	     */
+	    Selection *newsels;
+
+	    if (i == 0)
+		newsels = (Selection *)xalloc(sizeof(Selection));
+	    else
+		newsels = (Selection *)xrealloc(CurrentSelections,
+			    (NumCurrentSelections + 1) * sizeof(Selection));
+	    if (!newsels)
+		return BadAlloc;
+	    NumCurrentSelections++;
+	    CurrentSelections = newsels;
+	    CurrentSelections[i].selection = stuff->selection;
+	}
+        CurrentSelections[i].lastTimeChanged = time;
+	CurrentSelections[i].window = stuff->window;
+	CurrentSelections[i].pWin = pWin;
+	CurrentSelections[i].client = (pWin ? client : NullClient);
+	if (SelectionCallback)
+	{
+	    SelectionInfoRec	info;
+
+	    info.selection = &CurrentSelections[i];
+	    info.kind= SelectionSetOwner;
+	    CallCallbacks(&SelectionCallback, &info);
+	}
+
+#ifdef NXAGENT_CLIPBOARD
+      if ((CurrentSelections[i].pWin != NULL) &&
+              (nxagentOption(Clipboard) != ClipboardNone) &&
+                  ((CurrentSelections[i].selection == XA_PRIMARY) ||
+                       (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
+      {
+        nxagentSetSelectionOwner(&CurrentSelections[i]);
+      }
+#endif
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->selection;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (ValidAtom(stuff->id))
+    {
+	int i;
+        xGetSelectionOwnerReply reply;
+
+	i = 0;
+        while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->id) i++;
+        reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+        if (i < NumCurrentSelections)
+            reply.owner = CurrentSelections[i].window;
+        else
+            reply.owner = None;
+        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+        return(client->noClientException);
+    }
+    else            
+    {
+	client->errorValue = stuff->id;
+        return (BadAtom); 
+    }
+}
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+    Bool paramsOkay;
+    xEvent event;
+    WindowPtr pWin;
+    REQUEST(xConvertSelectionReq);
+
+    REQUEST_SIZE_MATCH(xConvertSelectionReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+#ifdef NXAGENT_CLIPBOARD
+    if (((stuff->selection == XA_PRIMARY) ||
+           (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
+               nxagentOption(Clipboard) != ClipboardNone)
+    {
+      int i = 0;
+
+      while ((i < NumCurrentSelections) &&
+                CurrentSelections[i].selection != stuff->selection) i++;
+
+      if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
+      {
+        if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
+                                       stuff->property, stuff->target, stuff->time))
+        {
+          return (client->noClientException);
+        }
+      }
+    }
+#endif
+
+    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+    if (stuff->property != None)
+	paramsOkay &= ValidAtom(stuff->property);
+    if (paramsOkay)
+    {
+	int i;
+
+	i = 0;
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) i++;
+	if ((i < NumCurrentSelections) && 
+	    (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+#ifdef XCSECURITY
+	    && (!client->CheckAccess ||
+		(* client->CheckAccess)(client, CurrentSelections[i].window,
+					RT_WINDOW, SecurityReadAccess,
+					CurrentSelections[i].pWin))
+#endif
+	    )
+	{        
+	    event.u.u.type = SelectionRequest;
+	    event.u.selectionRequest.time = stuff->time;
+	    event.u.selectionRequest.owner = 
+			CurrentSelections[i].window;
+	    event.u.selectionRequest.requestor = stuff->requestor;
+	    event.u.selectionRequest.selection = stuff->selection;
+	    event.u.selectionRequest.target = stuff->target;
+	    event.u.selectionRequest.property = stuff->property;
+	    if (TryClientEvents(
+		CurrentSelections[i].client, &event, 1, NoEventMask,
+		NoEventMask /* CantBeFiltered */, NullGrab))
+		return (client->noClientException);
+	}
+	event.u.u.type = SelectionNotify;
+	event.u.selectionNotify.time = stuff->time;
+	event.u.selectionNotify.requestor = stuff->requestor;
+	event.u.selectionNotify.selection = stuff->selection;
+	event.u.selectionNotify.target = stuff->target;
+	event.u.selectionNotify.property = None;
+	(void) TryClientEvents(client, &event, 1, NoEventMask,
+			       NoEventMask /* CantBeFiltered */, NullGrab);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->property;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+    REQUEST_SIZE_MATCH(xReq);
+    if (grabState != GrabNone && client != grabClient)
+    {
+	ResetCurrentRequest(client);
+	client->sequence--;
+	BITSET(grabWaiters, client->index);
+	IgnoreClient(client);
+	return(client->noClientException);
+    }
+    OnlyListenToOneClient(client);
+    grabState = GrabKickout;
+    grabClient = client;
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_GRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+
+    return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+    int i;
+
+    grabState = GrabNone;
+    ListenToAllClients();
+    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+	;
+    if (i >= 0)
+    {
+	i <<= 5;
+	while (!GETBIT(grabWaiters, i))
+	    i++;
+	BITCLEAR(grabWaiters, i);
+	AttendClient(clients[i]);
+    }
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_UNGRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+    REQUEST_SIZE_MATCH(xReq);
+    UngrabServer(client);
+    return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+    REQUEST(xTranslateCoordsReq);
+
+    register WindowPtr pWin, pDst;
+    xTranslateCoordsReply rep;
+
+    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+					   SecurityReadAccess);
+    if (!pDst)
+        return(BadWindow);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+    {
+	rep.sameScreen = xFalse;
+        rep.child = None;
+	rep.dstX = rep.dstY = 0;
+    }
+    else
+    {
+	INT16 x, y;
+	rep.sameScreen = xTrue;
+	rep.child = None;
+	/* computing absolute coordinates -- adjust to destination later */
+	x = pWin->drawable.x + stuff->srcX;
+	y = pWin->drawable.y + stuff->srcY;
+	pWin = pDst->firstChild;
+	while (pWin)
+	{
+#ifdef SHAPE
+	    BoxRec  box;
+#endif
+	    if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		 wBorderWidth (pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		 wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen, 
+					&pWin->borderSize, x, y, &box))
+		
+		&& (!wInputShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen,
+				    wInputShape(pWin),
+				    x - pWin->drawable.x,
+				    y - pWin->drawable.y, &box))
+#endif
+		)
+            {
+		rep.child = pWin->drawable.id;
+		pWin = (WindowPtr) NULL;
+	    }
+	    else
+		pWin = pWin->nextSib;
+	}
+	/* adjust to destination coordinates */
+	rep.dstX = x - pDst->drawable.x;
+	rep.dstY = y - pDst->drawable.y;
+    }
+    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+    return(client->noClientException);
+}
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+    int	err;
+    char fontReq[256];
+    REQUEST(xOpenFontReq);
+
+    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+    client->errorValue = stuff->fid;
+    LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+    memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    fontReq[stuff->nbytes]=0;
+    if (strchr(fontReq,'*') || strchr(fontReq,'?'))
+    {
+       extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
+#ifdef NXAGENT_FONTMATCH_DEBUG
+       fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
+#endif
+       nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
+       err = nxOpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    }
+    else
+    err = OpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+    FontPtr pFont;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityDestroyAccess);
+    if (pFont != (FontPtr)NULL)
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client closes a font the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this font looping through the
+         * resources.
+         */
+
+        if (pFont -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
+                        (void *) pFont);
+            #endif
+
+            nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
+                        "resource switching skipped.\n", (void *) pFont);
+          }
+          #endif
+        }
+
+        #endif
+
+        FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+        return (BadFont);
+    }
+}
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+    xQueryFontReply	*reply;
+    FontPtr pFont;
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    client->errorValue = stuff->id;		/* EITHER font or gc */
+
+    pFont = NULL;
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+	  /* can't use VERIFY_GC because it might return BadGC */
+	pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+					    SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->id;
+            return(BadFont);     /* procotol spec says only error is BadFont */
+	}
+	pFont = pGC->font;
+    }
+
+/* test
+{
+  Atom name_atom, value_atom;
+  int nprops;
+  FontPropPtr props;
+  int i;
+  char *name;
+
+  name_atom = MakeAtom("FONT", 4, True);
+  value_atom = 0L;
+
+  nprops = pFont->info.nprops;
+  props = pFont->info.props;
+
+  for (i = 0; i < nprops; i++)
+    if (props[i].name == name_atom) {
+      value_atom = props[i].value;
+      break;
+    }
+
+  if (!value_atom) return (BadFont);
+
+  name = (char *)NameForAtom(value_atom);
+  fprintf(stderr, "QueryFont: font name [%s]\n",name);
+}
+ end test */
+
+    {
+	xCharInfo	*pmax = FONTINKMAX(pFont);
+	xCharInfo	*pmin = FONTINKMIN(pFont);
+	int		nprotoxcistructs;
+	int		rlength;
+
+	nprotoxcistructs = (
+	   pmax->rightSideBearing == pmin->rightSideBearing &&
+	   pmax->leftSideBearing == pmin->leftSideBearing &&
+	   pmax->descent == pmin->descent &&
+	   pmax->ascent == pmin->ascent &&
+	   pmax->characterWidth == pmin->characterWidth) ?
+		0 : N2dChars(pFont);
+
+	rlength = sizeof(xQueryFontReply) +
+	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
+		     nprotoxcistructs * sizeof(xCharInfo);
+        reply = NULL;
+	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+	if(!reply)
+	{
+	    return(BadAlloc);
+	}
+
+	reply->type = X_Reply;
+	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+	reply->sequenceNumber = client->sequence;
+	QueryFont( pFont, reply, nprotoxcistructs);
+
+        WriteReplyToClient(client, rlength, reply);
+	DEALLOCATE_LOCAL(reply);
+	return(client->noClientException);
+    }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+    REQUEST(xQueryTextExtentsReq);
+    xQueryTextExtentsReply reply;
+    FontPtr pFont;
+    GC *pGC;
+    ExtentInfoRec info;
+    unsigned long length;
+
+    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+        
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+					   SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->fid;
+            return(BadFont);
+	}
+	pFont = pGC->font;
+    }
+    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+    length = length << 1;
+    if (stuff->oddLength)
+    {
+	if (length == 0)
+	    return(BadLength);
+        length--;
+    }
+    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+	return(BadAlloc);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.drawDirection = info.drawDirection;
+    reply.fontAscent = info.fontAscent;
+    reply.fontDescent = info.fontDescent;
+    reply.overallAscent = info.overallAscent;
+    reply.overallDescent = info.overallDescent;
+    reply.overallWidth = info.overallWidth;
+    reply.overallLeft = info.overallLeft;
+    reply.overallRight = info.overallRight;
+    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListFonts(register ClientPtr client)
+{
+    char tmp[256];
+
+    REQUEST(xListFontsReq);
+
+    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
+	stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+    char tmp[256];
+    REQUEST(xListFontsWithInfoReq);
+
+    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
+
+    return StartListFontsWithInfo(client, stuff->nbytes,
+				  (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+    PixmapPtr pPixmap = (PixmapPtr)value;
+    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    REQUEST(xCreatePixmapReq);
+    DepthPtr pDepth;
+    register int i;
+
+    REQUEST_SIZE_MATCH(xCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->width > 32767 || stuff->height > 32767)
+    {
+	/* It is allowed to try and allocate a pixmap which is larger than
+	 * 32767 in either dimension. However, all of the framebuffer code
+	 * is buggy and does not reliably draw to such big pixmaps, basically
+	 * because the Region data structure operates with signed shorts
+	 * for the rectangles in it.
+	 *
+	 * Furthermore, several places in the X server computes the
+	 * size in bytes of the pixmap and tries to store it in an
+	 * integer. This integer can overflow and cause the allocated size
+	 * to be much smaller.
+	 *
+	 * So, such big pixmaps are rejected here with a BadAlloc
+	 */
+	return BadAlloc;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+		(pDraw->pScreen, stuff->width,
+		 stuff->height, stuff->depth);
+    if (pMap)
+    {
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	    return(client->noClientException);
+    }
+    return (BadAlloc);
+}
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+    PixmapPtr pMap;
+
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+					     SecurityDestroyAccess);
+    if (pMap) 
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client releases a pixmap the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this pixmap looping through the
+         * resources.
+         */
+
+        if (pMap -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
+                       (void *) pMap);
+            #endif
+
+            nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
+                        "resource switching skipped.\n", (void *) pMap);
+          }
+          #endif
+        }
+
+        #endif
+
+	FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadPixmap);
+    }
+}
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+    int error;
+    GC *pGC;
+    register DrawablePtr pDraw;
+    unsigned len;
+    REQUEST(xCreateGCReq);
+
+    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+    client->errorValue = stuff->gc;
+    LEGAL_NEW_RESOURCE(stuff->gc, client);
+    SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+			      SecurityReadAccess);
+    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+    pGC = (GC *)CreateGC(pDraw, stuff->mask, 
+			 (XID *) &stuff[1], &error);
+    if (error != Success)
+        return error;
+    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+	return (BadAlloc);
+    return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+    GC *pGC;
+    REQUEST(xChangeGCReq);
+    int result;
+    unsigned len;
+		
+    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+    SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+
+    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+    register GC *dstGC;
+    register GC *pGC;
+    int result;
+    REQUEST(xCopyGCReq);
+
+    REQUEST_SIZE_MATCH(xCopyGCReq);
+    SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+    SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+        return (BadMatch);    
+    result = CopyGC(pGC, dstGC, stuff->mask);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+    register GC *pGC;
+    int result;
+    REQUEST(xSetDashesReq);
+
+    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+    if (stuff->nDashes == 0)
+    {
+	 client->errorValue = 0;
+         return BadValue;
+    }
+
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+		       (unsigned char *)&stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+    int	nr;
+    int result;
+    register GC *pGC;
+    REQUEST(xSetClipRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+    {
+	client->errorValue = stuff->ordering;
+        return BadValue;
+    }
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+		 
+    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+    if (nr & 4)
+	return(BadLength);
+    nr >>= 3;
+    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+    FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+    REQUEST(xClearAreaReq);
+    register WindowPtr pWin;
+
+    REQUEST_SIZE_MATCH(xClearAreaReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->drawable.class == InputOnly)
+    {
+	client->errorValue = stuff->window;
+	return (BadMatch);
+    }		    
+    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+    {
+	client->errorValue = stuff->exposures;
+        return(BadValue);
+    }
+    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+			       stuff->width, stuff->height,
+			       (Bool)stuff->exposures);
+    return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+    register DrawablePtr pDst;
+    register DrawablePtr pSrc;
+    register GC *pGC;
+    REQUEST(xCopyAreaReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        pSrc = pDst;
+
+    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY);
+    if (pGC->graphicsExposures)
+    {
+	(*pDst->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+	if (pRgn)
+	    REGION_DESTROY(pDst->pScreen, pRgn);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+    register DrawablePtr psrcDraw, pdstDraw;
+    register GC *pGC;
+    REQUEST(xCopyPlaneReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if (pdstDraw->pScreen != psrcDraw->pScreen)
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        psrcDraw = pdstDraw;
+
+    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+    {
+       client->errorValue = stuff->bitPlane;
+       return(BadValue);
+    }
+
+    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY, stuff->bitPlane);
+    if (pGC->graphicsExposures)
+    {
+	(*pdstDraw->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+	if (pRgn)
+	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyPointReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
+    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+    if (npoint)
+    {
+        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+			  (xPoint *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyLineReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+    if (npoint > 1)
+    {
+	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
+			      (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+    int nsegs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolySegmentReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+    if (nsegs & 4)
+	return(BadLength);
+    nsegs >>= 3;
+    if (nsegs)
+    {
+        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+    int nrects;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+    if (nrects & 4)
+	return(BadLength);
+    nrects >>= 3;
+    if (nrects)
+    {
+        (*pGC->ops->PolyRectangle)(pDraw, pGC, 
+		    nrects, (xRectangle *) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+    int          things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xFillPolyReq);
+
+    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
+	(stuff->shape != Convex))
+    {
+	client->errorValue = stuff->shape;
+        return BadValue;
+    }
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+    if (things)
+    {
+        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+			 stuff->coordMode, things,
+			 (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+    int             things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+
+    if (things)
+    {
+        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+		      (xRectangle *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+    int	    whichbyte = 1;
+
+    if (*((char *) &whichbyte))
+	return LSBFirst;
+    return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+    switch (bpp) {
+    case 1:	/* yuck */
+	if (BITMAP_BIT_ORDER != order)
+	    BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+	break;
+    case 4:
+	break;  /* yuck */
+    case 8:
+	break;
+    case 16:
+	if (IMAGE_BYTE_ORDER != order)
+	    TwoByteSwap ((unsigned char *) base, nbytes);
+	break;
+    case 32:
+	if (IMAGE_BYTE_ORDER != order)
+	    FourByteSwap ((unsigned char *) base, nbytes);
+	break;
+    }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+    register	GC *pGC;
+    register	DrawablePtr pDraw;
+    long	length; 	/* length of scanline server padded */
+    long 	lengthProto; 	/* length of scanline protocol padded */
+    char	*tmpImage;
+    REQUEST(xPutImageReq);
+
+    REQUEST_AT_LEAST_SIZE(xPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    if (stuff->format == XYBitmap)
+    {
+        if ((stuff->depth != 1) ||
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || 
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length      = BitmapBytePad(stuff->width + stuff->leftPad);
+	length      *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+            return BadMatch;
+        length      = PixmapBytePad(stuff->width, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    tmpImage = (char *)&stuff[1];
+    lengthProto = length;
+	
+    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 
+	(sizeof(xPutImageReq) >> 2)) != client->req_len)
+	return BadLength;
+
+    ReformatImage (tmpImage, lengthProto * stuff->height, 
+		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+		   ClientOrder(client));
+    
+    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+		  stuff->width, stuff->height, 
+		  stuff->leftPad, stuff->format, tmpImage);
+
+     return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable, 
+           int x, int y, int width, int height, 
+           Mask planemask, xGetImageReply **im_return)
+{
+    register DrawablePtr pDraw;
+    int			nlines, linesPerBuf;
+    register int	linesDone;
+    long		widthBytesLine, length;
+    Mask		plane = 0;
+    char		*pBuf;
+    xGetImageReply	xgi;
+#ifdef XCSECURITY
+    RegionPtr pVisibleRegion = NULL;
+#endif
+
+    if ((format != XYPixmap) && (format != ZPixmap))
+    {
+	client->errorValue = format;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+    if(pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + x < 0 ||
+ 	 pDraw->x + x + width > pDraw->pScreen->width ||
+         pDraw->y + y < 0 ||
+         pDraw->y + y + height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         x < - wBorderWidth((WindowPtr)pDraw) ||
+         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         y < -wBorderWidth((WindowPtr)pDraw) ||
+         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual (((WindowPtr) pDraw));
+    }
+    else
+    {
+      if(x < 0 ||
+         x+width > (int)pDraw->width ||
+         y < 0 ||
+         y+height > (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+
+    SET_DBE_SRCBUF(pDraw, drawable);
+
+    xgi.type = X_Reply;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(format == ZPixmap)
+    {
+	widthBytesLine = PixmapBytePad(width, pDraw->depth);
+	length = widthBytesLine * height;
+
+    }
+    else 
+    {
+	widthBytesLine = BitmapBytePad(width);
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = widthBytesLine * height *
+		 Ones(planemask & (plane | (plane - 1)));
+
+    }
+
+    xgi.length = length;
+
+    if (im_return) {
+	pBuf = (char *)xalloc(sz_xGetImageReply + length);
+	if (!pBuf)
+	    return (BadAlloc);
+	if (widthBytesLine == 0)
+	    linesPerBuf = 0;
+	else
+	    linesPerBuf = height;
+	*im_return = (xGetImageReply *)pBuf;
+	*(xGetImageReply *)pBuf = xgi;
+	pBuf += sz_xGetImageReply;
+    } else {
+	xgi.length = (xgi.length + 3) >> 2;
+	if (widthBytesLine == 0 || height == 0)
+	    linesPerBuf = 0;
+	else if (widthBytesLine >= IMAGE_BUFSIZE)
+	    linesPerBuf = 1;
+	else
+	{
+	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+	    if (linesPerBuf > height)
+		linesPerBuf = height;
+	}
+	length = linesPerBuf * widthBytesLine;
+	if (linesPerBuf < height)
+	{
+	    /* we have to make sure intermediate buffers don't need padding */
+	    while ((linesPerBuf > 1) &&
+		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+	    {
+		linesPerBuf--;
+		length -= widthBytesLine;
+	    }
+	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+	    {
+		linesPerBuf++;
+		length += widthBytesLine;
+	    }
+	}
+	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+	    return (BadAlloc);
+	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+    }
+
+#ifdef XCSECURITY
+    if (client->trustLevel != XSecurityClientTrusted &&
+	pDraw->type == DRAWABLE_WINDOW)
+    {
+	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+	if (pVisibleRegion)
+	{
+	    REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+	}
+    }
+#endif
+
+    if (linesPerBuf == 0)
+    {
+	/* nothing to do */
+    }
+    else if (format == ZPixmap)
+    {
+        linesDone = 0;
+        while (height - linesDone > 0)
+        {
+	    nlines = min(linesPerBuf, height - linesDone);
+	    (*pDraw->pScreen->GetImage) (pDraw,
+	                                 x,
+				         y + linesDone,
+				         width, 
+				         nlines,
+				         format,
+				         planemask,
+				         (pointer) pBuf);
+#ifdef XCSECURITY
+	    if (pVisibleRegion)
+		SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+			pDraw, x, y + linesDone, width, 
+			nlines, format, pBuf);
+#endif
+
+	    /* Note that this is NOT a call to WriteSwappedDataToClient,
+               as we do NOT byte swap */
+	    if (!im_return)
+	    {
+		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+			       BitsPerPixel (pDraw->depth),
+			       ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+		(void)WriteToClient(client,
+				    (int)(nlines * widthBytesLine),
+				    pBuf);
+	    }
+	    linesDone += nlines;
+        }
+    }
+    else /* XYPixmap */
+    {
+        for (; plane; plane >>= 1)
+	{
+	    if (planemask & plane)
+	    {
+	        linesDone = 0;
+	        while (height - linesDone > 0)
+	        {
+		    nlines = min(linesPerBuf, height - linesDone);
+	            (*pDraw->pScreen->GetImage) (pDraw,
+	                                         x,
+				                 y + linesDone,
+				                 width, 
+				                 nlines,
+				                 format,
+				                 plane,
+				                 (pointer)pBuf);
+#ifdef XCSECURITY
+		    if (pVisibleRegion)
+			SecurityCensorImage(client, pVisibleRegion,
+				widthBytesLine,
+				pDraw, x, y + linesDone, width, 
+				nlines, format, pBuf);
+#endif
+
+		    /* Note: NOT a call to WriteSwappedDataToClient,
+		       as we do NOT byte swap */
+		    if (im_return) {
+			pBuf += nlines * widthBytesLine;
+		    } else {
+			ReformatImage (pBuf, 
+				       (int)(nlines * widthBytesLine), 
+				       1,
+				       ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+			(void)WriteToClient(client,
+					(int)(nlines * widthBytesLine),
+					pBuf);
+		    }
+		    linesDone += nlines;
+		}
+            }
+	}
+    }
+#ifdef XCSECURITY
+    if (pVisibleRegion)
+	REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+#endif
+    if (!im_return)
+	DEALLOCATE_LOCAL(pBuf);
+    return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+    REQUEST(xGetImageReq);
+
+    REQUEST_SIZE_MATCH(xGetImageReq);
+
+    return DoGetImage(client, stuff->format, stuff->drawable,
+		      stuff->x, stuff->y,
+		      (int)stuff->width, (int)stuff->height,
+		      stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+    int	err;
+    REQUEST(xPolyTextReq);
+    DrawablePtr pDraw;
+    GC *pGC;
+
+    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = PolyText(client,
+		   pDraw,
+		   pGC,
+		   (unsigned char *)&stuff[1],
+		   ((unsigned char *) stuff) + (client->req_len << 2),
+		   stuff->x,
+		   stuff->y,
+		   stuff->reqType,
+		   stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+    VisualPtr	pVisual;
+    ColormapPtr	pmap;
+    Colormap	mid;
+    register WindowPtr   pWin;
+    ScreenPtr pScreen;
+    REQUEST(xCreateColormapReq);
+    int i, result;
+
+    REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+    {
+	client->errorValue = stuff->alloc;
+        return(BadValue);
+    }
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pScreen = pWin->drawable.pScreen;
+    for (i = 0, pVisual = pScreen->visuals;
+	 i < pScreen->numVisuals;
+	 i++, pVisual++)
+    {
+	if (pVisual->vid != stuff->visual)
+	    continue;
+	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
+				 (int)stuff->alloc, client->index);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+	    return(result);
+    }
+    client->errorValue = stuff->visual;
+    return(BadValue);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+    ColormapPtr pmap;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+						SecurityDestroyAccess);
+    if (pmap) 
+    {
+	/* Freeing a default colormap is a no-op */
+	if (!(pmap->flags & IsDefault))
+	    FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadColor);
+    }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+    Colormap	mid;
+    ColormapPtr	pSrcMap;
+    REQUEST(xCopyColormapAndFreeReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client,	stuff->srcCmap,
+		RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+    {
+	result = CopyColormapAndFree(mid, pSrcMap, client->index);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->srcCmap;
+	return(BadColor);
+    }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					    RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+        (*(pcmp->pScreen->InstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	if(pcmp->mid != pcmp->pScreen->defColormap)
+            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+    xListInstalledColormapsReply *preply; 
+    int nummaps;
+    WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+
+    if (!pWin)
+        return(BadWindow);
+
+    preply = (xListInstalledColormapsReply *) 
+		ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+		     pWin->drawable.pScreen->maxInstalledCmaps *
+		     sizeof(Colormap));
+    if(!preply)
+        return(BadAlloc);
+
+    preply->type = X_Reply;
+    preply->sequenceNumber = client->sequence;
+    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+    preply->nColormaps = nummaps;
+    preply->length = nummaps;
+    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+    DEALLOCATE_LOCAL(preply);
+    return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+    ColormapPtr pmap;
+    int	retval;
+    xAllocColorReply acr;
+    REQUEST(xAllocColorReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorReq);
+    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pmap)
+    {
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+	    return Success;
+#endif
+	acr.type = X_Reply;
+	acr.length = 0;
+	acr.sequenceNumber = client->sequence;
+	acr.red = stuff->red;
+	acr.green = stuff->green;
+	acr.blue = stuff->blue;
+	acr.pixel = 0;
+	if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+	                       &acr.pixel, client->index)) )
+	{
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return (retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+	return (client->noClientException);
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					    RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int		retval;
+
+	xAllocNamedColorReply ancr;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocNamedColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	ancr.type = X_Reply;
+	ancr.length = 0;
+	ancr.sequenceNumber = client->sequence;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+	{
+	    ancr.screenRed = ancr.exactRed;
+	    ancr.screenGreen = ancr.exactGreen;
+	    ancr.screenBlue = ancr.exactBlue;
+	    ancr.pixel = 0;
+	    if( (retval = AllocColor(pcmp,
+	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+			 &ancr.pixel, client->index)) )
+	    {
+                if (client->noClientException != Success)
+                    return(client->noClientException);
+                else
+    	            return(retval);
+	    }
+#ifdef PANORAMIX
+	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+	    return (client->noClientException);
+	}
+	else
+	    return(BadName);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorCellsReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorCellsReply	accr;
+	int			npixels, nmasks, retval;
+	long			length;
+	Pixel			*ppixels, *pmasks;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorCells request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	nmasks = stuff->planes;
+	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	pmasks = ppixels + npixels;
+
+	if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 
+				    (Bool)stuff->contiguous, ppixels, pmasks)) )
+	{
+	    DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    accr.type = X_Reply;
+	    accr.length = length >> 2;
+	    accr.sequenceNumber = client->sequence;
+	    accr.nPixels = npixels;
+	    accr.nMasks = nmasks;
+	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorPlanesReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorPlanesReply	acpr;
+	int			npixels, retval;
+	long			length;
+	Pixel			*ppixels;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorPlanes request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	acpr.type = X_Reply;
+	acpr.sequenceNumber = client->sequence;
+	acpr.nPixels = npixels;
+	length = (long)npixels * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+	    (Bool)stuff->contiguous, ppixels,
+	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+	{
+            DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+	acpr.length = length >> 2;
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xFreeColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+	if(pcmp->flags & AllAllocated)
+	    return(BadAccess);
+	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+	retval =  FreeColors(pcmp, client->index, count,
+	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+	if (count % sizeof(xColorItem))
+	    return(BadLength);
+	count /= sizeof(xColorItem);
+	retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xColorItem	def;
+        int             retval;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+	                 stuff->nbytes, &def.red, &def.green, &def.blue))
+	{
+	    def.flags = stuff->flags;
+	    def.pixel = stuff->pixel;
+	    retval = StoreColors(pcmp, 1, &def);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+		return(retval);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xQueryColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	int			count, retval;
+	xrgb 			*prgbs;
+	xQueryColorsReply	qcr;
+
+	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+	prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+	if(!prgbs && count)
+            return(BadAlloc);
+	if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+	{
+   	    if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	    if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	    {
+		client->errorValue = clientErrorValue;
+	        return (retval);
+	    }
+	}
+	qcr.type = X_Reply;
+	qcr.length = (count * sizeof(xrgb)) >> 2;
+	qcr.sequenceNumber = client->sequence;
+	qcr.nColors = count;
+	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+	if (count)
+	{
+	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+	}
+	if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	return(client->noClientException);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+} 
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xLookupColorReq);
+
+    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	xLookupColorReply lcr;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+	{
+	    lcr.type = X_Reply;
+	    lcr.length = 0;
+	    lcr.sequenceNumber = client->sequence;
+	    lcr.screenRed = lcr.exactRed;
+	    lcr.screenGreen = lcr.exactGreen;
+	    lcr.screenBlue = lcr.exactBlue;
+	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+	                                   &lcr.screenGreen,
+					   &lcr.screenBlue,
+					   pcmp->pVisual);
+	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+	    return(client->noClientException);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+    CursorPtr	pCursor;
+
+    register PixmapPtr 	src;
+    register PixmapPtr 	msk;
+    unsigned char *	srcbits;
+    unsigned char *	mskbits;
+    unsigned short	width, height;
+    long		n;
+    CursorMetricRec cm;
+
+
+    REQUEST(xCreateCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+					      RT_PIXMAP, SecurityReadAccess);
+    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+					      RT_PIXMAP, SecurityReadAccess);
+    if (   src == (PixmapPtr)NULL)
+    {
+	client->errorValue = stuff->source;
+	return (BadPixmap);
+    }
+    if ( msk == (PixmapPtr)NULL)
+    {
+	if (stuff->mask != None)
+	{
+	    client->errorValue = stuff->mask;
+	    return (BadPixmap);
+	}
+    }
+    else if (  src->drawable.width != msk->drawable.width
+	    || src->drawable.height != msk->drawable.height
+	    || src->drawable.depth != 1
+	    || msk->drawable.depth != 1)
+	return (BadMatch);
+
+    width = src->drawable.width;
+    height = src->drawable.height;
+
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+
+    n = BitmapBytePad(width)*height;
+    srcbits = (unsigned char *)xalloc(n);
+    if (!srcbits)
+	return (BadAlloc);
+    mskbits = (unsigned char *)xalloc(n);
+    if (!mskbits)
+    {
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+
+    /* zeroing the (pad) bits helps some ddx cursor handling */
+    bzero((char *)srcbits, n);
+    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+					 XYPixmap, 1, (pointer)srcbits);
+    if ( msk == (PixmapPtr)NULL)
+    {
+	register unsigned char *bits = mskbits;
+	while (--n >= 0)
+	    *bits++ = ~0;
+    }
+    else
+    {
+	/* zeroing the (pad) bits helps some ddx cursor handling */
+	bzero((char *)mskbits, n);
+	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+					height, XYPixmap, 1, (pointer)mskbits);
+    }
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursor( srcbits, mskbits, &cm,
+	    stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+	    stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+    {
+        #ifdef TEST
+        fprintf(stderr, "ProcCreateCursor: Created cursor at [%p].\n", (void *) pCursor);
+        #endif
+
+	    return (client->noClientException);
+    }
+
+    return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+    CursorPtr pCursor;
+    int res;
+
+    REQUEST(xCreateGlyphCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+			   stuff->mask, stuff->maskChar,
+			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+			   stuff->backRed, stuff->backGreen, stuff->backBlue,
+			   &pCursor, client);
+    if (res != Success)
+	return res;
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+    CursorPtr pCursor;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_CURSOR, SecurityDestroyAccess);
+    if (pCursor) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadCursor);
+    }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+    xQueryBestSizeReply	reply;
+    register DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    REQUEST(xQueryBestSizeReq);
+
+    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+    if ((stuff->class != CursorShape) && 
+	(stuff->class != TileShape) && 
+	(stuff->class != StippleShape))
+    {
+	client->errorValue = stuff->class;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+	return (BadMatch);
+    pScreen = pDraw->pScreen;
+    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+			       &stuff->height, pScreen);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.width = stuff->width;
+    reply.height = stuff->height;
+    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+    return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+    int blankingOption, exposureOption;
+    REQUEST(xSetScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+    blankingOption = stuff->preferBlank;
+    if ((blankingOption != DontPreferBlanking) &&
+        (blankingOption != PreferBlanking) &&
+        (blankingOption != DefaultBlanking))
+    {
+	client->errorValue = blankingOption;
+        return BadValue;
+    }
+    exposureOption = stuff->allowExpose;
+    if ((exposureOption != DontAllowExposures) &&
+        (exposureOption != AllowExposures) &&
+        (exposureOption != DefaultExposures))
+    {
+	client->errorValue = exposureOption;
+        return BadValue;
+    }
+    if (stuff->timeout < -1)
+    {
+	client->errorValue = stuff->timeout;
+        return BadValue;
+    }
+    if (stuff->interval < -1)
+    {
+	client->errorValue = stuff->interval;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to change our values.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
+                stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
+    #endif
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      if (blankingOption == DefaultBlanking)
+      {
+	ScreenSaverBlanking = defaultScreenSaverBlanking;
+      }
+      else
+      {
+	ScreenSaverBlanking = blankingOption; 
+      }
+
+      if (exposureOption == DefaultExposures)
+      {
+	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+      }
+      else
+      {
+        ScreenSaverAllowExposures = exposureOption;
+      }
+
+      if (stuff->timeout >= 0)
+      {
+        ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverTime = defaultScreenSaverTime;
+      }
+
+      if (stuff->interval >= 0)
+      {
+        ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverInterval = defaultScreenSaverInterval;
+      }
+    }
+    #ifdef TEST
+
+    else
+    {
+      fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
+                  nxagentOption(Timeout));
+    }
+
+    #endif
+
+    SetScreenSaverTimer();
+    return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+    xGetScreenSaverReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+    rep.preferBlanking = ScreenSaverBlanking;
+    rep.allowExposures = ScreenSaverAllowExposures;
+    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+    return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+    REQUEST(xChangeHostsReq);
+    int result;
+
+    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+    if(stuff->mode == HostInsert)
+	result = AddHost(client, (int)stuff->hostFamily,
+			 stuff->hostLength, (pointer)&stuff[1]);
+    else if (stuff->mode == HostDelete)
+	result = RemoveHost(client, (int)stuff->hostFamily, 
+			    stuff->hostLength, (pointer)&stuff[1]);  
+    else
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+    xListHostsReply reply;
+    int	len, nHosts, result;
+    pointer	pdata;
+    /* REQUEST(xListHostsReq); */
+
+    REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+    /* untrusted clients can't list hosts */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	SecurityAudit("client %d attempted to list hosts\n", client->index);
+	return BadAccess;
+    }
+#endif
+    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+    if (result != Success)
+	return(result);
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.nHosts = nHosts;
+    reply.length = len >> 2;
+    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+    if (nHosts)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+	WriteSwappedDataToClient(client, len, pdata);
+    }
+    xfree(pdata);
+    return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+    int result;
+    REQUEST(xSetAccessControlReq);
+
+    REQUEST_SIZE_MATCH(xSetAccessControlReq);
+    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+    REQUEST(xResourceReq);
+    ClientPtr	killclient;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (stuff->id == AllTemporary)
+    {
+	CloseDownRetainedResources();
+        return (client->noClientException);
+    }
+
+    if ((killclient = LookupClient(stuff->id, client)))
+    {
+	CloseDownClient(killclient);
+	/* if an LBX proxy gets killed, isItTimeToYield will be set */
+	if (isItTimeToYield || (client == killclient))
+	{
+	    /* force yield and return Success, so that Dispatch()
+	     * doesn't try to touch client
+	     */
+	    isItTimeToYield = TRUE;
+	    return (Success);
+	}
+	return (client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+	return (BadValue);
+    }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+    unsigned char *ptr;
+    unsigned long nbytes, total;
+    long nfonts;
+    int n, result;
+    int error;
+    REQUEST(xSetFontPathReq);
+    
+    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+    
+    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+    total = nbytes;
+    ptr = (unsigned char *)&stuff[1];
+    nfonts = stuff->nFonts;
+    while (--nfonts >= 0)
+    {
+	if ((total == 0) || (total < (n = (*ptr + 1))))
+	    return(BadLength);
+	total -= n;
+	ptr += n;
+    }
+    if (total >= 4)
+	return(BadLength);
+    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+			 &error);
+    if (!result)
+    {
+	result = client->noClientException;
+	client->errorValue = error;
+    }
+    return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+    xGetFontPathReply reply;
+    int stringLens, numpaths;
+    unsigned char *bufferStart;
+    /* REQUEST (xReq); */
+
+    REQUEST_SIZE_MATCH(xReq);
+    bufferStart = GetFontPath(&numpaths, &stringLens);
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = (stringLens + numpaths + 3) >> 2;
+    reply.nPaths = numpaths;
+
+    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+    if (stringLens || numpaths)
+	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+    return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+    REQUEST(xSetCloseDownModeReq);
+
+    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+    if ((stuff->mode == AllTemporary) ||
+	(stuff->mode == RetainPermanent) ||
+	(stuff->mode == RetainTemporary))
+    {
+	client->closeDownMode = stuff->mode;
+	return (client->noClientException);
+    }
+    else   
+    {
+	client->errorValue = stuff->mode;
+	return (BadValue);
+    }
+}
+
+int ProcForceScreenSaver(register ClientPtr client)
+{    
+    REQUEST(xForceScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+    
+    if ((stuff->mode != ScreenSaverReset) && 
+	(stuff->mode != ScreenSaverActive))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to force the screen
+     * saver handler execution.
+     */
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+    }
+
+    #ifdef TEST
+
+    else
+    {
+      fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
+                  stuff -> mode);
+    }
+
+    #endif
+
+    return client->noClientException;
+}
+
+int ProcNoOperation(register ClientPtr client)
+{
+    REQUEST_AT_LEAST_SIZE(xReq);
+    
+    /* noop -- don't do anything */
+    return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+    int i;
+    for (i = 0; i<256; i++)
+    {
+	if(!ProcVector[i])
+	{
+            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+	    ReplySwapVector[i] = ReplyNotSwappd;
+	}
+#ifdef K5AUTH
+	if (!k5_Vector[i])
+	{
+	    k5_Vector[i] = k5_bad;
+	}
+#endif
+    }
+    for(i = LASTEvent; i < 128; i++)
+    {
+	EventSwapVector[i] = NotImplemented;
+    }
+    
+}
+
+/**********************
+ * CloseDownClient
+ *
+ *  Client can either mark his resources destroy or retain.  If retained and
+ *  then killed again, the client is really destroyed.
+ *********************/
+
+void
+CloseDownClient(register ClientPtr client)
+{
+    Bool really_close_down = client->clientGone ||
+			     client->closeDownMode == DestroyAll;
+
+    /*
+     * There must be a better way to hook a
+     * call-back function to be called any
+     * time a client is going to be closed.
+     */
+
+    nxagentClearClipboard(client, NULL);
+
+    /*
+     * Need to reset the karma counter and
+     * get rid of the pending sync replies.
+     */
+
+    nxagentWakeupByReset(client);
+
+    /*
+     * Check if the client
+     * is a shadow nxagent.
+     */
+
+    nxagentCheckIfShadowAgent(client);
+
+    if (!client->clientGone)
+    {
+	/* ungrab server if grabbing client dies */
+	if (grabState != GrabNone && grabClient == client)
+	{
+	    UngrabServer(client);
+	}
+	BITCLEAR(grabWaiters, client->index);
+	DeleteClientFromAnySelections(client);
+	ReleaseActiveGrabs(client);
+	DeleteClientFontStuff(client);
+	if (!really_close_down)
+	{
+	    /*  This frees resources that should never be retained
+	     *  no matter what the close down mode is.  Actually we
+	     *  could do this unconditionally, but it's probably
+	     *  better not to traverse all the client's resources
+	     *  twice (once here, once a few lines down in
+	     *  FreeClientResources) in the common case of
+	     *  really_close_down == TRUE.
+	     */
+	    FreeClientNeverRetainResources(client);
+	    client->clientState = ClientStateRetained;
+  	    if (ClientStateCallback)
+            {
+		NewClientInfoRec clientinfo;
+
+		clientinfo.client = client; 
+		clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+		clientinfo.setup = (xConnSetup *) NULL;
+		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+            } 
+	}
+	client->clientGone = TRUE;  /* so events aren't sent to client */
+	if (ClientIsAsleep(client))
+	    ClientSignal (client);
+	ProcessWorkQueueZombies();
+#ifdef LBX
+	ProcessQTagZombies();
+#endif
+	CloseDownConnection(client);
+
+	/* If the client made it to the Running stage, nClients has
+	 * been incremented on its behalf, so we need to decrement it
+	 * now.  If it hasn't gotten to Running, nClients has *not*
+	 * been incremented, so *don't* decrement it.
+	 */
+	if (client->clientState != ClientStateInitial &&
+	    client->clientState != ClientStateAuthenticating )
+	{
+	    --nClients;
+	}
+    }
+
+    if (really_close_down)
+    {
+	if (client->clientState == ClientStateRunning && nClients == 0)
+	    dispatchException |= dispatchExceptionAtReset;
+
+	client->clientState = ClientStateGone;
+	if (ClientStateCallback)
+	{
+	    NewClientInfoRec clientinfo;
+
+	    clientinfo.client = client; 
+	    clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+	    clientinfo.setup = (xConnSetup *) NULL;
+	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+	} 	    
+	FreeClientResources(client);
+	if (client->index < nextFreeClientID)
+	    nextFreeClientID = client->index;
+	clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+	SmartLastClient = NullClient;
+#endif
+	xfree(client);
+
+	while (!clients[currentMaxClients-1])
+	    currentMaxClients--;
+    }
+}
+
+static void
+KillAllClients()
+{
+    int i;
+    for (i=1; i<currentMaxClients; i++)
+        if (clients[i]) {
+            /* Make sure Retained clients are released. */
+            clients[i]->closeDownMode = DestroyAll;
+            CloseDownClient(clients[i]);     
+        }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ *    Find all clients that are gone and have terminated in RetainTemporary 
+ *    and  destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+    register int i;
+    register ClientPtr client;
+
+    for (i=1; i<currentMaxClients; i++)
+    {
+        client = clients[i];
+        if (client && (client->closeDownMode == RetainTemporary)
+	    && (client->clientGone))
+	    CloseDownClient(client);
+    }
+}
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+    client->index = i;
+    client->sequence = 0; 
+    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+    client->clientGone = FALSE;
+    if (i)
+    {
+	client->closeDownMode = DestroyAll;
+	client->lastDrawable = (DrawablePtr)WindowTable[0];
+	client->lastDrawableID = WindowTable[0]->drawable.id;
+    }
+    else
+    {
+	client->closeDownMode = RetainPermanent;
+	client->lastDrawable = (DrawablePtr)NULL;
+	client->lastDrawableID = INVALID;
+    }
+    client->lastGC = (GCPtr) NULL;
+    client->lastGCID = INVALID;
+    client->numSaved = 0;
+    client->saveSet = (SaveSetElt *)NULL;
+    client->noClientException = Success;
+#ifdef LOG_DEBUG
+    client->requestLogIndex = 0;
+#endif
+    client->requestVector = InitialVector;
+    client->osPrivate = ospriv;
+    client->swapped = FALSE;
+    client->big_requests = FALSE;
+    client->priority = 0;
+    client->clientState = ClientStateInitial;
+#ifdef XKB
+    if (!noXkbExtension) {
+	client->xkbClientFlags = 0;
+	client->mapNotifyMask = 0;
+	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+    }
+#endif
+    client->replyBytesRemaining = 0;
+#ifdef LBX
+    client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+    client->trustLevel = XSecurityClientTrusted;
+    client->CheckAccess = NULL;
+    client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+    client->appgroup = NULL;
+#endif
+    client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+    client->smart_priority = 0;
+    client->smart_start_tick = SmartScheduleTime;
+    client->smart_stop_tick = SmartScheduleTime;
+    client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(ClientPtr client)
+{
+    register char *ptr;
+    DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    if (totalClientSize == sizeof(ClientRec))
+	ppriv = (DevUnion *)NULL;
+    else if (client->index)
+	ppriv = (DevUnion *)(client + 1);
+    else
+    {
+	ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+	if (!ppriv)
+	    return 0;
+    }
+    client->devPrivates = ppriv;
+    sizes = clientPrivateSizes;
+    ptr = (char *)(ppriv + clientPrivateLen);
+    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+
+    /*
+     * Initialize the private members.
+     */
+
+    nxagentInitClientPrivates(client);
+
+    return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+    register int i;
+    register ClientPtr client;
+    xReq data;
+
+    i = nextFreeClientID;
+    if (i == MAXCLIENTS)
+	return (ClientPtr)NULL;
+    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+    if (!client)
+	return (ClientPtr)NULL;
+    InitClient(client, i, ospriv);
+    InitClientPrivates(client);
+    if (!InitClientResources(client))
+    {
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    data.reqType = 1;
+    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+    {
+	FreeClientResources(client);
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    if (i == currentMaxClients)
+	currentMaxClients++;
+    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+	nextFreeClientID++;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+        clientinfo.setup = (xConnSetup *) NULL;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+    REQUEST(xReq);
+    register xConnClientPrefix *prefix;
+    int whichbyte = 1;
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+	return (client->noClientException = -1);
+    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+    {
+	client->swapped = TRUE;
+	SwapConnClientPrefix(prefix);
+    }
+    stuff->reqType = 2;
+    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+    if (client->swapped)
+    {
+	swaps(&stuff->length, whichbyte);
+    }
+    ResetCurrentRequest(client);
+    return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+    nClients++;
+}
+#endif
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+    register xWindowRoot *root;
+    register int i;
+    int numScreens;
+    char* lConnectionInfo;
+    xConnSetupPrefix* lconnSetupPrefix;
+
+    if (reason)
+    {
+	xConnSetupPrefix csp;
+
+	csp.success = xFalse;
+	csp.lengthReason = strlen(reason);
+	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+	csp.majorVersion = X_PROTOCOL;
+	csp.minorVersion = X_PROTOCOL_REVISION;
+	if (client->swapped)
+	    WriteSConnSetupPrefix(client, &csp);
+	else
+	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+        (void)WriteToClient(client, (int)csp.lengthReason, reason);
+	return (client->noClientException = -1);
+    }
+
+    numScreens = screenInfo.numScreens;
+    lConnectionInfo = ConnectionInfo;
+    lconnSetupPrefix = &connSetupPrefix;
+
+    /* We're about to start speaking X protocol back to the client by
+     * sending the connection setup info.  This means the authorization
+     * step is complete, and we can count the client as an
+     * authorized one.
+     */
+    nClients++;
+
+    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+    client->sequence = 0;
+#ifdef XAPPGROUP
+    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+    /* fill in the "currentInputMask" */
+    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+    for (i=0; i<numScreens; i++) 
+    {
+	register unsigned int j;
+	register xDepth *pDepth;
+
+        root->currentInputMask = WindowTable[i]->eventMask |
+			         wOtherEventMasks (WindowTable[i]);
+	pDepth = (xDepth *)(root + 1);
+	for (j = 0; j < root->nDepths; j++)
+	{
+	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+				pDepth->nVisuals * sizeof(xVisualType));
+	}
+	root = (xWindowRoot *)pDepth;
+    }
+
+    if (client->swapped)
+    {
+	WriteSConnSetupPrefix(client, lconnSetupPrefix);
+	WriteSConnectionInfo(client,
+			     (unsigned long)(lconnSetupPrefix->length << 2),
+			     lConnectionInfo);
+    }
+    else
+    {
+	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
+			    (char *) lconnSetupPrefix);
+	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+			    lConnectionInfo);
+    }
+    client->clientState = ClientStateRunning;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = lconnSetupPrefix;  
+        clientinfo.setup = (xConnSetup *)lConnectionInfo;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+    char *reason, *auth_proto, *auth_string;
+    register xConnClientPrefix *prefix;
+    REQUEST(xReq);
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    auth_proto = (char *)prefix + sz_xConnClientPrefix;
+    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+    if ((prefix->majorVersion != X_PROTOCOL) ||
+	(prefix->minorVersion != X_PROTOCOL_REVISION))
+	reason = "Protocol version mismatch";
+    else
+	reason = ClientAuthorized(client,
+				  (unsigned short)prefix->nbytesAuthProto,
+				  auth_proto,
+				  (unsigned short)prefix->nbytesAuthString,
+				  auth_string);
+    /*
+     * If Kerberos is being used for this client, the clientState
+     * will be set to ClientStateAuthenticating at this point.
+     * More messages need to be exchanged among the X server, Kerberos
+     * server, and client to figure out if everyone is authorized.
+     * So we don't want to send the connection setup info yet, since
+     * the auth step isn't really done.
+     */
+    if (client->clientState == ClientStateCheckingSecurity)
+	client->clientState = ClientStateCheckedSecurity;
+    else if (client->clientState != ClientStateAuthenticating)
+	return(SendConnSetup(client, reason));
+    return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 
+                  XID resId, int errorCode)
+{
+    xError rep;
+
+    rep.type = X_Error;
+    rep.sequenceNumber = client->sequence;
+    rep.errorCode = errorCode;
+    rep.majorCode = majorCode;
+    rep.minorCode = minorCode;
+    rep.resourceID = resId;
+
+    WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].pWin == pWin)
+        {
+	    if (SelectionCallback)
+	    {
+	        SelectionInfoRec    info;
+
+		info.selection = &CurrentSelections[i];
+		info.kind = SelectionWindowDestroy;
+		CallCallbacks(&SelectionCallback, &info);
+	    }
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].client == client)
+        {
+	    if (SelectionCallback)
+	    {
+	        SelectionInfoRec    info;
+
+		info.selection = &CurrentSelections[i];
+		info.kind = SelectionWindowDestroy;
+		CallCallbacks(&SelectionCallback, &info);
+	    }
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+    client->noClientException = -1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
new file mode 100644
index 000000000..845c6cfb9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -0,0 +1,4670 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dispatch.c,v 1.13 2005/09/13 01:33:19 daniels Exp $ */
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.32 2003/11/10 18:21:45 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#ifdef __sun
+#define False 0
+#define True 1
+#endif
+
+#define GC XlibGC
+#include <X11/Xlib.h>
+#undef GC
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#endif
+
+#include "Atoms.h"
+#include "Splash.h"
+#include "Client.h"
+#include "Clipboard.h"
+#include "Reconnect.h"
+#include "Millis.h"
+#include "Font.h"
+#include "Shadow.h"
+#include "Handlers.h"
+#include "Keyboard.h"
+
+const int nxagentMaxFontNames = 10000;
+
+char dispatchExceptionAtReset = DE_RESET;
+
+/*
+ * This allows the agent to exit if no
+ * client is connected within a timeout.
+ */
+
+int nxagentClients = 0;
+
+void nxagentWaitDisplay(void);
+
+void nxagentListRemoteFonts(const char *, int);
+
+unsigned int nxagentWMtimeout = 0;
+Bool         nxagentWMPassed  = 0;
+
+/*
+ * Timeouts based on screen saver time.
+ */
+
+int nxagentAutoDisconnectTimeout = 0;
+
+#ifdef LBX
+#include "../../lbx/lbxserve.h"
+#endif
+
+#include "Xatom.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  WATCH
+
+/*
+ * Log begin and end of the important handlers.
+ */
+
+#undef  BLOCKS
+
+#ifdef WATCH
+#include "unistd.h"
+#endif
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+#ifdef VIEWPORT_FRAME
+
+extern WindowPtr nxagentViewportFrameLeft;
+extern WindowPtr nxagentViewportFrameRight;
+extern WindowPtr nxagentViewportFrameAbove;
+extern WindowPtr nxagentViewportFrameBelow;
+
+#define IsViewportFrame(pWin) ((pWin) == nxagentViewportFrameLeft || \
+                                   (pWin) == nxagentViewportFrameRight || \
+                                       (pWin) == nxagentViewportFrameAbove || \
+                                           (pWin) == nxagentViewportFrameBelow)
+
+#else
+
+#define IsViewportFrame(pWin) (0)
+
+#endif /* #ifdef VIEWPORT_FRAME */
+
+extern int nxagentMaxAllowedResets;
+
+extern int nxagentFindClientResource(int, RESTYPE, pointer);
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int	nClients;	/* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue;   /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+    (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+    checkForInput[0] = c0;
+    checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+    TimeStamp systime;
+
+    /* To avoid time running backwards, we must call GetTimeInMillis before
+     * calling ProcessInputEvents.
+     */
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] != *checkForInput[1])
+	ProcessInputEvents();
+    if (CompareTimeStamps(systime, currentTime) == LATER)
+	currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+    TimeStamp systime;
+
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] == *checkForInput[1])
+	currentTime = systime;
+}
+
+void
+InitSelections()
+{
+    if (CurrentSelections)
+	xfree(CurrentSelections);
+    CurrentSelections = (Selection *)NULL;
+    NumCurrentSelections = 0;
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+      Selection *newsels;
+      newsels = (Selection *)xalloc(2 * sizeof(Selection));
+      if (!newsels)
+        return;
+      NumCurrentSelections += 2;
+      CurrentSelections = newsels;
+
+      CurrentSelections[0].selection = XA_PRIMARY;
+      CurrentSelections[0].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[0].window = WindowTable[0]->drawable.id;
+      CurrentSelections[0].pWin = NULL;
+      CurrentSelections[0].client = NullClient;
+
+      CurrentSelections[1].selection = MakeAtom("CLIPBOARD", 9, 1);
+      CurrentSelections[1].lastTimeChanged = ClientTimeToServerTime(0);
+      CurrentSelections[1].window = WindowTable[0]->drawable.id;
+      CurrentSelections[1].pWin = NULL;
+      CurrentSelections[1].client = NullClient;
+    }
+#endif
+
+}
+
+void 
+FlushClientCaches(XID id)
+{
+    int i;
+    register ClientPtr client;
+
+    client = clients[CLIENT_ID(id)];
+    if (client == NullClient)
+        return ;
+    for (i=0; i<currentMaxClients; i++)
+    {
+	client = clients[i];
+        if (client != NullClient)
+	{
+            if (client->lastDrawableID == id)
+	    {
+		client->lastDrawableID = WindowTable[0]->drawable.id;
+		client->lastDrawable = (DrawablePtr)WindowTable[0];
+	    }
+            else if (client->lastGCID == id)
+	    {
+                client->lastGCID = INVALID;
+		client->lastGC = (GCPtr)NULL;
+	    }
+	}
+    }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
+#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
+
+Bool	    SmartScheduleDisable = FALSE;
+long	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long	    SmartScheduleTime;
+ClientPtr   SmartLastClient;
+int	    SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int         SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long	    SmartLastPrint;
+#endif
+
+void        Dispatch(void);
+void        InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+    ClientPtr	pClient;
+    int		i;
+    int		client;
+    int		bestPrio, best = 0;
+    int		bestRobin, robin;
+    long	now = SmartScheduleTime;
+    long	idle;
+
+    bestPrio = -0x7fffffff;
+    bestRobin = 0;
+    idle = 2 * SmartScheduleSlice;
+    for (i = 0; i < nready; i++)
+    {
+	client = clientReady[i];
+	pClient = clients[client];
+	/* Praise clients which are idle */
+	if ((now - pClient->smart_check_tick) >= idle)
+	{
+	    if (pClient->smart_priority < 0)
+		pClient->smart_priority++;
+	}
+	pClient->smart_check_tick = now;
+	
+	/* check priority to select best client */
+	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+	if (pClient->smart_priority > bestPrio ||
+	    (pClient->smart_priority == bestPrio && robin > bestRobin))
+	{
+	    bestPrio = pClient->smart_priority;
+	    bestRobin = robin;
+	    best = client;
+	}
+#ifdef SMART_DEBUG
+	if ((now - SmartLastPrint) >= 5000)
+	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+    }
+#ifdef SMART_DEBUG
+    if ((now - SmartLastPrint) >= 5000)
+    {
+	fprintf (stderr, " use %2d\n", best);
+	SmartLastPrint = now;
+    }
+#endif
+    pClient = clients[best];
+    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+    /*
+     * Set current client pointer
+     */
+    if (SmartLastClient != pClient)
+    {
+	pClient->smart_start_tick = now;
+	SmartLastClient = pClient;
+    }
+    /*
+     * Adjust slice
+     */
+    if (nready == 1)
+    {
+	/*
+	 * If it's been a long time since another client
+	 * has run, bump the slice up to get maximal
+	 * performance from a single client
+	 */
+	if ((now - pClient->smart_start_tick) > 1000 &&
+	    SmartScheduleSlice < SmartScheduleMaxSlice)
+	{
+	    SmartScheduleSlice += SmartScheduleInterval;
+	}
+    }
+    else
+    {
+	SmartScheduleSlice = SmartScheduleInterval;
+    }
+    return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+    register int        *clientReady;     /* array of request ready clients */
+    register int	result;
+    register ClientPtr	client;
+    register int	nready;
+    register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+    long			start_tick;
+#endif
+
+    unsigned long currentDispatch = 0;
+
+    nextFreeClientID = 1;
+    InitSelections();
+    nClients = 0;
+
+    /*
+     * The agent initialization was successfully
+     * completed. We can now handle our clients.
+     */
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+
+      nxagentSessionState = SESSION_UP;
+    }
+
+    #ifdef XKB
+
+    nxagentInitXkbWrapper();
+
+    nxagentTuneXkbWrapper();
+
+    #endif
+
+    #ifdef NXAGENT_ONSTART
+
+    /*
+     * Set NX_WM property (used by NX client to identify
+     * the agent's window) three seconds since the first
+     * client connects.
+     */
+
+    nxagentWMtimeout = GetTimeInMillis() + 3000;
+
+    #endif
+
+    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+    if (!clientReady)
+	return;
+
+  #ifdef WATCH
+
+  fprintf(stderr, "Dispatch: Watchpoint 12.\n");
+
+/*
+Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
+------- -----	------	-------			--------		----------	  -----
+#3      1		352 bits (0 KB) ->	236 bits (0 KB) ->	352/1 -> 236/1	= 1.492:1
+#14     1		256 bits (0 KB) ->	101 bits (0 KB) ->	256/1 -> 101/1	= 2.535:1
+#16     1		256 bits (0 KB) ->	26 bits (0 KB) ->	256/1 -> 26/1	= 9.846:1
+#20     2	2	12256 bits (1 KB) ->	56 bits (0 KB) ->	6128/1 -> 28/1	= 218.857:1
+#43     1		256 bits (0 KB) ->	45 bits (0 KB) ->	256/1 -> 45/1	= 5.689:1
+#47     2	2	42304 bits (5 KB) ->	49 bits (0 KB) ->	21152/1 -> 24/1	= 863.347:1
+#98     1		256 bits (0 KB) ->	34 bits (0 KB) ->	256/1 -> 34/1	= 7.529:1
+*/
+
+  sleep(30);
+
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "Dispatch: Value of dispatchException is [%x].\n",
+              dispatchException);
+
+  fprintf(stderr, "Dispatch: Value of dispatchExceptionAtReset is [%x].\n",
+              dispatchExceptionAtReset);
+  #endif
+
+  if (!(dispatchException & DE_TERMINATE))
+    dispatchException = 0;
+
+    while (!dispatchException)
+    {
+        if (*icheck[0] != *icheck[1])
+	{
+	    ProcessInputEvents();
+	    FlushIfCriticalOutputPending();
+	}
+
+        /*
+         * Ensure we remove the splash after the timeout.
+         * Initializing clientReady[0] to -1 will tell
+         * WaitForSomething() to yield control after the
+         * timeout set in clientReady[1].
+         */
+
+        clientReady[0] = 0;
+
+        if (nxagentSplashWindow != None || (nxagentOption(Xdmcp) == 1 && nxagentXdmcpUp == 0))
+        {
+          #ifdef TEST
+          fprintf(stderr, "******Dispatch: Requesting a timeout of [%d] Ms.\n",
+                      NXAGENT_WAKEUP);
+          #endif
+
+          clientReady[0] = -1;
+          clientReady[1] = NXAGENT_WAKEUP;
+        }
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[End dispatch]\n");
+        #endif
+
+	nready = WaitForSomething(clientReady);
+
+        #ifdef BLOCKS
+        fprintf(stderr, "[Begin dispatch]\n");
+        #endif
+
+        #ifdef TEST
+        fprintf(stderr, "******Dispatch: Running with [%d] clients ready.\n",
+                    nready);
+        #endif
+        
+        #ifdef NXAGENT_ONSTART
+
+        currentDispatch = GetTimeInMillis();
+
+        /*
+         * If the timeout is expired set the
+         * selection informing the NX client
+         * that the agent is ready.
+         */
+
+         if (!nxagentWMPassed && (nxagentWMtimeout < currentDispatch))
+         {
+           nxagentRemoveSplashWindow(NULL);
+         }
+
+         nxagentClients = nClients;
+
+         #endif
+
+#ifdef SMART_SCHEDULE
+	if (nready && !SmartScheduleDisable)
+	{
+	    clientReady[0] = SmartScheduleClient (clientReady, nready);
+	    nready = 1;
+	}
+#endif
+       /***************** 
+	*  Handle events in round robin fashion, doing input between 
+	*  each round 
+	*****************/
+
+	while (!dispatchException && (--nready >= 0))
+	{
+	    client = clients[clientReady[nready]];
+	    if (! client)
+	    {
+		/* KillClient can cause this to happen */
+		continue;
+	    }
+	    /* GrabServer activation can cause this to be true */
+	    if (grabState == GrabKickout)
+	    {
+		grabState = GrabActive;
+		break;
+	    }
+	    isItTimeToYield = FALSE;
+ 
+            requestingClient = client;
+#ifdef SMART_SCHEDULE
+	    start_tick = SmartScheduleTime;
+#endif
+	    while (!isItTimeToYield)
+	    {
+	        if (*icheck[0] != *icheck[1])
+		{
+		    ProcessInputEvents();
+		    FlushIfCriticalOutputPending();
+		}
+#ifdef SMART_SCHEDULE
+		if (!SmartScheduleDisable && 
+		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+		{
+		    /* Penalize clients which consume ticks */
+		    if (client->smart_priority > SMART_MIN_PRIORITY)
+			client->smart_priority--;
+		    break;
+		}
+#endif
+		/* now, finally, deal with client requests */
+
+                #ifdef TEST
+                fprintf(stderr, "******Dispatch: Reading request from client [%d].\n",
+                            client->index);
+                #endif
+
+	        result = ReadRequestFromClient(client);
+	        if (result <= 0) 
+	        {
+		    if (result < 0)
+			CloseDownClient(client);
+		    break;
+	        }
+#ifdef NXAGENT_SERVER
+
+                #ifdef TEST
+
+                else
+                {
+
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Read [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d].\n", MAJOROP, *((char *) client->requestBuffer + 1),
+                                      client->req_len << 2, client->index);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Read [%s] request OPCODE#%d size [%d] client [%d].\n",
+                                  nxagentRequestLiteral[MAJOROP], MAJOROP, client->req_len << 2,
+                                      client->index);
+                    }
+                }
+
+                #endif
+#endif
+
+		client->sequence++;
+#ifdef DEBUG
+		if (client->requestLogIndex == MAX_REQUEST_LOG)
+		    client->requestLogIndex = 0;
+		client->requestLog[client->requestLogIndex] = MAJOROP;
+		client->requestLogIndex++;
+#endif
+		if (result > (maxBigRequestSize << 2))
+		    result = BadLength;
+		else
+#ifdef NXAGENT_SERVER
+                {
+                    result = (* client->requestVector[MAJOROP])(client);
+
+                    #ifdef TEST
+
+                    if (MAJOROP > 127)
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [Extension] request OPCODE#%d MINOR#%d "
+                                  "size [%d] client [%d] result [%d].\n", MAJOROP,
+                                      *((char *) client->requestBuffer + 1), client->req_len << 2,
+                                          client->index, result);
+                    }
+                    else
+                    {
+                      fprintf(stderr, "******Dispatch: Handled [%s] request OPCODE#%d size [%d] client [%d] "
+                                  "result [%d].\n", nxagentRequestLiteral[MAJOROP], MAJOROP,
+                                      client->req_len << 2, client->index, result);
+                    }
+
+                    #endif
+
+                    /*
+                     * Can set isItTimeToYield to force
+                     * the dispatcher to pay attention
+                     * to another client.
+                     */
+
+                    nxagentDispatchHandler(client, client->req_len << 2, 0);
+                }
+#else
+		    result = (* client->requestVector[MAJOROP])(client);
+#endif
+
+		if (result != Success) 
+		{
+		    if (client->noClientException != Success)
+                        CloseDownClient(client);
+                    else
+		        SendErrorToClient(client, MAJOROP,
+					  MinorOpcodeOfRequest(client),
+					  client->errorValue, result);
+		    break;
+	        }
+#ifdef DAMAGEEXT
+		FlushIfCriticalOutputPending ();
+#endif
+	    }
+	    FlushAllOutput();
+#ifdef SMART_SCHEDULE
+	    client = clients[clientReady[nready]];
+	    if (client)
+		client->smart_stop_tick = SmartScheduleTime;
+#endif
+	    requestingClient = NULL;
+	}
+	dispatchException &= ~DE_PRIORITYCHANGE;
+    }
+#if defined(DDXBEFORERESET)
+    ddxBeforeReset ();
+#endif
+    if ((dispatchException & DE_RESET) && 
+            (serverGeneration > nxagentMaxAllowedResets))
+    {
+        dispatchException &= ~DE_RESET;
+        dispatchException |= DE_TERMINATE;
+
+        fprintf(stderr, "Info: Reached threshold of maximum allowed resets.\n");
+    }
+
+    nxagentResetAtomMap();
+
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      /*
+       * The session is terminating. Force an I/O
+       * error on the display and wait until the
+       * NX transport is gone.
+       */
+  
+      fprintf(stderr, "Session: Terminating session at '%s'.\n", GetTimeAsString());
+
+      nxagentWaitDisplay();
+
+      fprintf(stderr, "Session: Session terminated at '%s'.\n", GetTimeAsString());
+    }
+
+    if (nxagentOption(Shadow) == 1)
+    {
+      NXShadowDestroy();
+    }
+
+    KillAllClients();
+    DEALLOCATE_LOCAL(clientReady);
+    dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+int
+ProcBadRequest(ClientPtr client)
+{
+    return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+    register WindowPtr pParent, pWin;
+    REQUEST(xCreateWindowReq);
+    int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+    
+    LEGAL_NEW_RESOURCE(stuff->wid, client);
+    if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+						    SecurityWriteAccess)))
+        return BadWindow;
+    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+    if (Ones(stuff->mask) != len)
+        return BadLength;
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+			      stuff->y, stuff->width, stuff->height, 
+			      stuff->borderWidth, stuff->class,
+			      stuff->mask, (XID *) &stuff[1], 
+			      (int)stuff->depth, 
+			      client, stuff->visual, &result);
+    if (pWin)
+    {
+	Mask mask = pWin->eventMask;
+
+	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+	    return BadAlloc;
+	pWin->eventMask = mask;
+    }
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeWindowAttributesReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+    if (len != Ones(stuff->valueMask))
+        return BadLength;
+    result =  ChangeWindowAttributes(pWin, 
+				  stuff->valueMask, 
+				  (XID *) &stuff[1], 
+				  client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+    xGetWindowAttributesReply wa;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    GetWindowAttributes(pWin, client, &wa);
+    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+    return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->parent)
+	FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    DestroySubwindows(pWin, client);
+    return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeSaveSetReq);
+    register int result;
+		  
+    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+        return BadMatch;
+    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+    {
+        result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->mode;
+	return( BadValue );
+    }
+}
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+    register WindowPtr pWin, pParent;
+    REQUEST(xReparentWindowReq);
+    register int result;
+
+    REQUEST_SIZE_MATCH(xReparentWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    if (!nxagentWMPassed)
+    {
+      nxagentRemoveSplashWindow(pWin);
+    }
+
+    pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+					      SecurityWriteAccess);
+    if (!pParent)
+        return(BadWindow);
+    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+    {
+        if ((pWin->backgroundState == ParentRelative) &&
+            (pParent->drawable.depth != pWin->drawable.depth))
+            return BadMatch;
+	if ((pWin->drawable.class != InputOnly) &&
+	    (pParent->drawable.class == InputOnly))
+	    return BadMatch;
+        result =  ReparentWindow(pWin, pParent, 
+			 (short)stuff->x, (short)stuff->y, client);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else 
+        return (BadMatch);
+}
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapWindow(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapSubwindows(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapWindow(pWin, FALSE);
+           /* update cache to say it is mapped */
+
+    return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapSubwindows(pWin);
+    return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xConfigureWindowReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+    if (Ones((Mask)stuff->mask) != len)
+        return BadLength;
+    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
+			      client);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xCirculateWindowReq);
+
+    REQUEST_SIZE_MATCH(xCirculateWindowReq);
+    if ((stuff->direction != RaiseLowest) &&
+	(stuff->direction != LowerHighest))
+    {
+	client->errorValue = stuff->direction;
+        return BadValue;
+    }
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    CirculateWindow(pWin, (int)stuff->direction, client);
+    return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+    register DrawablePtr pDraw;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+    rep->type = X_Reply;
+    rep->length = 0;
+    rep->sequenceNumber = client->sequence;
+    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+    rep->depth = pDraw->depth;
+    rep->width = pDraw->width;
+    rep->height = pDraw->height;
+
+    /* XXX - Because the pixmap-implementation of the multibuffer extension 
+     *       may have the buffer-id's drawable resource value be a pointer
+     *       to the buffer's window instead of the buffer itself
+     *       (this happens if the buffer is the displayed buffer),
+     *       we also have to check that the id matches before we can
+     *       truly say that it is a DRAWABLE_WINDOW.
+     */
+
+    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+    {
+        register WindowPtr pWin = (WindowPtr)pDraw;
+	rep->x = pWin->origin.x - wBorderWidth (pWin);
+	rep->y = pWin->origin.y - wBorderWidth (pWin);
+	rep->borderWidth = pWin->borderWidth;
+    }
+    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+    {
+	rep->x = rep->y = rep->borderWidth = 0;
+    }
+
+    return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+    xGetGeometryReply rep;
+    int status;
+
+    if ((status = GetGeometry(client, &rep)) != Success)
+	return status;
+
+    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+    return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+    xQueryTreeReply reply;
+    int numChildren = 0;
+    register WindowPtr pChild, pWin, pHead;
+    Window  *childIDs = (Window *)NULL;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    reply.type = X_Reply;
+    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+    reply.sequenceNumber = client->sequence;
+    if (pWin->parent)
+	reply.parent = pWin->parent->drawable.id;
+    else
+        reply.parent = (Window)None;
+    pHead = RealChildHead(pWin);
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+      if (!IsViewportFrame(pChild))
+      {
+	numChildren++;
+      }
+    }
+    if (numChildren)
+    {
+	int curChild = 0;
+
+	childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+	if (!childIDs)
+	    return BadAlloc;
+	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+        {
+          if (!IsViewportFrame(pChild))
+          {
+	    childIDs[curChild++] = pChild->drawable.id;
+          }
+        }
+    }
+    
+    reply.nChildren = numChildren;
+    reply.length = (numChildren * sizeof(Window)) >> 2;
+    
+    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+    if (numChildren)
+    {
+    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+	DEALLOCATE_LOCAL(childIDs);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+    Atom atom;
+    char *tchar;
+    REQUEST(xInternAtomReq);
+
+    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+    {
+	client->errorValue = stuff->onlyIfExists;
+        return(BadValue);
+    }
+    tchar = (char *) &stuff[1];
+    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+    if (atom != BAD_RESOURCE)
+    {
+	xInternAtomReply reply;
+	reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+	reply.atom = atom;
+	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+	return(client->noClientException);
+    }
+    else
+	return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+    char *str;
+    xGetAtomNameReply reply;
+    int len;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if ( (str = NameForAtom(stuff->id)) )
+    {
+	len = strlen(str);
+	reply.type = X_Reply;
+	reply.length = (len + 3) >> 2;
+	reply.sequenceNumber = client->sequence;
+	reply.nameLength = len;
+	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+	(void)WriteToClient(client, len, str);
+	return(client->noClientException);
+    }
+    else 
+    { 
+	client->errorValue = stuff->id;
+	return (BadAtom);
+    }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+    WindowPtr pWin;
+    TimeStamp time;
+    REQUEST(xSetSelectionOwnerReq);
+
+    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+    UpdateCurrentTime();
+    time = ClientTimeToServerTime(stuff->time);
+
+    /* If the client's time stamp is in the future relative to the server's
+	time stamp, do not set the selection, just return success. */
+    if (CompareTimeStamps(time, currentTime) == LATER)
+    	return Success;
+    if (stuff->window != None)
+    {
+        pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					       SecurityReadAccess);
+        if (!pWin)
+            return(BadWindow);
+    }
+    else
+        pWin = (WindowPtr)None;
+    if (ValidAtom(stuff->selection))
+    {
+	int i = 0;
+
+	/*
+	 * First, see if the selection is already set... 
+	 */
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) 
+            i++;
+        if (i < NumCurrentSelections)
+        {        
+	    xEvent event;
+
+	    /* If the timestamp in client's request is in the past relative
+		to the time stamp indicating the last time the owner of the
+		selection was set, do not set the selection, just return 
+		success. */
+            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+		== EARLIER)
+		return Success;
+	    if (CurrentSelections[i].client &&
+		(!pWin || (CurrentSelections[i].client != client)))
+	    {
+		event.u.u.type = SelectionClear;
+		event.u.selectionClear.time = time.milliseconds;
+		event.u.selectionClear.window = CurrentSelections[i].window;
+		event.u.selectionClear.atom = CurrentSelections[i].selection;
+		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+				NoEventMask, NoEventMask /* CantBeFiltered */,
+				NullGrab);
+	    }
+	}
+	else
+	{
+	    /*
+	     * It doesn't exist, so add it...
+	     */
+	    Selection *newsels;
+
+	    if (i == 0)
+		newsels = (Selection *)xalloc(sizeof(Selection));
+	    else
+		newsels = (Selection *)xrealloc(CurrentSelections,
+			    (NumCurrentSelections + 1) * sizeof(Selection));
+	    if (!newsels)
+		return BadAlloc;
+	    NumCurrentSelections++;
+	    CurrentSelections = newsels;
+	    CurrentSelections[i].selection = stuff->selection;
+	}
+        CurrentSelections[i].lastTimeChanged = time;
+	CurrentSelections[i].window = stuff->window;
+	CurrentSelections[i].pWin = pWin;
+	CurrentSelections[i].client = (pWin ? client : NullClient);
+	if (SelectionCallback)
+	{
+	    SelectionInfoRec	info;
+
+	    info.selection = &CurrentSelections[i];
+	    info.kind= SelectionSetOwner;
+	    CallCallbacks(&SelectionCallback, &info);
+	}
+
+#ifdef NXAGENT_CLIPBOARD
+      if ((CurrentSelections[i].pWin != NULL) &&
+              (nxagentOption(Clipboard) != ClipboardNone) &&
+                  ((CurrentSelections[i].selection == XA_PRIMARY) ||
+                       (CurrentSelections[i].selection == MakeAtom("CLIPBOARD", 9, 0))))
+      {
+        nxagentSetSelectionOwner(&CurrentSelections[i]);
+      }
+#endif
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->selection;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (ValidAtom(stuff->id))
+    {
+	int i;
+        xGetSelectionOwnerReply reply;
+
+	i = 0;
+        while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->id) i++;
+        reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+        if (i < NumCurrentSelections)
+            reply.owner = CurrentSelections[i].window;
+        else
+            reply.owner = None;
+        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+        return(client->noClientException);
+    }
+    else            
+    {
+	client->errorValue = stuff->id;
+        return (BadAtom); 
+    }
+}
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+    Bool paramsOkay;
+    xEvent event;
+    WindowPtr pWin;
+    REQUEST(xConvertSelectionReq);
+
+    REQUEST_SIZE_MATCH(xConvertSelectionReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+#ifdef NXAGENT_CLIPBOARD
+    if (((stuff->selection == XA_PRIMARY) ||
+           (stuff->selection == MakeAtom("CLIPBOARD", 9, 0))) &&
+               nxagentOption(Clipboard) != ClipboardNone)
+    {
+      int i = 0;
+
+      while ((i < NumCurrentSelections) &&
+                CurrentSelections[i].selection != stuff->selection) i++;
+
+      if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None))
+      {
+        if (nxagentConvertSelection(client, pWin, stuff->selection, stuff->requestor,
+                                       stuff->property, stuff->target, stuff->time))
+        {
+          return (client->noClientException);
+        }
+      }
+    }
+#endif
+
+    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+    if (stuff->property != None)
+	paramsOkay &= ValidAtom(stuff->property);
+    if (paramsOkay)
+    {
+	int i;
+
+	i = 0;
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) i++;
+	if ((i < NumCurrentSelections) && 
+	    (CurrentSelections[i].window != None) && (CurrentSelections[i].client != NullClient)
+#ifdef XCSECURITY
+	    && (!client->CheckAccess ||
+		(* client->CheckAccess)(client, CurrentSelections[i].window,
+					RT_WINDOW, SecurityReadAccess,
+					CurrentSelections[i].pWin))
+#endif
+	    )
+	{        
+	    event.u.u.type = SelectionRequest;
+	    event.u.selectionRequest.time = stuff->time;
+	    event.u.selectionRequest.owner = 
+			CurrentSelections[i].window;
+	    event.u.selectionRequest.requestor = stuff->requestor;
+	    event.u.selectionRequest.selection = stuff->selection;
+	    event.u.selectionRequest.target = stuff->target;
+	    event.u.selectionRequest.property = stuff->property;
+	    if (TryClientEvents(
+		CurrentSelections[i].client, &event, 1, NoEventMask,
+		NoEventMask /* CantBeFiltered */, NullGrab))
+		return (client->noClientException);
+	}
+	event.u.u.type = SelectionNotify;
+	event.u.selectionNotify.time = stuff->time;
+	event.u.selectionNotify.requestor = stuff->requestor;
+	event.u.selectionNotify.selection = stuff->selection;
+	event.u.selectionNotify.target = stuff->target;
+	event.u.selectionNotify.property = None;
+	(void) TryClientEvents(client, &event, 1, NoEventMask,
+			       NoEventMask /* CantBeFiltered */, NullGrab);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->property;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+    REQUEST_SIZE_MATCH(xReq);
+    if (grabState != GrabNone && client != grabClient)
+    {
+	ResetCurrentRequest(client);
+	client->sequence--;
+	BITSET(grabWaiters, client->index);
+	IgnoreClient(client);
+	return(client->noClientException);
+    }
+    OnlyListenToOneClient(client);
+    grabState = GrabKickout;
+    grabClient = client;
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_GRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+
+    return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+    int i;
+
+    grabState = GrabNone;
+    ListenToAllClients();
+    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+	;
+    if (i >= 0)
+    {
+	i <<= 5;
+	while (!GETBIT(grabWaiters, i))
+	    i++;
+	BITCLEAR(grabWaiters, i);
+	AttendClient(clients[i]);
+    }
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_UNGRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+    REQUEST_SIZE_MATCH(xReq);
+    UngrabServer(client);
+    return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+    REQUEST(xTranslateCoordsReq);
+
+    register WindowPtr pWin, pDst;
+    xTranslateCoordsReply rep;
+
+    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+					   SecurityReadAccess);
+    if (!pDst)
+        return(BadWindow);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+    {
+	rep.sameScreen = xFalse;
+        rep.child = None;
+	rep.dstX = rep.dstY = 0;
+    }
+    else
+    {
+	INT16 x, y;
+	rep.sameScreen = xTrue;
+	rep.child = None;
+	/* computing absolute coordinates -- adjust to destination later */
+	x = pWin->drawable.x + stuff->srcX;
+	y = pWin->drawable.y + stuff->srcY;
+	pWin = pDst->firstChild;
+	while (pWin)
+	{
+#ifdef SHAPE
+	    BoxRec  box;
+#endif
+	    if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		 wBorderWidth (pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		 wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen, 
+					&pWin->borderSize, x, y, &box))
+		
+		&& (!wInputShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen,
+				    wInputShape(pWin),
+				    x - pWin->drawable.x,
+				    y - pWin->drawable.y, &box))
+#endif
+		)
+            {
+		rep.child = pWin->drawable.id;
+		pWin = (WindowPtr) NULL;
+	    }
+	    else
+		pWin = pWin->nextSib;
+	}
+	/* adjust to destination coordinates */
+	rep.dstX = x - pDst->drawable.x;
+	rep.dstY = y - pDst->drawable.y;
+    }
+    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+    return(client->noClientException);
+}
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+    int	err;
+    char fontReq[256];
+    REQUEST(xOpenFontReq);
+
+    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+    client->errorValue = stuff->fid;
+    LEGAL_NEW_RESOURCE(stuff->fid, client);
+
+    memcpy(fontReq,(char *)&stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    fontReq[stuff->nbytes]=0;
+    if (strchr(fontReq,'*') || strchr(fontReq,'?'))
+    {
+       extern int nxOpenFont(ClientPtr, XID, Mask, unsigned, char*);
+#ifdef NXAGENT_FONTMATCH_DEBUG
+       fprintf(stderr, "Dispatch: ProcOpenFont try to find a common font with font pattern=%s\n",fontReq);
+#endif
+       nxagentListRemoteFonts(fontReq, nxagentMaxFontNames);
+       err = nxOpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    }
+    else
+    err = OpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+    FontPtr pFont;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityDestroyAccess);
+    if (pFont != (FontPtr)NULL)
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client closes a font the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this font looping through the
+         * resources.
+         */
+
+        if (pFont -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_FONT, pFont) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcCloseFont: Switching resource for font at [%p].\n",
+                        (void *) pFont);
+            #endif
+
+            nxagentFontPriv(pFont) -> mirrorID = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentFontPriv(pFont) -> mirrorID, RT_NX_FONT, pFont);
+
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcCloseFont: Found duplicated font at [%p], "
+                        "resource switching skipped.\n", (void *) pFont);
+          }
+          #endif
+        }
+
+        #endif
+
+        FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+        return (BadFont);
+    }
+}
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+    xQueryFontReply	*reply;
+    FontPtr pFont;
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    client->errorValue = stuff->id;		/* EITHER font or gc */
+
+    pFont = NULL;
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+	  /* can't use VERIFY_GC because it might return BadGC */
+	pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+					    SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->id;
+            return(BadFont);     /* procotol spec says only error is BadFont */
+	}
+	pFont = pGC->font;
+    }
+
+/* test
+{
+  Atom name_atom, value_atom;
+  int nprops;
+  FontPropPtr props;
+  int i;
+  char *name;
+
+  name_atom = MakeAtom("FONT", 4, True);
+  value_atom = 0L;
+
+  nprops = pFont->info.nprops;
+  props = pFont->info.props;
+
+  for (i = 0; i < nprops; i++)
+    if (props[i].name == name_atom) {
+      value_atom = props[i].value;
+      break;
+    }
+
+  if (!value_atom) return (BadFont);
+
+  name = (char *)NameForAtom(value_atom);
+  fprintf(stderr, "QueryFont: font name [%s]\n",name);
+}
+ end test */
+
+    {
+	xCharInfo	*pmax = FONTINKMAX(pFont);
+	xCharInfo	*pmin = FONTINKMIN(pFont);
+	int		nprotoxcistructs;
+	int		rlength;
+
+	nprotoxcistructs = (
+	   pmax->rightSideBearing == pmin->rightSideBearing &&
+	   pmax->leftSideBearing == pmin->leftSideBearing &&
+	   pmax->descent == pmin->descent &&
+	   pmax->ascent == pmin->ascent &&
+	   pmax->characterWidth == pmin->characterWidth) ?
+		0 : N2dChars(pFont);
+
+	rlength = sizeof(xQueryFontReply) +
+	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
+		     nprotoxcistructs * sizeof(xCharInfo);
+        reply = NULL;
+	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+	if(!reply)
+	{
+	    return(BadAlloc);
+	}
+
+	reply->type = X_Reply;
+	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+	reply->sequenceNumber = client->sequence;
+	QueryFont( pFont, reply, nprotoxcistructs);
+
+        WriteReplyToClient(client, rlength, reply);
+	DEALLOCATE_LOCAL(reply);
+	return(client->noClientException);
+    }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+    REQUEST(xQueryTextExtentsReq);
+    xQueryTextExtentsReply reply;
+    FontPtr pFont;
+    GC *pGC;
+    ExtentInfoRec info;
+    unsigned long length;
+
+    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+        
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+					   SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->fid;
+            return(BadFont);
+	}
+	pFont = pGC->font;
+    }
+    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+    length = length << 1;
+    if (stuff->oddLength)
+    {
+	if (length == 0)
+	    return(BadLength);
+        length--;
+    }
+    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+	return(BadAlloc);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.drawDirection = info.drawDirection;
+    reply.fontAscent = info.fontAscent;
+    reply.fontDescent = info.fontDescent;
+    reply.overallAscent = info.overallAscent;
+    reply.overallDescent = info.overallDescent;
+    reply.overallWidth = info.overallWidth;
+    reply.overallLeft = info.overallLeft;
+    reply.overallRight = info.overallRight;
+    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListFonts(register ClientPtr client)
+{
+    char tmp[256];
+
+    REQUEST(xListFontsReq);
+
+    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames : stuff->maxNames);
+    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
+	stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+    char tmp[256];
+    REQUEST(xListFontsWithInfoReq);
+
+    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+    memcpy(tmp,(unsigned char *) &stuff[1],(stuff->nbytes<256)?stuff->nbytes:255);
+    tmp[stuff->nbytes]=0;
+#ifdef NXAGENT_FONTMATCH_DEBUG
+    fprintf(stderr, "Dispatch: ListFont with info request with pattern %s max_names=%d\n",tmp,stuff->maxNames);
+#endif
+    nxagentListRemoteFonts(tmp, stuff -> maxNames < nxagentMaxFontNames ? nxagentMaxFontNames :stuff->maxNames);
+
+    return StartListFontsWithInfo(client, stuff->nbytes,
+				  (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+    PixmapPtr pPixmap = (PixmapPtr)value;
+    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    REQUEST(xCreatePixmapReq);
+    DepthPtr pDepth;
+    register int i;
+
+    REQUEST_SIZE_MATCH(xCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->width > 32767 || stuff->height > 32767)
+    {
+	/* It is allowed to try and allocate a pixmap which is larger than
+	 * 32767 in either dimension. However, all of the framebuffer code
+	 * is buggy and does not reliably draw to such big pixmaps, basically
+	 * because the Region data structure operates with signed shorts
+	 * for the rectangles in it.
+	 *
+	 * Furthermore, several places in the X server computes the
+	 * size in bytes of the pixmap and tries to store it in an
+	 * integer. This integer can overflow and cause the allocated size
+	 * to be much smaller.
+	 *
+	 * So, such big pixmaps are rejected here with a BadAlloc
+	 */
+	return BadAlloc;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+		(pDraw->pScreen, stuff->width,
+		 stuff->height, stuff->depth);
+    if (pMap)
+    {
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	    return(client->noClientException);
+    }
+    return (BadAlloc);
+}
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+    PixmapPtr pMap;
+
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+					     SecurityDestroyAccess);
+    if (pMap) 
+    {
+        #ifdef NXAGENT_SERVER
+
+        /*
+         * When a client releases a pixmap the resource
+         * should not be lost if the reference counter
+         * is not 0, otherwise the server will not be
+         * able to find this pixmap looping through the
+         * resources.
+         */
+
+        if (pMap -> refcnt > 0)
+        {
+          if (nxagentFindClientResource(serverClient -> index, RT_NX_PIXMAP, pMap) == 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "ProcFreePixmap: Switching resource for pixmap at [%p].\n",
+                       (void *) pMap);
+            #endif
+
+            nxagentPixmapPriv(pMap) -> mid = FakeClientID(serverClient -> index);
+
+            AddResource(nxagentPixmapPriv(pMap) -> mid, RT_NX_PIXMAP, pMap);
+          }
+          #ifdef TEST
+          else
+          {
+            fprintf(stderr, "ProcFreePixmap: Found duplicated pixmap at [%p], "
+                        "resource switching skipped.\n", (void *) pMap);
+          }
+          #endif
+        }
+
+        #endif
+
+	FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadPixmap);
+    }
+}
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+    int error;
+    GC *pGC;
+    register DrawablePtr pDraw;
+    unsigned len;
+    REQUEST(xCreateGCReq);
+
+    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+    client->errorValue = stuff->gc;
+    LEGAL_NEW_RESOURCE(stuff->gc, client);
+    SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+			      SecurityReadAccess);
+    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+    pGC = (GC *)CreateGC(pDraw, stuff->mask, 
+			 (XID *) &stuff[1], &error);
+    if (error != Success)
+        return error;
+    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+	return (BadAlloc);
+    return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+    GC *pGC;
+    REQUEST(xChangeGCReq);
+    int result;
+    unsigned len;
+		
+    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+    SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+
+    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+    register GC *dstGC;
+    register GC *pGC;
+    int result;
+    REQUEST(xCopyGCReq);
+
+    REQUEST_SIZE_MATCH(xCopyGCReq);
+    SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+    SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+        return (BadMatch);    
+    result = CopyGC(pGC, dstGC, stuff->mask);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+    register GC *pGC;
+    int result;
+    REQUEST(xSetDashesReq);
+
+    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+    if (stuff->nDashes == 0)
+    {
+	 client->errorValue = 0;
+         return BadValue;
+    }
+
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+		       (unsigned char *)&stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+    int	nr;
+    int result;
+    register GC *pGC;
+    REQUEST(xSetClipRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+    {
+	client->errorValue = stuff->ordering;
+        return BadValue;
+    }
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+		 
+    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+    if (nr & 4)
+	return(BadLength);
+    nr >>= 3;
+    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+    FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+    REQUEST(xClearAreaReq);
+    register WindowPtr pWin;
+
+    REQUEST_SIZE_MATCH(xClearAreaReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->drawable.class == InputOnly)
+    {
+	client->errorValue = stuff->window;
+	return (BadMatch);
+    }		    
+    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+    {
+	client->errorValue = stuff->exposures;
+        return(BadValue);
+    }
+    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+			       stuff->width, stuff->height,
+			       (Bool)stuff->exposures);
+    return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+    register DrawablePtr pDst;
+    register DrawablePtr pSrc;
+    register GC *pGC;
+    REQUEST(xCopyAreaReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        pSrc = pDst;
+
+    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY);
+    if (pGC->graphicsExposures)
+    {
+	(*pDst->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+	if (pRgn)
+	    REGION_DESTROY(pDst->pScreen, pRgn);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+    register DrawablePtr psrcDraw, pdstDraw;
+    register GC *pGC;
+    REQUEST(xCopyPlaneReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if (pdstDraw->pScreen != psrcDraw->pScreen)
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        psrcDraw = pdstDraw;
+
+    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+    {
+       client->errorValue = stuff->bitPlane;
+       return(BadValue);
+    }
+
+    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY, stuff->bitPlane);
+    if (pGC->graphicsExposures)
+    {
+	(*pdstDraw->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+	if (pRgn)
+	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyPointReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
+    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+    if (npoint)
+    {
+        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+			  (xPoint *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyLineReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+    if (npoint > 1)
+    {
+	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
+			      (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+    int nsegs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolySegmentReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+    if (nsegs & 4)
+	return(BadLength);
+    nsegs >>= 3;
+    if (nsegs)
+    {
+        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+    int nrects;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+    if (nrects & 4)
+	return(BadLength);
+    nrects >>= 3;
+    if (nrects)
+    {
+        (*pGC->ops->PolyRectangle)(pDraw, pGC, 
+		    nrects, (xRectangle *) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+    int          things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xFillPolyReq);
+
+    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
+	(stuff->shape != Convex))
+    {
+	client->errorValue = stuff->shape;
+        return BadValue;
+    }
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+    if (things)
+    {
+        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+			 stuff->coordMode, things,
+			 (DDXPointPtr) &stuff[1]);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+    int             things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+
+    if (things)
+    {
+        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+		      (xRectangle *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+    {
+        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    }
+    return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+    int	    whichbyte = 1;
+
+    if (*((char *) &whichbyte))
+	return LSBFirst;
+    return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+    switch (bpp) {
+    case 1:	/* yuck */
+	if (BITMAP_BIT_ORDER != order)
+	    BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+	break;
+    case 4:
+	break;  /* yuck */
+    case 8:
+	break;
+    case 16:
+	if (IMAGE_BYTE_ORDER != order)
+	    TwoByteSwap ((unsigned char *) base, nbytes);
+	break;
+    case 32:
+	if (IMAGE_BYTE_ORDER != order)
+	    FourByteSwap ((unsigned char *) base, nbytes);
+	break;
+    }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+    register	GC *pGC;
+    register	DrawablePtr pDraw;
+    long	length; 	/* length of scanline server padded */
+    long 	lengthProto; 	/* length of scanline protocol padded */
+    char	*tmpImage;
+    REQUEST(xPutImageReq);
+
+    REQUEST_AT_LEAST_SIZE(xPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    if (stuff->format == XYBitmap)
+    {
+        if ((stuff->depth != 1) ||
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || 
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length      = BitmapBytePad(stuff->width + stuff->leftPad);
+	length      *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+            return BadMatch;
+        length      = PixmapBytePad(stuff->width, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    tmpImage = (char *)&stuff[1];
+    lengthProto = length;
+	
+    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 
+	(sizeof(xPutImageReq) >> 2)) != client->req_len)
+	return BadLength;
+
+    ReformatImage (tmpImage, lengthProto * stuff->height, 
+		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+		   ClientOrder(client));
+    
+    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+		  stuff->width, stuff->height, 
+		  stuff->leftPad, stuff->format, tmpImage);
+
+     return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable, 
+           int x, int y, int width, int height, 
+           Mask planemask, xGetImageReply **im_return)
+{
+    register DrawablePtr pDraw;
+    int			nlines, linesPerBuf;
+    register int	linesDone;
+    long		widthBytesLine, length;
+    Mask		plane = 0;
+    char		*pBuf;
+    xGetImageReply	xgi;
+#ifdef XCSECURITY
+    RegionPtr pVisibleRegion = NULL;
+#endif
+
+    if ((format != XYPixmap) && (format != ZPixmap))
+    {
+	client->errorValue = format;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+    if(pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + x < 0 ||
+ 	 pDraw->x + x + width > pDraw->pScreen->width ||
+         pDraw->y + y < 0 ||
+         pDraw->y + y + height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         x < - wBorderWidth((WindowPtr)pDraw) ||
+         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         y < -wBorderWidth((WindowPtr)pDraw) ||
+         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual (((WindowPtr) pDraw));
+    }
+    else
+    {
+      if(x < 0 ||
+         x+width > (int)pDraw->width ||
+         y < 0 ||
+         y+height > (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+
+    SET_DBE_SRCBUF(pDraw, drawable);
+
+    xgi.type = X_Reply;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(format == ZPixmap)
+    {
+	widthBytesLine = PixmapBytePad(width, pDraw->depth);
+	length = widthBytesLine * height;
+
+    }
+    else 
+    {
+	widthBytesLine = BitmapBytePad(width);
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = widthBytesLine * height *
+		 Ones(planemask & (plane | (plane - 1)));
+
+    }
+
+    xgi.length = length;
+
+    if (im_return) {
+	pBuf = (char *)xalloc(sz_xGetImageReply + length);
+	if (!pBuf)
+	    return (BadAlloc);
+	if (widthBytesLine == 0)
+	    linesPerBuf = 0;
+	else
+	    linesPerBuf = height;
+	*im_return = (xGetImageReply *)pBuf;
+	*(xGetImageReply *)pBuf = xgi;
+	pBuf += sz_xGetImageReply;
+    } else {
+	xgi.length = (xgi.length + 3) >> 2;
+	if (widthBytesLine == 0 || height == 0)
+	    linesPerBuf = 0;
+	else if (widthBytesLine >= IMAGE_BUFSIZE)
+	    linesPerBuf = 1;
+	else
+	{
+	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+	    if (linesPerBuf > height)
+		linesPerBuf = height;
+	}
+	length = linesPerBuf * widthBytesLine;
+	if (linesPerBuf < height)
+	{
+	    /* we have to make sure intermediate buffers don't need padding */
+	    while ((linesPerBuf > 1) &&
+		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+	    {
+		linesPerBuf--;
+		length -= widthBytesLine;
+	    }
+	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+	    {
+		linesPerBuf++;
+		length += widthBytesLine;
+	    }
+	}
+	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+	    return (BadAlloc);
+	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+    }
+
+#ifdef XCSECURITY
+    if (client->trustLevel != XSecurityClientTrusted &&
+	pDraw->type == DRAWABLE_WINDOW)
+    {
+	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+	if (pVisibleRegion)
+	{
+	    REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+	}
+    }
+#endif
+
+    if (linesPerBuf == 0)
+    {
+	/* nothing to do */
+    }
+    else if (format == ZPixmap)
+    {
+        linesDone = 0;
+        while (height - linesDone > 0)
+        {
+	    nlines = min(linesPerBuf, height - linesDone);
+	    (*pDraw->pScreen->GetImage) (pDraw,
+	                                 x,
+				         y + linesDone,
+				         width, 
+				         nlines,
+				         format,
+				         planemask,
+				         (pointer) pBuf);
+#ifdef XCSECURITY
+	    if (pVisibleRegion)
+		SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+			pDraw, x, y + linesDone, width, 
+			nlines, format, pBuf);
+#endif
+
+	    /* Note that this is NOT a call to WriteSwappedDataToClient,
+               as we do NOT byte swap */
+	    if (!im_return)
+	    {
+		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+			       BitsPerPixel (pDraw->depth),
+			       ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+		(void)WriteToClient(client,
+				    (int)(nlines * widthBytesLine),
+				    pBuf);
+	    }
+	    linesDone += nlines;
+        }
+    }
+    else /* XYPixmap */
+    {
+        for (; plane; plane >>= 1)
+	{
+	    if (planemask & plane)
+	    {
+	        linesDone = 0;
+	        while (height - linesDone > 0)
+	        {
+		    nlines = min(linesPerBuf, height - linesDone);
+	            (*pDraw->pScreen->GetImage) (pDraw,
+	                                         x,
+				                 y + linesDone,
+				                 width, 
+				                 nlines,
+				                 format,
+				                 plane,
+				                 (pointer)pBuf);
+#ifdef XCSECURITY
+		    if (pVisibleRegion)
+			SecurityCensorImage(client, pVisibleRegion,
+				widthBytesLine,
+				pDraw, x, y + linesDone, width, 
+				nlines, format, pBuf);
+#endif
+
+		    /* Note: NOT a call to WriteSwappedDataToClient,
+		       as we do NOT byte swap */
+		    if (im_return) {
+			pBuf += nlines * widthBytesLine;
+		    } else {
+			ReformatImage (pBuf, 
+				       (int)(nlines * widthBytesLine), 
+				       1,
+				       ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+			(void)WriteToClient(client,
+					(int)(nlines * widthBytesLine),
+					pBuf);
+		    }
+		    linesDone += nlines;
+		}
+            }
+	}
+    }
+#ifdef XCSECURITY
+    if (pVisibleRegion)
+	REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+#endif
+    if (!im_return)
+	DEALLOCATE_LOCAL(pBuf);
+    return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+    REQUEST(xGetImageReq);
+
+    REQUEST_SIZE_MATCH(xGetImageReq);
+
+    return DoGetImage(client, stuff->format, stuff->drawable,
+		      stuff->x, stuff->y,
+		      (int)stuff->width, (int)stuff->height,
+		      stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+    int	err;
+    REQUEST(xPolyTextReq);
+    DrawablePtr pDraw;
+    GC *pGC;
+
+    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = PolyText(client,
+		   pDraw,
+		   pGC,
+		   (unsigned char *)&stuff[1],
+		   ((unsigned char *) stuff) + (client->req_len << 2),
+		   stuff->x,
+		   stuff->y,
+		   stuff->reqType,
+		   stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+    VisualPtr	pVisual;
+    ColormapPtr	pmap;
+    Colormap	mid;
+    register WindowPtr   pWin;
+    ScreenPtr pScreen;
+    REQUEST(xCreateColormapReq);
+    int i, result;
+
+    REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+    {
+	client->errorValue = stuff->alloc;
+        return(BadValue);
+    }
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pScreen = pWin->drawable.pScreen;
+    for (i = 0, pVisual = pScreen->visuals;
+	 i < pScreen->numVisuals;
+	 i++, pVisual++)
+    {
+	if (pVisual->vid != stuff->visual)
+	    continue;
+	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
+				 (int)stuff->alloc, client->index);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+	    return(result);
+    }
+    client->errorValue = stuff->visual;
+    return(BadValue);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+    ColormapPtr pmap;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+						SecurityDestroyAccess);
+    if (pmap) 
+    {
+	/* Freeing a default colormap is a no-op */
+	if (!(pmap->flags & IsDefault))
+	    FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadColor);
+    }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+    Colormap	mid;
+    ColormapPtr	pSrcMap;
+    REQUEST(xCopyColormapAndFreeReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client,	stuff->srcCmap,
+		RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+    {
+	result = CopyColormapAndFree(mid, pSrcMap, client->index);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->srcCmap;
+	return(BadColor);
+    }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					    RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+        (*(pcmp->pScreen->InstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	if(pcmp->mid != pcmp->pScreen->defColormap)
+            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+    xListInstalledColormapsReply *preply; 
+    int nummaps;
+    WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+
+    if (!pWin)
+        return(BadWindow);
+
+    preply = (xListInstalledColormapsReply *) 
+		ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+		     pWin->drawable.pScreen->maxInstalledCmaps *
+		     sizeof(Colormap));
+    if(!preply)
+        return(BadAlloc);
+
+    preply->type = X_Reply;
+    preply->sequenceNumber = client->sequence;
+    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+    preply->nColormaps = nummaps;
+    preply->length = nummaps;
+    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+    DEALLOCATE_LOCAL(preply);
+    return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+    ColormapPtr pmap;
+    int	retval;
+    xAllocColorReply acr;
+    REQUEST(xAllocColorReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorReq);
+    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pmap)
+    {
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+	    return Success;
+#endif
+	acr.type = X_Reply;
+	acr.length = 0;
+	acr.sequenceNumber = client->sequence;
+	acr.red = stuff->red;
+	acr.green = stuff->green;
+	acr.blue = stuff->blue;
+	acr.pixel = 0;
+	if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+	                       &acr.pixel, client->index)) )
+	{
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return (retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+	return (client->noClientException);
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					    RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int		retval;
+
+	xAllocNamedColorReply ancr;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocNamedColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	ancr.type = X_Reply;
+	ancr.length = 0;
+	ancr.sequenceNumber = client->sequence;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+	{
+	    ancr.screenRed = ancr.exactRed;
+	    ancr.screenGreen = ancr.exactGreen;
+	    ancr.screenBlue = ancr.exactBlue;
+	    ancr.pixel = 0;
+	    if( (retval = AllocColor(pcmp,
+	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+			 &ancr.pixel, client->index)) )
+	    {
+                if (client->noClientException != Success)
+                    return(client->noClientException);
+                else
+    	            return(retval);
+	    }
+#ifdef PANORAMIX
+	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+	    return (client->noClientException);
+	}
+	else
+	    return(BadName);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorCellsReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorCellsReply	accr;
+	int			npixels, nmasks, retval;
+	long			length;
+	Pixel			*ppixels, *pmasks;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorCells request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	nmasks = stuff->planes;
+	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	pmasks = ppixels + npixels;
+
+	if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 
+				    (Bool)stuff->contiguous, ppixels, pmasks)) )
+	{
+	    DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    accr.type = X_Reply;
+	    accr.length = length >> 2;
+	    accr.sequenceNumber = client->sequence;
+	    accr.nPixels = npixels;
+	    accr.nMasks = nmasks;
+	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorPlanesReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorPlanesReply	acpr;
+	int			npixels, retval;
+	long			length;
+	Pixel			*ppixels;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorPlanes request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	acpr.type = X_Reply;
+	acpr.sequenceNumber = client->sequence;
+	acpr.nPixels = npixels;
+	length = (long)npixels * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+	    (Bool)stuff->contiguous, ppixels,
+	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+	{
+            DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+	acpr.length = length >> 2;
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xFreeColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+	if(pcmp->flags & AllAllocated)
+	    return(BadAccess);
+	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+	retval =  FreeColors(pcmp, client->index, count,
+	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+	if (count % sizeof(xColorItem))
+	    return(BadLength);
+	count /= sizeof(xColorItem);
+	retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xColorItem	def;
+        int             retval;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+	                 stuff->nbytes, &def.red, &def.green, &def.blue))
+	{
+	    def.flags = stuff->flags;
+	    def.pixel = stuff->pixel;
+	    retval = StoreColors(pcmp, 1, &def);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+		return(retval);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xQueryColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	int			count, retval;
+	xrgb 			*prgbs;
+	xQueryColorsReply	qcr;
+
+	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+	prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+	if(!prgbs && count)
+            return(BadAlloc);
+	if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+	{
+   	    if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	    if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	    {
+		client->errorValue = clientErrorValue;
+	        return (retval);
+	    }
+	}
+	qcr.type = X_Reply;
+	qcr.length = (count * sizeof(xrgb)) >> 2;
+	qcr.sequenceNumber = client->sequence;
+	qcr.nColors = count;
+	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+	if (count)
+	{
+	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+	}
+	if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	return(client->noClientException);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+} 
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xLookupColorReq);
+
+    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	xLookupColorReply lcr;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+	{
+	    lcr.type = X_Reply;
+	    lcr.length = 0;
+	    lcr.sequenceNumber = client->sequence;
+	    lcr.screenRed = lcr.exactRed;
+	    lcr.screenGreen = lcr.exactGreen;
+	    lcr.screenBlue = lcr.exactBlue;
+	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+	                                   &lcr.screenGreen,
+					   &lcr.screenBlue,
+					   pcmp->pVisual);
+	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+	    return(client->noClientException);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+    CursorPtr	pCursor;
+
+    register PixmapPtr 	src;
+    register PixmapPtr 	msk;
+    unsigned char *	srcbits;
+    unsigned char *	mskbits;
+    unsigned short	width, height;
+    long		n;
+    CursorMetricRec cm;
+
+
+    REQUEST(xCreateCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+					      RT_PIXMAP, SecurityReadAccess);
+    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+					      RT_PIXMAP, SecurityReadAccess);
+    if (   src == (PixmapPtr)NULL)
+    {
+	client->errorValue = stuff->source;
+	return (BadPixmap);
+    }
+    if ( msk == (PixmapPtr)NULL)
+    {
+	if (stuff->mask != None)
+	{
+	    client->errorValue = stuff->mask;
+	    return (BadPixmap);
+	}
+    }
+    else if (  src->drawable.width != msk->drawable.width
+	    || src->drawable.height != msk->drawable.height
+	    || src->drawable.depth != 1
+	    || msk->drawable.depth != 1)
+	return (BadMatch);
+
+    width = src->drawable.width;
+    height = src->drawable.height;
+
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+
+    n = BitmapBytePad(width)*height;
+    srcbits = (unsigned char *)xalloc(n);
+    if (!srcbits)
+	return (BadAlloc);
+    mskbits = (unsigned char *)xalloc(n);
+    if (!mskbits)
+    {
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+
+    /* zeroing the (pad) bits helps some ddx cursor handling */
+    bzero((char *)srcbits, n);
+    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+					 XYPixmap, 1, (pointer)srcbits);
+    if ( msk == (PixmapPtr)NULL)
+    {
+	register unsigned char *bits = mskbits;
+	while (--n >= 0)
+	    *bits++ = ~0;
+    }
+    else
+    {
+	/* zeroing the (pad) bits helps some ddx cursor handling */
+	bzero((char *)mskbits, n);
+	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+					height, XYPixmap, 1, (pointer)mskbits);
+    }
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursor( srcbits, mskbits, &cm,
+	    stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+	    stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+    {
+        #ifdef TEST
+        fprintf(stderr, "ProcCreateCursor: Created cursor at [%p].\n", (void *) pCursor);
+        #endif
+
+	    return (client->noClientException);
+    }
+
+    return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+    CursorPtr pCursor;
+    int res;
+
+    REQUEST(xCreateGlyphCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+			   stuff->mask, stuff->maskChar,
+			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+			   stuff->backRed, stuff->backGreen, stuff->backBlue,
+			   &pCursor, client);
+    if (res != Success)
+	return res;
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+    CursorPtr pCursor;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_CURSOR, SecurityDestroyAccess);
+    if (pCursor) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadCursor);
+    }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+    xQueryBestSizeReply	reply;
+    register DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    REQUEST(xQueryBestSizeReq);
+
+    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+    if ((stuff->class != CursorShape) && 
+	(stuff->class != TileShape) && 
+	(stuff->class != StippleShape))
+    {
+	client->errorValue = stuff->class;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+	return (BadMatch);
+    pScreen = pDraw->pScreen;
+    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+			       &stuff->height, pScreen);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.width = stuff->width;
+    reply.height = stuff->height;
+    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+    return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+    int blankingOption, exposureOption;
+    REQUEST(xSetScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+    blankingOption = stuff->preferBlank;
+    if ((blankingOption != DontPreferBlanking) &&
+        (blankingOption != PreferBlanking) &&
+        (blankingOption != DefaultBlanking))
+    {
+	client->errorValue = blankingOption;
+        return BadValue;
+    }
+    exposureOption = stuff->allowExpose;
+    if ((exposureOption != DontAllowExposures) &&
+        (exposureOption != AllowExposures) &&
+        (exposureOption != DefaultExposures))
+    {
+	client->errorValue = exposureOption;
+        return BadValue;
+    }
+    if (stuff->timeout < -1)
+    {
+	client->errorValue = stuff->timeout;
+        return BadValue;
+    }
+    if (stuff->interval < -1)
+    {
+	client->errorValue = stuff->interval;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to change our values.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "ProcSetScreenSaver: Called with timeout [%d] interval [%d] Blanking [%d] Exposure [%d].\n",
+                stuff -> timeout, stuff -> interval, blankingOption, exposureOption);
+    #endif
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      if (blankingOption == DefaultBlanking)
+      {
+	ScreenSaverBlanking = defaultScreenSaverBlanking;
+      }
+      else
+      {
+	ScreenSaverBlanking = blankingOption; 
+      }
+
+      if (exposureOption == DefaultExposures)
+      {
+	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+      }
+      else
+      {
+        ScreenSaverAllowExposures = exposureOption;
+      }
+
+      if (stuff->timeout >= 0)
+      {
+        ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverTime = defaultScreenSaverTime;
+      }
+
+      if (stuff->interval >= 0)
+      {
+        ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+      }
+      else
+      {
+        ScreenSaverInterval = defaultScreenSaverInterval;
+      }
+    }
+    #ifdef TEST
+
+    else
+    {
+      fprintf(stderr, "ProcSetScreenSaver: Keeping auto-disconnect timeout set to [%d] seconds.\n",
+                  nxagentOption(Timeout));
+    }
+
+    #endif
+
+    SetScreenSaverTimer();
+    return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+    xGetScreenSaverReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+    rep.preferBlanking = ScreenSaverBlanking;
+    rep.allowExposures = ScreenSaverAllowExposures;
+    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+    return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+    REQUEST(xChangeHostsReq);
+    int result;
+
+    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+    if(stuff->mode == HostInsert)
+	result = AddHost(client, (int)stuff->hostFamily,
+			 stuff->hostLength, (pointer)&stuff[1]);
+    else if (stuff->mode == HostDelete)
+	result = RemoveHost(client, (int)stuff->hostFamily, 
+			    stuff->hostLength, (pointer)&stuff[1]);  
+    else
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+    xListHostsReply reply;
+    int	len, nHosts, result;
+    pointer	pdata;
+    /* REQUEST(xListHostsReq); */
+
+    REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+    /* untrusted clients can't list hosts */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	SecurityAudit("client %d attempted to list hosts\n", client->index);
+	return BadAccess;
+    }
+#endif
+    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+    if (result != Success)
+	return(result);
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.nHosts = nHosts;
+    reply.length = len >> 2;
+    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+    if (nHosts)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+	WriteSwappedDataToClient(client, len, pdata);
+    }
+    xfree(pdata);
+    return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+    int result;
+    REQUEST(xSetAccessControlReq);
+
+    REQUEST_SIZE_MATCH(xSetAccessControlReq);
+    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+    REQUEST(xResourceReq);
+    ClientPtr	killclient;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (stuff->id == AllTemporary)
+    {
+	CloseDownRetainedResources();
+        return (client->noClientException);
+    }
+
+    if ((killclient = LookupClient(stuff->id, client)))
+    {
+	CloseDownClient(killclient);
+	/* if an LBX proxy gets killed, isItTimeToYield will be set */
+	if (isItTimeToYield || (client == killclient))
+	{
+	    /* force yield and return Success, so that Dispatch()
+	     * doesn't try to touch client
+	     */
+	    isItTimeToYield = TRUE;
+	    return (Success);
+	}
+	return (client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+	return (BadValue);
+    }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+    unsigned char *ptr;
+    unsigned long nbytes, total;
+    long nfonts;
+    int n, result;
+    int error;
+    REQUEST(xSetFontPathReq);
+    
+    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+    
+    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+    total = nbytes;
+    ptr = (unsigned char *)&stuff[1];
+    nfonts = stuff->nFonts;
+    while (--nfonts >= 0)
+    {
+	if ((total == 0) || (total < (n = (*ptr + 1))))
+	    return(BadLength);
+	total -= n;
+	ptr += n;
+    }
+    if (total >= 4)
+	return(BadLength);
+    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+			 &error);
+    if (!result)
+    {
+	result = client->noClientException;
+	client->errorValue = error;
+    }
+    return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+    xGetFontPathReply reply;
+    int stringLens, numpaths;
+    unsigned char *bufferStart;
+    /* REQUEST (xReq); */
+
+    REQUEST_SIZE_MATCH(xReq);
+    bufferStart = GetFontPath(&numpaths, &stringLens);
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = (stringLens + numpaths + 3) >> 2;
+    reply.nPaths = numpaths;
+
+    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+    if (stringLens || numpaths)
+	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+    return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+    REQUEST(xSetCloseDownModeReq);
+
+    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+    if ((stuff->mode == AllTemporary) ||
+	(stuff->mode == RetainPermanent) ||
+	(stuff->mode == RetainTemporary))
+    {
+	client->closeDownMode = stuff->mode;
+	return (client->noClientException);
+    }
+    else   
+    {
+	client->errorValue = stuff->mode;
+	return (BadValue);
+    }
+}
+
+int ProcForceScreenSaver(register ClientPtr client)
+{    
+    REQUEST(xForceScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+    
+    if ((stuff->mode != ScreenSaverReset) && 
+	(stuff->mode != ScreenSaverActive))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+
+    /*
+     * The NX agent uses the screen saver procedure
+     * to monitor the user activities and launch its
+     * handlers (like timeout feature), so we can't
+     * always allow the clients to force the screen
+     * saver handler execution.
+     */
+
+    if (nxagentOption(Timeout) == 0)
+    {
+      SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+    }
+
+    #ifdef TEST
+
+    else
+    {
+      fprintf(stderr, "ProcForceScreenSaver: Ignoring the client request with mode [%d].\n",
+                  stuff -> mode);
+    }
+
+    #endif
+
+    return client->noClientException;
+}
+
+int ProcNoOperation(register ClientPtr client)
+{
+    REQUEST_AT_LEAST_SIZE(xReq);
+    
+    /* noop -- don't do anything */
+    return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+    int i;
+    for (i = 0; i<256; i++)
+    {
+	if(!ProcVector[i])
+	{
+            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+	    ReplySwapVector[i] = ReplyNotSwappd;
+	}
+#ifdef K5AUTH
+	if (!k5_Vector[i])
+	{
+	    k5_Vector[i] = k5_bad;
+	}
+#endif
+    }
+    for(i = LASTEvent; i < 128; i++)
+    {
+	EventSwapVector[i] = NotImplemented;
+    }
+    
+}
+
+/**********************
+ * CloseDownClient
+ *
+ *  Client can either mark his resources destroy or retain.  If retained and
+ *  then killed again, the client is really destroyed.
+ *********************/
+
+void
+CloseDownClient(register ClientPtr client)
+{
+    Bool really_close_down = client->clientGone ||
+			     client->closeDownMode == DestroyAll;
+
+    /*
+     * There must be a better way to hook a
+     * call-back function to be called any
+     * time a client is going to be closed.
+     */
+
+    nxagentClearClipboard(client, NULL);
+
+    /*
+     * Need to reset the karma counter and
+     * get rid of the pending sync replies.
+     */
+
+    nxagentWakeupByReset(client);
+
+    /*
+     * Check if the client
+     * is a shadow nxagent.
+     */
+
+    nxagentCheckIfShadowAgent(client);
+
+    if (!client->clientGone)
+    {
+	/* ungrab server if grabbing client dies */
+	if (grabState != GrabNone && grabClient == client)
+	{
+	    UngrabServer(client);
+	}
+	BITCLEAR(grabWaiters, client->index);
+	DeleteClientFromAnySelections(client);
+	ReleaseActiveGrabs(client);
+	DeleteClientFontStuff(client);
+	if (!really_close_down)
+	{
+	    /*  This frees resources that should never be retained
+	     *  no matter what the close down mode is.  Actually we
+	     *  could do this unconditionally, but it's probably
+	     *  better not to traverse all the client's resources
+	     *  twice (once here, once a few lines down in
+	     *  FreeClientResources) in the common case of
+	     *  really_close_down == TRUE.
+	     */
+	    FreeClientNeverRetainResources(client);
+	    client->clientState = ClientStateRetained;
+  	    if (ClientStateCallback)
+            {
+		NewClientInfoRec clientinfo;
+
+		clientinfo.client = client; 
+		clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+		clientinfo.setup = (xConnSetup *) NULL;
+		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+            } 
+	}
+	client->clientGone = TRUE;  /* so events aren't sent to client */
+	if (ClientIsAsleep(client))
+	    ClientSignal (client);
+	ProcessWorkQueueZombies();
+#ifdef LBX
+	ProcessQTagZombies();
+#endif
+	CloseDownConnection(client);
+
+	/* If the client made it to the Running stage, nClients has
+	 * been incremented on its behalf, so we need to decrement it
+	 * now.  If it hasn't gotten to Running, nClients has *not*
+	 * been incremented, so *don't* decrement it.
+	 */
+	if (client->clientState != ClientStateInitial &&
+	    client->clientState != ClientStateAuthenticating )
+	{
+	    --nClients;
+	}
+    }
+
+    if (really_close_down)
+    {
+	if (client->clientState == ClientStateRunning && nClients == 0)
+	    dispatchException |= dispatchExceptionAtReset;
+
+	client->clientState = ClientStateGone;
+	if (ClientStateCallback)
+	{
+	    NewClientInfoRec clientinfo;
+
+	    clientinfo.client = client; 
+	    clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+	    clientinfo.setup = (xConnSetup *) NULL;
+	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+	} 	    
+	FreeClientResources(client);
+	if (client->index < nextFreeClientID)
+	    nextFreeClientID = client->index;
+	clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+	SmartLastClient = NullClient;
+#endif
+	xfree(client);
+
+	while (!clients[currentMaxClients-1])
+	    currentMaxClients--;
+    }
+}
+
+static void
+KillAllClients()
+{
+    int i;
+    for (i=1; i<currentMaxClients; i++)
+        if (clients[i]) {
+            /* Make sure Retained clients are released. */
+            clients[i]->closeDownMode = DestroyAll;
+            CloseDownClient(clients[i]);     
+        }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ *    Find all clients that are gone and have terminated in RetainTemporary 
+ *    and  destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+    register int i;
+    register ClientPtr client;
+
+    for (i=1; i<currentMaxClients; i++)
+    {
+        client = clients[i];
+        if (client && (client->closeDownMode == RetainTemporary)
+	    && (client->clientGone))
+	    CloseDownClient(client);
+    }
+}
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+    client->index = i;
+    client->sequence = 0; 
+    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+    client->clientGone = FALSE;
+    if (i)
+    {
+	client->closeDownMode = DestroyAll;
+	client->lastDrawable = (DrawablePtr)WindowTable[0];
+	client->lastDrawableID = WindowTable[0]->drawable.id;
+    }
+    else
+    {
+	client->closeDownMode = RetainPermanent;
+	client->lastDrawable = (DrawablePtr)NULL;
+	client->lastDrawableID = INVALID;
+    }
+    client->lastGC = (GCPtr) NULL;
+    client->lastGCID = INVALID;
+    client->numSaved = 0;
+    client->saveSet = (SaveSetElt *)NULL;
+    client->noClientException = Success;
+#ifdef LOG_DEBUG
+    client->requestLogIndex = 0;
+#endif
+    client->requestVector = InitialVector;
+    client->osPrivate = ospriv;
+    client->swapped = FALSE;
+    client->big_requests = FALSE;
+    client->priority = 0;
+    client->clientState = ClientStateInitial;
+#ifdef XKB
+    if (!noXkbExtension) {
+	client->xkbClientFlags = 0;
+	client->mapNotifyMask = 0;
+	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+    }
+#endif
+    client->replyBytesRemaining = 0;
+#ifdef LBX
+    client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+    client->trustLevel = XSecurityClientTrusted;
+    client->CheckAccess = NULL;
+    client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+    client->appgroup = NULL;
+#endif
+    client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+    client->smart_priority = 0;
+    client->smart_start_tick = SmartScheduleTime;
+    client->smart_stop_tick = SmartScheduleTime;
+    client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(ClientPtr client)
+{
+    register char *ptr;
+    DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    if (totalClientSize == sizeof(ClientRec))
+	ppriv = (DevUnion *)NULL;
+    else if (client->index)
+	ppriv = (DevUnion *)(client + 1);
+    else
+    {
+	ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+	if (!ppriv)
+	    return 0;
+    }
+    client->devPrivates = ppriv;
+    sizes = clientPrivateSizes;
+    ptr = (char *)(ppriv + clientPrivateLen);
+    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+
+    /*
+     * Initialize the private members.
+     */
+
+    nxagentInitClientPrivates(client);
+
+    return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+    register int i;
+    register ClientPtr client;
+    xReq data;
+
+    i = nextFreeClientID;
+    if (i == MAXCLIENTS)
+	return (ClientPtr)NULL;
+    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+    if (!client)
+	return (ClientPtr)NULL;
+    InitClient(client, i, ospriv);
+    InitClientPrivates(client);
+    if (!InitClientResources(client))
+    {
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    data.reqType = 1;
+    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+    {
+	FreeClientResources(client);
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    if (i == currentMaxClients)
+	currentMaxClients++;
+    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+	nextFreeClientID++;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+        clientinfo.setup = (xConnSetup *) NULL;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+    REQUEST(xReq);
+    register xConnClientPrefix *prefix;
+    int whichbyte = 1;
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+	return (client->noClientException = -1);
+    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+    {
+	client->swapped = TRUE;
+	SwapConnClientPrefix(prefix);
+    }
+    stuff->reqType = 2;
+    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+    if (client->swapped)
+    {
+	swaps(&stuff->length, whichbyte);
+    }
+    ResetCurrentRequest(client);
+    return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+    nClients++;
+}
+#endif
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+    register xWindowRoot *root;
+    register int i;
+    int numScreens;
+    char* lConnectionInfo;
+    xConnSetupPrefix* lconnSetupPrefix;
+
+    if (reason)
+    {
+	xConnSetupPrefix csp;
+
+	csp.success = xFalse;
+	csp.lengthReason = strlen(reason);
+	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+	csp.majorVersion = X_PROTOCOL;
+	csp.minorVersion = X_PROTOCOL_REVISION;
+	if (client->swapped)
+	    WriteSConnSetupPrefix(client, &csp);
+	else
+	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+        (void)WriteToClient(client, (int)csp.lengthReason, reason);
+	return (client->noClientException = -1);
+    }
+
+    numScreens = screenInfo.numScreens;
+    lConnectionInfo = ConnectionInfo;
+    lconnSetupPrefix = &connSetupPrefix;
+
+    /* We're about to start speaking X protocol back to the client by
+     * sending the connection setup info.  This means the authorization
+     * step is complete, and we can count the client as an
+     * authorized one.
+     */
+    nClients++;
+
+    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+    client->sequence = 0;
+#ifdef XAPPGROUP
+    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+    /* fill in the "currentInputMask" */
+    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+    for (i=0; i<numScreens; i++) 
+    {
+	register unsigned int j;
+	register xDepth *pDepth;
+
+        root->currentInputMask = WindowTable[i]->eventMask |
+			         wOtherEventMasks (WindowTable[i]);
+	pDepth = (xDepth *)(root + 1);
+	for (j = 0; j < root->nDepths; j++)
+	{
+	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+				pDepth->nVisuals * sizeof(xVisualType));
+	}
+	root = (xWindowRoot *)pDepth;
+    }
+
+    if (client->swapped)
+    {
+	WriteSConnSetupPrefix(client, lconnSetupPrefix);
+	WriteSConnectionInfo(client,
+			     (unsigned long)(lconnSetupPrefix->length << 2),
+			     lConnectionInfo);
+    }
+    else
+    {
+	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
+			    (char *) lconnSetupPrefix);
+	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+			    lConnectionInfo);
+    }
+    client->clientState = ClientStateRunning;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = lconnSetupPrefix;  
+        clientinfo.setup = (xConnSetup *)lConnectionInfo;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+    char *reason, *auth_proto, *auth_string;
+    register xConnClientPrefix *prefix;
+    REQUEST(xReq);
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    auth_proto = (char *)prefix + sz_xConnClientPrefix;
+    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+    if ((prefix->majorVersion != X_PROTOCOL) ||
+	(prefix->minorVersion != X_PROTOCOL_REVISION))
+	reason = "Protocol version mismatch";
+    else
+	reason = ClientAuthorized(client,
+				  (unsigned short)prefix->nbytesAuthProto,
+				  auth_proto,
+				  (unsigned short)prefix->nbytesAuthString,
+				  auth_string);
+    /*
+     * If Kerberos is being used for this client, the clientState
+     * will be set to ClientStateAuthenticating at this point.
+     * More messages need to be exchanged among the X server, Kerberos
+     * server, and client to figure out if everyone is authorized.
+     * So we don't want to send the connection setup info yet, since
+     * the auth step isn't really done.
+     */
+    if (client->clientState == ClientStateCheckingSecurity)
+	client->clientState = ClientStateCheckedSecurity;
+    else if (client->clientState != ClientStateAuthenticating)
+	return(SendConnSetup(client, reason));
+    return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 
+                  XID resId, int errorCode)
+{
+    xError rep;
+
+    rep.type = X_Error;
+    rep.sequenceNumber = client->sequence;
+    rep.errorCode = errorCode;
+    rep.majorCode = majorCode;
+    rep.minorCode = minorCode;
+    rep.resourceID = resId;
+
+    WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].pWin == pWin)
+        {
+	    if (SelectionCallback)
+	    {
+	        SelectionInfoRec    info;
+
+		info.selection = &CurrentSelections[i];
+		info.kind = SelectionWindowDestroy;
+		CallCallbacks(&SelectionCallback, &info);
+	    }
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].client == client)
+        {
+	    if (SelectionCallback)
+	    {
+	        SelectionInfoRec    info;
+
+		info.selection = &CurrentSelections[i];
+		info.kind = SelectionWindowDestroy;
+		CallCallbacks(&SelectionCallback, &info);
+	    }
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+    client->noClientException = -1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original
new file mode 100644
index 000000000..6941456de
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.X.original
@@ -0,0 +1,4035 @@
+/* $XdotOrg: xc/programs/Xserver/dix/dispatch.c,v 1.13 2005/09/13 01:33:19 daniels Exp $ */
+/* $Xorg: dispatch.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/************************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/dispatch.c,v 3.32 2003/11/10 18:21:45 tsi Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XKB
+#define XKB_IN_SERVER
+#include "inputstr.h"
+#include <X11/extensions/XKBsrv.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+
+Selection *CurrentSelections;
+int NumCurrentSelections;
+CallbackListPtr SelectionCallback = NULL;
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+extern int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static void DeleteClientFromAnySelections(ClientPtr client);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int	nClients;	/* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue;   /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+    (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+    checkForInput[0] = c0;
+    checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime()
+{
+    TimeStamp systime;
+
+    /* To avoid time running backwards, we must call GetTimeInMillis before
+     * calling ProcessInputEvents.
+     */
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] != *checkForInput[1])
+	ProcessInputEvents();
+    if (CompareTimeStamps(systime, currentTime) == LATER)
+	currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf()
+{
+    TimeStamp systime;
+
+    systime.months = currentTime.months;
+    systime.milliseconds = GetTimeInMillis();
+    if (systime.milliseconds < currentTime.milliseconds)
+	systime.months++;
+    if (*checkForInput[0] == *checkForInput[1])
+	currentTime = systime;
+}
+
+void
+InitSelections()
+{
+    if (CurrentSelections)
+	xfree(CurrentSelections);
+    CurrentSelections = (Selection *)NULL;
+    NumCurrentSelections = 0;
+}
+
+void 
+FlushClientCaches(XID id)
+{
+    int i;
+    register ClientPtr client;
+
+    client = clients[CLIENT_ID(id)];
+    if (client == NullClient)
+        return ;
+    for (i=0; i<currentMaxClients; i++)
+    {
+	client = clients[i];
+        if (client != NullClient)
+	{
+            if (client->lastDrawableID == id)
+	    {
+		client->lastDrawableID = WindowTable[0]->drawable.id;
+		client->lastDrawable = (DrawablePtr)WindowTable[0];
+	    }
+            else if (client->lastGCID == id)
+	    {
+                client->lastGCID = INVALID;
+		client->lastGC = (GCPtr)NULL;
+	    }
+	}
+    }
+}
+#ifdef SMART_SCHEDULE
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL	20	    /* ms */
+#define SMART_SCHEDULE_MAX_SLICE	200	    /* ms */
+
+Bool	    SmartScheduleDisable = FALSE;
+long	    SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long	    SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long	    SmartScheduleTime;
+ClientPtr   SmartLastClient;
+int	    SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+int         SmartScheduleClient(int *clientReady, int nready);
+
+#ifdef SMART_DEBUG
+long	    SmartLastPrint;
+#endif
+
+void        Dispatch(void);
+void        InitProcVectors(void);
+
+int
+SmartScheduleClient (int *clientReady, int nready)
+{
+    ClientPtr	pClient;
+    int		i;
+    int		client;
+    int		bestPrio, best = 0;
+    int		bestRobin, robin;
+    long	now = SmartScheduleTime;
+    long	idle;
+
+    bestPrio = -0x7fffffff;
+    bestRobin = 0;
+    idle = 2 * SmartScheduleSlice;
+    for (i = 0; i < nready; i++)
+    {
+	client = clientReady[i];
+	pClient = clients[client];
+	/* Praise clients which are idle */
+	if ((now - pClient->smart_check_tick) >= idle)
+	{
+	    if (pClient->smart_priority < 0)
+		pClient->smart_priority++;
+	}
+	pClient->smart_check_tick = now;
+	
+	/* check priority to select best client */
+	robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+	if (pClient->smart_priority > bestPrio ||
+	    (pClient->smart_priority == bestPrio && robin > bestRobin))
+	{
+	    bestPrio = pClient->smart_priority;
+	    bestRobin = robin;
+	    best = client;
+	}
+#ifdef SMART_DEBUG
+	if ((now - SmartLastPrint) >= 5000)
+	    fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+    }
+#ifdef SMART_DEBUG
+    if ((now - SmartLastPrint) >= 5000)
+    {
+	fprintf (stderr, " use %2d\n", best);
+	SmartLastPrint = now;
+    }
+#endif
+    pClient = clients[best];
+    SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+    /*
+     * Set current client pointer
+     */
+    if (SmartLastClient != pClient)
+    {
+	pClient->smart_start_tick = now;
+	SmartLastClient = pClient;
+    }
+    /*
+     * Adjust slice
+     */
+    if (nready == 1)
+    {
+	/*
+	 * If it's been a long time since another client
+	 * has run, bump the slice up to get maximal
+	 * performance from a single client
+	 */
+	if ((now - pClient->smart_start_tick) > 1000 &&
+	    SmartScheduleSlice < SmartScheduleMaxSlice)
+	{
+	    SmartScheduleSlice += SmartScheduleInterval;
+	}
+    }
+    else
+    {
+	SmartScheduleSlice = SmartScheduleInterval;
+    }
+    return best;
+}
+#endif
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+    register int        *clientReady;     /* array of request ready clients */
+    register int	result;
+    register ClientPtr	client;
+    register int	nready;
+    register HWEventQueuePtr* icheck = checkForInput;
+#ifdef SMART_SCHEDULE
+    long			start_tick;
+#endif
+
+    nextFreeClientID = 1;
+    InitSelections();
+    nClients = 0;
+
+    clientReady = (int *) ALLOCATE_LOCAL(sizeof(int) * MaxClients);
+    if (!clientReady)
+	return;
+
+    while (!dispatchException)
+    {
+        if (*icheck[0] != *icheck[1])
+	{
+	    ProcessInputEvents();
+	    FlushIfCriticalOutputPending();
+	}
+
+	nready = WaitForSomething(clientReady);
+
+#ifdef SMART_SCHEDULE
+	if (nready && !SmartScheduleDisable)
+	{
+	    clientReady[0] = SmartScheduleClient (clientReady, nready);
+	    nready = 1;
+	}
+#endif
+       /***************** 
+	*  Handle events in round robin fashion, doing input between 
+	*  each round 
+	*****************/
+
+	while (!dispatchException && (--nready >= 0))
+	{
+	    client = clients[clientReady[nready]];
+	    if (! client)
+	    {
+		/* KillClient can cause this to happen */
+		continue;
+	    }
+	    /* GrabServer activation can cause this to be true */
+	    if (grabState == GrabKickout)
+	    {
+		grabState = GrabActive;
+		break;
+	    }
+	    isItTimeToYield = FALSE;
+ 
+            requestingClient = client;
+#ifdef SMART_SCHEDULE
+	    start_tick = SmartScheduleTime;
+#endif
+	    while (!isItTimeToYield)
+	    {
+	        if (*icheck[0] != *icheck[1])
+		{
+		    ProcessInputEvents();
+		    FlushIfCriticalOutputPending();
+		}
+#ifdef SMART_SCHEDULE
+		if (!SmartScheduleDisable && 
+		    (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+		{
+		    /* Penalize clients which consume ticks */
+		    if (client->smart_priority > SMART_MIN_PRIORITY)
+			client->smart_priority--;
+		    break;
+		}
+#endif
+		/* now, finally, deal with client requests */
+
+	        result = ReadRequestFromClient(client);
+	        if (result <= 0) 
+	        {
+		    if (result < 0)
+			CloseDownClient(client);
+		    break;
+	        }
+
+		client->sequence++;
+#ifdef DEBUG
+		if (client->requestLogIndex == MAX_REQUEST_LOG)
+		    client->requestLogIndex = 0;
+		client->requestLog[client->requestLogIndex] = MAJOROP;
+		client->requestLogIndex++;
+#endif
+		if (result > (maxBigRequestSize << 2))
+		    result = BadLength;
+		else
+		    result = (* client->requestVector[MAJOROP])(client);
+	    
+		if (result != Success) 
+		{
+		    if (client->noClientException != Success)
+                        CloseDownClient(client);
+                    else
+		        SendErrorToClient(client, MAJOROP,
+					  MinorOpcodeOfRequest(client),
+					  client->errorValue, result);
+		    break;
+	        }
+#ifdef DAMAGEEXT
+		FlushIfCriticalOutputPending ();
+#endif
+	    }
+	    FlushAllOutput();
+#ifdef SMART_SCHEDULE
+	    client = clients[clientReady[nready]];
+	    if (client)
+		client->smart_stop_tick = SmartScheduleTime;
+#endif
+	    requestingClient = NULL;
+	}
+	dispatchException &= ~DE_PRIORITYCHANGE;
+    }
+#if defined(DDXBEFORERESET)
+    ddxBeforeReset ();
+#endif
+    KillAllClients();
+    DEALLOCATE_LOCAL(clientReady);
+    dispatchException &= ~DE_RESET;
+}
+
+#undef MAJOROP
+
+int
+ProcBadRequest(ClientPtr client)
+{
+    return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+    register WindowPtr pParent, pWin;
+    REQUEST(xCreateWindowReq);
+    int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+    
+    LEGAL_NEW_RESOURCE(stuff->wid, client);
+    if (!(pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+						    SecurityWriteAccess)))
+        return BadWindow;
+    len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+    if (Ones(stuff->mask) != len)
+        return BadLength;
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+			      stuff->y, stuff->width, stuff->height, 
+			      stuff->borderWidth, stuff->class,
+			      stuff->mask, (XID *) &stuff[1], 
+			      (int)stuff->depth, 
+			      client, stuff->visual, &result);
+    if (pWin)
+    {
+	Mask mask = pWin->eventMask;
+
+	pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+	if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+	    return BadAlloc;
+	pWin->eventMask = mask;
+    }
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcChangeWindowAttributes(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeWindowAttributesReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+    if (len != Ones(stuff->valueMask))
+        return BadLength;
+    result =  ChangeWindowAttributes(pWin, 
+				  stuff->valueMask, 
+				  (XID *) &stuff[1], 
+				  client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcGetWindowAttributes(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+    xGetWindowAttributesReply wa;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    GetWindowAttributes(pWin, client, &wa);
+    WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+    return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->parent)
+	FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityDestroyAccess);
+    if (!pWin)
+        return(BadWindow);
+    DestroySubwindows(pWin, client);
+    return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xChangeSaveSetReq);
+    register int result;
+		  
+    REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+        return BadMatch;
+    if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+    {
+        result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->mode;
+	return( BadValue );
+    }
+}
+
+int
+ProcReparentWindow(register ClientPtr client)
+{
+    register WindowPtr pWin, pParent;
+    REQUEST(xReparentWindowReq);
+    register int result;
+
+    REQUEST_SIZE_MATCH(xReparentWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    pParent = (WindowPtr)SecurityLookupWindow(stuff->parent, client,
+					      SecurityWriteAccess);
+    if (!pParent)
+        return(BadWindow);
+    if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+    {
+        if ((pWin->backgroundState == ParentRelative) &&
+            (pParent->drawable.depth != pWin->drawable.depth))
+            return BadMatch;
+	if ((pWin->drawable.class != InputOnly) &&
+	    (pParent->drawable.class == InputOnly))
+	    return BadMatch;
+        result =  ReparentWindow(pWin, pParent, 
+			 (short)stuff->x, (short)stuff->y, client);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else 
+        return (BadMatch);
+}
+
+int
+ProcMapWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapWindow(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    MapSubwindows(pWin, client);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapWindow(pWin, FALSE);
+           /* update cache to say it is mapped */
+    return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->id, client,
+					    SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    UnmapSubwindows(pWin);
+    return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xConfigureWindowReq);
+    register int result;
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+    pWin = (WindowPtr)SecurityLookupWindow( stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+    if (Ones((Mask)stuff->mask) != len)
+        return BadLength;
+    result =  ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 
+			      client);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcCirculateWindow(register ClientPtr client)
+{
+    register WindowPtr pWin;
+    REQUEST(xCirculateWindowReq);
+
+    REQUEST_SIZE_MATCH(xCirculateWindowReq);
+    if ((stuff->direction != RaiseLowest) &&
+	(stuff->direction != LowerHighest))
+    {
+	client->errorValue = stuff->direction;
+        return BadValue;
+    }
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    CirculateWindow(pWin, (int)stuff->direction, client);
+    return(client->noClientException);
+}
+
+int
+GetGeometry(register ClientPtr client, xGetGeometryReply *rep)
+{
+    register DrawablePtr pDraw;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->id, client, SecurityReadAccess);
+    rep->type = X_Reply;
+    rep->length = 0;
+    rep->sequenceNumber = client->sequence;
+    rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+    rep->depth = pDraw->depth;
+    rep->width = pDraw->width;
+    rep->height = pDraw->height;
+
+    /* XXX - Because the pixmap-implementation of the multibuffer extension 
+     *       may have the buffer-id's drawable resource value be a pointer
+     *       to the buffer's window instead of the buffer itself
+     *       (this happens if the buffer is the displayed buffer),
+     *       we also have to check that the id matches before we can
+     *       truly say that it is a DRAWABLE_WINDOW.
+     */
+
+    if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+        ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+    {
+        register WindowPtr pWin = (WindowPtr)pDraw;
+	rep->x = pWin->origin.x - wBorderWidth (pWin);
+	rep->y = pWin->origin.y - wBorderWidth (pWin);
+	rep->borderWidth = pWin->borderWidth;
+    }
+    else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+    {
+	rep->x = rep->y = rep->borderWidth = 0;
+    }
+
+    return Success;
+}
+
+
+int
+ProcGetGeometry(register ClientPtr client)
+{
+    xGetGeometryReply rep;
+    int status;
+
+    if ((status = GetGeometry(client, &rep)) != Success)
+	return status;
+
+    WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+    return(client->noClientException);
+}
+
+
+int
+ProcQueryTree(register ClientPtr client)
+{
+    xQueryTreeReply reply;
+    int numChildren = 0;
+    register WindowPtr pChild, pWin, pHead;
+    Window  *childIDs = (Window *)NULL;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    reply.type = X_Reply;
+    reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+    reply.sequenceNumber = client->sequence;
+    if (pWin->parent)
+	reply.parent = pWin->parent->drawable.id;
+    else
+        reply.parent = (Window)None;
+    pHead = RealChildHead(pWin);
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+	numChildren++;
+    if (numChildren)
+    {
+	int curChild = 0;
+
+	childIDs = (Window *) ALLOCATE_LOCAL(numChildren * sizeof(Window));
+	if (!childIDs)
+	    return BadAlloc;
+	for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+	    childIDs[curChild++] = pChild->drawable.id;
+    }
+    
+    reply.nChildren = numChildren;
+    reply.length = (numChildren * sizeof(Window)) >> 2;
+    
+    WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+    if (numChildren)
+    {
+    	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+	DEALLOCATE_LOCAL(childIDs);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcInternAtom(register ClientPtr client)
+{
+    Atom atom;
+    char *tchar;
+    REQUEST(xInternAtomReq);
+
+    REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+    if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+    {
+	client->errorValue = stuff->onlyIfExists;
+        return(BadValue);
+    }
+    tchar = (char *) &stuff[1];
+    atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+    if (atom != BAD_RESOURCE)
+    {
+	xInternAtomReply reply;
+	reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+	reply.atom = atom;
+	WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+	return(client->noClientException);
+    }
+    else
+	return (BadAlloc);
+}
+
+int
+ProcGetAtomName(register ClientPtr client)
+{
+    char *str;
+    xGetAtomNameReply reply;
+    int len;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if ( (str = NameForAtom(stuff->id)) )
+    {
+	len = strlen(str);
+	reply.type = X_Reply;
+	reply.length = (len + 3) >> 2;
+	reply.sequenceNumber = client->sequence;
+	reply.nameLength = len;
+	WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+	(void)WriteToClient(client, len, str);
+	return(client->noClientException);
+    }
+    else 
+    { 
+	client->errorValue = stuff->id;
+	return (BadAtom);
+    }
+}
+
+#ifdef K5AUTH
+extern int k5_bad();
+#endif
+
+int
+ProcSetSelectionOwner(register ClientPtr client)
+{
+    WindowPtr pWin;
+    TimeStamp time;
+    REQUEST(xSetSelectionOwnerReq);
+
+    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+    UpdateCurrentTime();
+    time = ClientTimeToServerTime(stuff->time);
+
+    /* If the client's time stamp is in the future relative to the server's
+	time stamp, do not set the selection, just return success. */
+    if (CompareTimeStamps(time, currentTime) == LATER)
+    	return Success;
+    if (stuff->window != None)
+    {
+        pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					       SecurityReadAccess);
+        if (!pWin)
+            return(BadWindow);
+    }
+    else
+        pWin = (WindowPtr)None;
+    if (ValidAtom(stuff->selection))
+    {
+	int i = 0;
+
+	/*
+	 * First, see if the selection is already set... 
+	 */
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) 
+            i++;
+        if (i < NumCurrentSelections)
+        {        
+	    xEvent event;
+
+	    /* If the timestamp in client's request is in the past relative
+		to the time stamp indicating the last time the owner of the
+		selection was set, do not set the selection, just return 
+		success. */
+            if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
+		== EARLIER)
+		return Success;
+	    if (CurrentSelections[i].client &&
+		(!pWin || (CurrentSelections[i].client != client)))
+	    {
+		event.u.u.type = SelectionClear;
+		event.u.selectionClear.time = time.milliseconds;
+		event.u.selectionClear.window = CurrentSelections[i].window;
+		event.u.selectionClear.atom = CurrentSelections[i].selection;
+		(void) TryClientEvents (CurrentSelections[i].client, &event, 1,
+				NoEventMask, NoEventMask /* CantBeFiltered */,
+				NullGrab);
+	    }
+	}
+	else
+	{
+	    /*
+	     * It doesn't exist, so add it...
+	     */
+	    Selection *newsels;
+
+	    if (i == 0)
+		newsels = (Selection *)xalloc(sizeof(Selection));
+	    else
+		newsels = (Selection *)xrealloc(CurrentSelections,
+			    (NumCurrentSelections + 1) * sizeof(Selection));
+	    if (!newsels)
+		return BadAlloc;
+	    NumCurrentSelections++;
+	    CurrentSelections = newsels;
+	    CurrentSelections[i].selection = stuff->selection;
+	}
+        CurrentSelections[i].lastTimeChanged = time;
+	CurrentSelections[i].window = stuff->window;
+	CurrentSelections[i].pWin = pWin;
+	CurrentSelections[i].client = (pWin ? client : NullClient);
+	if (SelectionCallback)
+	{
+	    SelectionInfoRec	info;
+
+	    info.selection = &CurrentSelections[i];
+	    info.kind= SelectionSetOwner;
+	    CallCallbacks(&SelectionCallback, &info);
+	}
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->selection;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGetSelectionOwner(register ClientPtr client)
+{
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (ValidAtom(stuff->id))
+    {
+	int i;
+        xGetSelectionOwnerReply reply;
+
+	i = 0;
+        while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->id) i++;
+        reply.type = X_Reply;
+	reply.length = 0;
+	reply.sequenceNumber = client->sequence;
+        if (i < NumCurrentSelections)
+            reply.owner = CurrentSelections[i].window;
+        else
+            reply.owner = None;
+        WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
+        return(client->noClientException);
+    }
+    else            
+    {
+	client->errorValue = stuff->id;
+        return (BadAtom); 
+    }
+}
+
+int
+ProcConvertSelection(register ClientPtr client)
+{
+    Bool paramsOkay;
+    xEvent event;
+    WindowPtr pWin;
+    REQUEST(xConvertSelectionReq);
+
+    REQUEST_SIZE_MATCH(xConvertSelectionReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->requestor, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
+    if (stuff->property != None)
+	paramsOkay &= ValidAtom(stuff->property);
+    if (paramsOkay)
+    {
+	int i;
+
+	i = 0;
+	while ((i < NumCurrentSelections) && 
+	       CurrentSelections[i].selection != stuff->selection) i++;
+	if ((i < NumCurrentSelections) && 
+	    (CurrentSelections[i].window != None)
+#ifdef XCSECURITY
+	    && (!client->CheckAccess ||
+		(* client->CheckAccess)(client, CurrentSelections[i].window,
+					RT_WINDOW, SecurityReadAccess,
+					CurrentSelections[i].pWin))
+#endif
+	    )
+	{        
+	    event.u.u.type = SelectionRequest;
+	    event.u.selectionRequest.time = stuff->time;
+	    event.u.selectionRequest.owner = 
+			CurrentSelections[i].window;
+	    event.u.selectionRequest.requestor = stuff->requestor;
+	    event.u.selectionRequest.selection = stuff->selection;
+	    event.u.selectionRequest.target = stuff->target;
+	    event.u.selectionRequest.property = stuff->property;
+	    if (TryClientEvents(
+		CurrentSelections[i].client, &event, 1, NoEventMask,
+		NoEventMask /* CantBeFiltered */, NullGrab))
+		return (client->noClientException);
+	}
+	event.u.u.type = SelectionNotify;
+	event.u.selectionNotify.time = stuff->time;
+	event.u.selectionNotify.requestor = stuff->requestor;
+	event.u.selectionNotify.selection = stuff->selection;
+	event.u.selectionNotify.target = stuff->target;
+	event.u.selectionNotify.property = None;
+	(void) TryClientEvents(client, &event, 1, NoEventMask,
+			       NoEventMask /* CantBeFiltered */, NullGrab);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->property;
+        return (BadAtom);
+    }
+}
+
+int
+ProcGrabServer(register ClientPtr client)
+{
+    REQUEST_SIZE_MATCH(xReq);
+    if (grabState != GrabNone && client != grabClient)
+    {
+	ResetCurrentRequest(client);
+	client->sequence--;
+	BITSET(grabWaiters, client->index);
+	IgnoreClient(client);
+	return(client->noClientException);
+    }
+    OnlyListenToOneClient(client);
+    grabState = GrabKickout;
+    grabClient = client;
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_GRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+
+    return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+    int i;
+
+    grabState = GrabNone;
+    ListenToAllClients();
+    for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+	;
+    if (i >= 0)
+    {
+	i <<= 5;
+	while (!GETBIT(grabWaiters, i))
+	    i++;
+	BITCLEAR(grabWaiters, i);
+	AttendClient(clients[i]);
+    }
+
+    if (ServerGrabCallback)
+    {
+	ServerGrabInfoRec grabinfo;
+	grabinfo.client = client;
+	grabinfo.grabstate  = SERVER_UNGRABBED;
+	CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+    }
+}
+
+int
+ProcUngrabServer(register ClientPtr client)
+{
+    REQUEST_SIZE_MATCH(xReq);
+    UngrabServer(client);
+    return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(register ClientPtr client)
+{
+    REQUEST(xTranslateCoordsReq);
+
+    register WindowPtr pWin, pDst;
+    xTranslateCoordsReply rep;
+
+    REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->srcWid, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+    pDst = (WindowPtr)SecurityLookupWindow(stuff->dstWid, client,
+					   SecurityReadAccess);
+    if (!pDst)
+        return(BadWindow);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+    {
+	rep.sameScreen = xFalse;
+        rep.child = None;
+	rep.dstX = rep.dstY = 0;
+    }
+    else
+    {
+	INT16 x, y;
+	rep.sameScreen = xTrue;
+	rep.child = None;
+	/* computing absolute coordinates -- adjust to destination later */
+	x = pWin->drawable.x + stuff->srcX;
+	y = pWin->drawable.y + stuff->srcY;
+	pWin = pDst->firstChild;
+	while (pWin)
+	{
+#ifdef SHAPE
+	    BoxRec  box;
+#endif
+	    if ((pWin->mapped) &&
+		(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+		(x < pWin->drawable.x + (int)pWin->drawable.width +
+		 wBorderWidth (pWin)) &&
+		(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+		(y < pWin->drawable.y + (int)pWin->drawable.height +
+		 wBorderWidth (pWin))
+#ifdef SHAPE
+		/* When a window is shaped, a further check
+		 * is made to see if the point is inside
+		 * borderSize
+		 */
+		&& (!wBoundingShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen, 
+					&pWin->borderSize, x, y, &box))
+		
+		&& (!wInputShape(pWin) ||
+		    POINT_IN_REGION(pWin->drawable.pScreen,
+				    wInputShape(pWin),
+				    x - pWin->drawable.x,
+				    y - pWin->drawable.y, &box))
+#endif
+		)
+            {
+		rep.child = pWin->drawable.id;
+		pWin = (WindowPtr) NULL;
+	    }
+	    else
+		pWin = pWin->nextSib;
+	}
+	/* adjust to destination coordinates */
+	rep.dstX = x - pDst->drawable.x;
+	rep.dstY = y - pDst->drawable.y;
+    }
+    WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+    return(client->noClientException);
+}
+
+int
+ProcOpenFont(register ClientPtr client)
+{
+    int	err;
+    REQUEST(xOpenFontReq);
+
+    REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+    client->errorValue = stuff->fid;
+    LEGAL_NEW_RESOURCE(stuff->fid, client);
+    err = OpenFont(client, stuff->fid, (Mask) 0,
+		stuff->nbytes, (char *)&stuff[1]);
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcCloseFont(register ClientPtr client)
+{
+    FontPtr pFont;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityDestroyAccess);
+    if ( pFont != (FontPtr)NULL)	/* id was valid */
+    {
+        FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+        return (BadFont);
+    }
+}
+
+int
+ProcQueryFont(register ClientPtr client)
+{
+    xQueryFontReply	*reply;
+    FontPtr pFont;
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    client->errorValue = stuff->id;		/* EITHER font or gc */
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+	  /* can't use VERIFY_GC because it might return BadGC */
+	pGC = (GC *) SecurityLookupIDByType(client, stuff->id, RT_GC,
+					    SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->id;
+            return(BadFont);     /* procotol spec says only error is BadFont */
+	}
+	pFont = pGC->font;
+    }
+
+    {
+	xCharInfo	*pmax = FONTINKMAX(pFont);
+	xCharInfo	*pmin = FONTINKMIN(pFont);
+	int		nprotoxcistructs;
+	int		rlength;
+
+	nprotoxcistructs = (
+	   pmax->rightSideBearing == pmin->rightSideBearing &&
+	   pmax->leftSideBearing == pmin->leftSideBearing &&
+	   pmax->descent == pmin->descent &&
+	   pmax->ascent == pmin->ascent &&
+	   pmax->characterWidth == pmin->characterWidth) ?
+		0 : N2dChars(pFont);
+
+	rlength = sizeof(xQueryFontReply) +
+	             FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp)  +
+		     nprotoxcistructs * sizeof(xCharInfo);
+	reply = (xQueryFontReply *)ALLOCATE_LOCAL(rlength);
+	if(!reply)
+	{
+	    return(BadAlloc);
+	}
+
+	reply->type = X_Reply;
+	reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+	reply->sequenceNumber = client->sequence;
+	QueryFont( pFont, reply, nprotoxcistructs);
+
+        WriteReplyToClient(client, rlength, reply);
+	DEALLOCATE_LOCAL(reply);
+	return(client->noClientException);
+    }
+}
+
+int
+ProcQueryTextExtents(register ClientPtr client)
+{
+    REQUEST(xQueryTextExtentsReq);
+    xQueryTextExtentsReply reply;
+    FontPtr pFont;
+    GC *pGC;
+    ExtentInfoRec info;
+    unsigned long length;
+
+    REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+        
+    pFont = (FontPtr)SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+					    SecurityReadAccess);
+    if (!pFont)
+    {
+        pGC = (GC *)SecurityLookupIDByType(client, stuff->fid, RT_GC,
+					   SecurityReadAccess);
+        if (!pGC)
+	{
+	    client->errorValue = stuff->fid;
+            return(BadFont);
+	}
+	pFont = pGC->font;
+    }
+    length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+    length = length << 1;
+    if (stuff->oddLength)
+    {
+	if (length == 0)
+	    return(BadLength);
+        length--;
+    }
+    if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+	return(BadAlloc);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.drawDirection = info.drawDirection;
+    reply.fontAscent = info.fontAscent;
+    reply.fontDescent = info.fontDescent;
+    reply.overallAscent = info.overallAscent;
+    reply.overallDescent = info.overallDescent;
+    reply.overallWidth = info.overallWidth;
+    reply.overallLeft = info.overallLeft;
+    reply.overallRight = info.overallRight;
+    WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListFonts(register ClientPtr client)
+{
+    REQUEST(xListFontsReq);
+
+    REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+
+    return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 
+	stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(register ClientPtr client)
+{
+    REQUEST(xListFontsWithInfoReq);
+
+    REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+    return StartListFontsWithInfo(client, stuff->nbytes,
+				  (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+    PixmapPtr pPixmap = (PixmapPtr)value;
+    return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(register ClientPtr client)
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    REQUEST(xCreatePixmapReq);
+    DepthPtr pDepth;
+    register int i;
+
+    REQUEST_SIZE_MATCH(xCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->width > 32767 || stuff->height > 32767)
+    {
+	/* It is allowed to try and allocate a pixmap which is larger than
+	 * 32767 in either dimension. However, all of the framebuffer code
+	 * is buggy and does not reliably draw to such big pixmaps, basically
+	 * because the Region data structure operates with signed shorts
+	 * for the rectangles in it.
+	 *
+	 * Furthermore, several places in the X server computes the
+	 * size in bytes of the pixmap and tries to store it in an
+	 * integer. This integer can overflow and cause the allocated size
+	 * to be much smaller.
+	 *
+	 * So, such big pixmaps are rejected here with a BadAlloc
+	 */
+	return BadAlloc;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+		(pDraw->pScreen, stuff->width,
+		 stuff->height, stuff->depth);
+    if (pMap)
+    {
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	    return(client->noClientException);
+    }
+    return (BadAlloc);
+}
+
+int
+ProcFreePixmap(register ClientPtr client)
+{
+    PixmapPtr pMap;
+
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pMap = (PixmapPtr)SecurityLookupIDByType(client, stuff->id, RT_PIXMAP,
+					     SecurityDestroyAccess);
+    if (pMap) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return(client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadPixmap);
+    }
+}
+
+int
+ProcCreateGC(register ClientPtr client)
+{
+    int error;
+    GC *pGC;
+    register DrawablePtr pDraw;
+    unsigned len;
+    REQUEST(xCreateGCReq);
+
+    REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+    client->errorValue = stuff->gc;
+    LEGAL_NEW_RESOURCE(stuff->gc, client);
+    SECURITY_VERIFY_DRAWABLE (pDraw, stuff->drawable, client,
+			      SecurityReadAccess);
+    len = client->req_len -  (sizeof(xCreateGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+    pGC = (GC *)CreateGC(pDraw, stuff->mask, 
+			 (XID *) &stuff[1], &error);
+    if (error != Success)
+        return error;
+    if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+	return (BadAlloc);
+    return(client->noClientException);
+}
+
+int
+ProcChangeGC(register ClientPtr client)
+{
+    GC *pGC;
+    REQUEST(xChangeGCReq);
+    int result;
+    unsigned len;
+		
+    REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+    SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityWriteAccess);
+    len = client->req_len -  (sizeof(xChangeGCReq) >> 2);
+    if (len != Ones(stuff->mask))
+        return BadLength;
+
+    result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcCopyGC(register ClientPtr client)
+{
+    register GC *dstGC;
+    register GC *pGC;
+    int result;
+    REQUEST(xCopyGCReq);
+
+    REQUEST_SIZE_MATCH(xCopyGCReq);
+    SECURITY_VERIFY_GC( pGC, stuff->srcGC, client, SecurityReadAccess);
+    SECURITY_VERIFY_GC( dstGC, stuff->dstGC, client, SecurityWriteAccess);
+    if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+        return (BadMatch);    
+    result = CopyGC(pGC, dstGC, stuff->mask);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetDashes(register ClientPtr client)
+{
+    register GC *pGC;
+    int result;
+    REQUEST(xSetDashesReq);
+
+    REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+    if (stuff->nDashes == 0)
+    {
+	 client->errorValue = 0;
+         return BadValue;
+    }
+
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+
+    result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+		       (unsigned char *)&stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+    {
+	client->errorValue = clientErrorValue;
+        return(result);
+    }
+}
+
+int
+ProcSetClipRectangles(register ClientPtr client)
+{
+    int	nr;
+    int result;
+    register GC *pGC;
+    REQUEST(xSetClipRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+	(stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+    {
+	client->errorValue = stuff->ordering;
+        return BadValue;
+    }
+    SECURITY_VERIFY_GC(pGC,stuff->gc, client, SecurityWriteAccess);
+		 
+    nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+    if (nr & 4)
+	return(BadLength);
+    nr >>= 3;
+    result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+			  nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+int
+ProcFreeGC(register ClientPtr client)
+{
+    register GC *pGC;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    SECURITY_VERIFY_GC(pGC, stuff->id, client, SecurityDestroyAccess);
+    FreeResource(stuff->id, RT_NONE);
+    return(client->noClientException);
+}
+
+int
+ProcClearToBackground(register ClientPtr client)
+{
+    REQUEST(xClearAreaReq);
+    register WindowPtr pWin;
+
+    REQUEST_SIZE_MATCH(xClearAreaReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (pWin->drawable.class == InputOnly)
+    {
+	client->errorValue = stuff->window;
+	return (BadMatch);
+    }		    
+    if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+    {
+	client->errorValue = stuff->exposures;
+        return(BadValue);
+    }
+    (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+			       stuff->width, stuff->height,
+			       (Bool)stuff->exposures);
+    return(client->noClientException);
+}
+
+int
+ProcCopyArea(register ClientPtr client)
+{
+    register DrawablePtr pDst;
+    register DrawablePtr pSrc;
+    register GC *pGC;
+    REQUEST(xCopyAreaReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client); 
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        pSrc = pDst;
+
+    SET_DBE_SRCBUF(pSrc, stuff->srcDrawable);
+
+    pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY);
+    if (pGC->graphicsExposures)
+    {
+	(*pDst->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+	if (pRgn)
+	    REGION_DESTROY(pDst->pScreen, pRgn);
+    }
+
+    return(client->noClientException);
+}
+
+int
+ProcCopyPlane(register ClientPtr client)
+{
+    register DrawablePtr psrcDraw, pdstDraw;
+    register GC *pGC;
+    REQUEST(xCopyPlaneReq);
+    RegionPtr pRgn;
+
+    REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, pGC, client);
+    if (stuff->dstDrawable != stuff->srcDrawable)
+    {
+	SECURITY_VERIFY_DRAWABLE(psrcDraw, stuff->srcDrawable, client,
+				 SecurityReadAccess);
+	if (pdstDraw->pScreen != psrcDraw->pScreen)
+	{
+	    client->errorValue = stuff->dstDrawable;
+	    return (BadMatch);
+	}
+    }
+    else
+        psrcDraw = pdstDraw;
+
+    SET_DBE_SRCBUF(psrcDraw, stuff->srcDrawable);
+
+    /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+    if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+       (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+    {
+       client->errorValue = stuff->bitPlane;
+       return(BadValue);
+    }
+
+    pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+				 stuff->width, stuff->height, 
+				 stuff->dstX, stuff->dstY, stuff->bitPlane);
+    if (pGC->graphicsExposures)
+    {
+	(*pdstDraw->pScreen->SendGraphicsExpose)
+ 		(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+	if (pRgn)
+	    REGION_DESTROY(pdstDraw->pScreen, pRgn);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcPolyPoint(register ClientPtr client)
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyPointReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client); 
+    npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+    if (npoint)
+        (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+			  (xPoint *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcPolyLine(register ClientPtr client)
+{
+    int npoint;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyLineReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+    if (npoint > 1)
+	(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 
+			      (DDXPointPtr) &stuff[1]);
+    return(client->noClientException);
+}
+
+int
+ProcPolySegment(register ClientPtr client)
+{
+    int nsegs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolySegmentReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+    if (nsegs & 4)
+	return(BadLength);
+    nsegs >>= 3;
+    if (nsegs)
+        (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (register ClientPtr client)
+{
+    int nrects;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+    if (nrects & 4)
+	return(BadLength);
+    nrects >>= 3;
+    if (nrects)
+        (*pGC->ops->PolyRectangle)(pDraw, pGC, 
+		    nrects, (xRectangle *) &stuff[1]);
+    return(client->noClientException);
+}
+
+int
+ProcPolyArc(register ClientPtr client)
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+        (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcFillPoly(register ClientPtr client)
+{
+    int          things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xFillPolyReq);
+
+    REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+    if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&  
+	(stuff->shape != Convex))
+    {
+	client->errorValue = stuff->shape;
+        return BadValue;
+    }
+    if ((stuff->coordMode != CoordModeOrigin) && 
+	(stuff->coordMode != CoordModePrevious))
+    {
+	client->errorValue = stuff->coordMode;
+        return BadValue;
+    }
+
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+    if (things)
+        (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+			 stuff->coordMode, things,
+			 (DDXPointPtr) &stuff[1]);
+    return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(register ClientPtr client)
+{
+    int             things;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillRectangleReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+
+    if (things)
+        (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+		      (xRectangle *) &stuff[1]);
+    return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(register ClientPtr client)
+{
+    int		narcs;
+    register GC *pGC;
+    register DrawablePtr pDraw;
+    REQUEST(xPolyFillArcReq);
+
+    REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+    if (narcs % sizeof(xArc))
+	return(BadLength);
+    narcs /= sizeof(xArc);
+    if (narcs)
+        (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+    return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+    int	    whichbyte = 1;
+
+    if (*((char *) &whichbyte))
+	return LSBFirst;
+    return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+    switch (bpp) {
+    case 1:	/* yuck */
+	if (BITMAP_BIT_ORDER != order)
+	    BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+	ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+	break;
+    case 4:
+	break;  /* yuck */
+    case 8:
+	break;
+    case 16:
+	if (IMAGE_BYTE_ORDER != order)
+	    TwoByteSwap ((unsigned char *) base, nbytes);
+	break;
+    case 32:
+	if (IMAGE_BYTE_ORDER != order)
+	    FourByteSwap ((unsigned char *) base, nbytes);
+	break;
+    }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(register ClientPtr client)
+{
+    register	GC *pGC;
+    register	DrawablePtr pDraw;
+    long	length; 	/* length of scanline server padded */
+    long 	lengthProto; 	/* length of scanline protocol padded */
+    char	*tmpImage;
+    REQUEST(xPutImageReq);
+
+    REQUEST_AT_LEAST_SIZE(xPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    if (stuff->format == XYBitmap)
+    {
+        if ((stuff->depth != 1) ||
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length 	    = BitmapBytePad(stuff->width + stuff->leftPad);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || 
+	    (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+            return BadMatch;
+        length      = BitmapBytePad(stuff->width + stuff->leftPad);
+	length      *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+            return BadMatch;
+        length      = PixmapBytePad(stuff->width, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    tmpImage = (char *)&stuff[1];
+    lengthProto = length;
+	
+    if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 
+	(sizeof(xPutImageReq) >> 2)) != client->req_len)
+	return BadLength;
+
+    ReformatImage (tmpImage, lengthProto * stuff->height, 
+		   stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+		   ClientOrder(client));
+    
+    (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+		  stuff->width, stuff->height, 
+		  stuff->leftPad, stuff->format, tmpImage);
+
+     return (client->noClientException);
+}
+
+
+int
+DoGetImage(register ClientPtr client, int format, Drawable drawable, 
+           int x, int y, int width, int height, 
+           Mask planemask, xGetImageReply **im_return)
+{
+    register DrawablePtr pDraw;
+    int			nlines, linesPerBuf;
+    register int	linesDone;
+    long		widthBytesLine, length;
+    Mask		plane = 0;
+    char		*pBuf;
+    xGetImageReply	xgi;
+#ifdef XCSECURITY
+    RegionPtr pVisibleRegion = NULL;
+#endif
+
+    if ((format != XYPixmap) && (format != ZPixmap))
+    {
+	client->errorValue = format;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_DRAWABLE(pDraw, drawable, client, SecurityReadAccess);
+    if(pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + x < 0 ||
+ 	 pDraw->x + x + width > pDraw->pScreen->width ||
+         pDraw->y + y < 0 ||
+         pDraw->y + y + height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         x < - wBorderWidth((WindowPtr)pDraw) ||
+         x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         y < -wBorderWidth((WindowPtr)pDraw) ||
+         y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual (((WindowPtr) pDraw));
+    }
+    else
+    {
+      if(x < 0 ||
+         x+width > (int)pDraw->width ||
+         y < 0 ||
+         y+height > (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+
+    SET_DBE_SRCBUF(pDraw, drawable);
+
+    xgi.type = X_Reply;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(format == ZPixmap)
+    {
+	widthBytesLine = PixmapBytePad(width, pDraw->depth);
+	length = widthBytesLine * height;
+
+    }
+    else 
+    {
+	widthBytesLine = BitmapBytePad(width);
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = widthBytesLine * height *
+		 Ones(planemask & (plane | (plane - 1)));
+
+    }
+
+    xgi.length = length;
+
+    if (im_return) {
+	pBuf = (char *)xalloc(sz_xGetImageReply + length);
+	if (!pBuf)
+	    return (BadAlloc);
+	if (widthBytesLine == 0)
+	    linesPerBuf = 0;
+	else
+	    linesPerBuf = height;
+	*im_return = (xGetImageReply *)pBuf;
+	*(xGetImageReply *)pBuf = xgi;
+	pBuf += sz_xGetImageReply;
+    } else {
+	xgi.length = (xgi.length + 3) >> 2;
+	if (widthBytesLine == 0 || height == 0)
+	    linesPerBuf = 0;
+	else if (widthBytesLine >= IMAGE_BUFSIZE)
+	    linesPerBuf = 1;
+	else
+	{
+	    linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+	    if (linesPerBuf > height)
+		linesPerBuf = height;
+	}
+	length = linesPerBuf * widthBytesLine;
+	if (linesPerBuf < height)
+	{
+	    /* we have to make sure intermediate buffers don't need padding */
+	    while ((linesPerBuf > 1) &&
+		   (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+	    {
+		linesPerBuf--;
+		length -= widthBytesLine;
+	    }
+	    while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+	    {
+		linesPerBuf++;
+		length += widthBytesLine;
+	    }
+	}
+	if(!(pBuf = (char *) ALLOCATE_LOCAL(length)))
+	    return (BadAlloc);
+	WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+    }
+
+#ifdef XCSECURITY
+    if (client->trustLevel != XSecurityClientTrusted &&
+	pDraw->type == DRAWABLE_WINDOW)
+    {
+	pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+	if (pVisibleRegion)
+	{
+	    REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, -pDraw->x, -pDraw->y);
+	}
+    }
+#endif
+
+    if (linesPerBuf == 0)
+    {
+	/* nothing to do */
+    }
+    else if (format == ZPixmap)
+    {
+        linesDone = 0;
+        while (height - linesDone > 0)
+        {
+	    nlines = min(linesPerBuf, height - linesDone);
+	    (*pDraw->pScreen->GetImage) (pDraw,
+	                                 x,
+				         y + linesDone,
+				         width, 
+				         nlines,
+				         format,
+				         planemask,
+				         (pointer) pBuf);
+#ifdef XCSECURITY
+	    if (pVisibleRegion)
+		SecurityCensorImage(client, pVisibleRegion, widthBytesLine,
+			pDraw, x, y + linesDone, width, 
+			nlines, format, pBuf);
+#endif
+
+	    /* Note that this is NOT a call to WriteSwappedDataToClient,
+               as we do NOT byte swap */
+	    if (!im_return)
+	    {
+		ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+			       BitsPerPixel (pDraw->depth),
+			       ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+		(void)WriteToClient(client,
+				    (int)(nlines * widthBytesLine),
+				    pBuf);
+	    }
+	    linesDone += nlines;
+        }
+    }
+    else /* XYPixmap */
+    {
+        for (; plane; plane >>= 1)
+	{
+	    if (planemask & plane)
+	    {
+	        linesDone = 0;
+	        while (height - linesDone > 0)
+	        {
+		    nlines = min(linesPerBuf, height - linesDone);
+	            (*pDraw->pScreen->GetImage) (pDraw,
+	                                         x,
+				                 y + linesDone,
+				                 width, 
+				                 nlines,
+				                 format,
+				                 plane,
+				                 (pointer)pBuf);
+#ifdef XCSECURITY
+		    if (pVisibleRegion)
+			SecurityCensorImage(client, pVisibleRegion,
+				widthBytesLine,
+				pDraw, x, y + linesDone, width, 
+				nlines, format, pBuf);
+#endif
+
+		    /* Note: NOT a call to WriteSwappedDataToClient,
+		       as we do NOT byte swap */
+		    if (im_return) {
+			pBuf += nlines * widthBytesLine;
+		    } else {
+			ReformatImage (pBuf, 
+				       (int)(nlines * widthBytesLine), 
+				       1,
+				       ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+			(void)WriteToClient(client,
+					(int)(nlines * widthBytesLine),
+					pBuf);
+		    }
+		    linesDone += nlines;
+		}
+            }
+	}
+    }
+#ifdef XCSECURITY
+    if (pVisibleRegion)
+	REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+#endif
+    if (!im_return)
+	DEALLOCATE_LOCAL(pBuf);
+    return (client->noClientException);
+}
+
+int
+ProcGetImage(register ClientPtr client)
+{
+    REQUEST(xGetImageReq);
+
+    REQUEST_SIZE_MATCH(xGetImageReq);
+
+    return DoGetImage(client, stuff->format, stuff->drawable,
+		      stuff->x, stuff->y,
+		      (int)stuff->width, (int)stuff->height,
+		      stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(register ClientPtr client)
+{
+    int	err;
+    REQUEST(xPolyTextReq);
+    DrawablePtr pDraw;
+    GC *pGC;
+
+    REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = PolyText(client,
+		   pDraw,
+		   pGC,
+		   (unsigned char *)&stuff[1],
+		   ((unsigned char *) stuff) + (client->req_len << 2),
+		   stuff->x,
+		   stuff->y,
+		   stuff->reqType,
+		   stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText8(register ClientPtr client)
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+int
+ProcImageText16(register ClientPtr client)
+{
+    int	err;
+    register DrawablePtr pDraw;
+    register GC *pGC;
+
+    REQUEST(xImageTextReq);
+
+    REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+    err = ImageText(client,
+		    pDraw,
+		    pGC,
+		    stuff->nChars,
+		    (unsigned char *)&stuff[1],
+		    stuff->x,
+		    stuff->y,
+		    stuff->reqType,
+		    stuff->drawable);
+
+    if (err == Success)
+    {
+	return(client->noClientException);
+    }
+    else
+	return err;
+}
+
+
+int
+ProcCreateColormap(register ClientPtr client)
+{
+    VisualPtr	pVisual;
+    ColormapPtr	pmap;
+    Colormap	mid;
+    register WindowPtr   pWin;
+    ScreenPtr pScreen;
+    REQUEST(xCreateColormapReq);
+    int i, result;
+
+    REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+    if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+    {
+	client->errorValue = stuff->alloc;
+        return(BadValue);
+    }
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pScreen = pWin->drawable.pScreen;
+    for (i = 0, pVisual = pScreen->visuals;
+	 i < pScreen->numVisuals;
+	 i++, pVisual++)
+    {
+	if (pVisual->vid != stuff->visual)
+	    continue;
+	result =  CreateColormap(mid, pScreen, pVisual, &pmap,
+				 (int)stuff->alloc, client->index);
+	if (client->noClientException != Success)
+	    return(client->noClientException);
+	else
+	    return(result);
+    }
+    client->errorValue = stuff->visual;
+    return(BadValue);
+}
+
+int
+ProcFreeColormap(register ClientPtr client)
+{
+    ColormapPtr pmap;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pmap = (ColormapPtr )SecurityLookupIDByType(client, stuff->id, RT_COLORMAP,
+						SecurityDestroyAccess);
+    if (pmap) 
+    {
+	/* Freeing a default colormap is a no-op */
+	if (!(pmap->flags & IsDefault))
+	    FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadColor);
+    }
+}
+
+
+int
+ProcCopyColormapAndFree(register ClientPtr client)
+{
+    Colormap	mid;
+    ColormapPtr	pSrcMap;
+    REQUEST(xCopyColormapAndFreeReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+    mid = stuff->mid;
+    LEGAL_NEW_RESOURCE(mid, client);
+    if( (pSrcMap = (ColormapPtr )SecurityLookupIDByType(client,	stuff->srcCmap,
+		RT_COLORMAP, SecurityReadAccess|SecurityWriteAccess)) )
+    {
+	result = CopyColormapAndFree(mid, pSrcMap, client->index);
+	if (client->noClientException != Success)
+            return(client->noClientException);
+	else
+            return(result);
+    }
+    else
+    {
+	client->errorValue = stuff->srcCmap;
+	return(BadColor);
+    }
+}
+
+int
+ProcInstallColormap(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					    RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+        (*(pcmp->pScreen->InstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcUninstallColormap(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	if(pcmp->mid != pcmp->pScreen->defColormap)
+            (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->id;
+        return (BadColor);
+    }
+}
+
+int
+ProcListInstalledColormaps(register ClientPtr client)
+{
+    xListInstalledColormapsReply *preply; 
+    int nummaps;
+    WindowPtr pWin;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+
+    if (!pWin)
+        return(BadWindow);
+
+    preply = (xListInstalledColormapsReply *) 
+		ALLOCATE_LOCAL(sizeof(xListInstalledColormapsReply) +
+		     pWin->drawable.pScreen->maxInstalledCmaps *
+		     sizeof(Colormap));
+    if(!preply)
+        return(BadAlloc);
+
+    preply->type = X_Reply;
+    preply->sequenceNumber = client->sequence;
+    nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+        (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+    preply->nColormaps = nummaps;
+    preply->length = nummaps;
+    WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+    WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+    DEALLOCATE_LOCAL(preply);
+    return(client->noClientException);
+}
+
+int
+ProcAllocColor (register ClientPtr client)
+{
+    ColormapPtr pmap;
+    int	retval;
+    xAllocColorReply acr;
+    REQUEST(xAllocColorReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorReq);
+    pmap = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pmap)
+    {
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pmap, (xReq *) stuff))
+	    return Success;
+#endif
+	acr.type = X_Reply;
+	acr.length = 0;
+	acr.sequenceNumber = client->sequence;
+	acr.red = stuff->red;
+	acr.green = stuff->green;
+	acr.blue = stuff->blue;
+	acr.pixel = 0;
+	if( (retval = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+	                       &acr.pixel, client->index)) )
+	{
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return (retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+        WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+	return (client->noClientException);
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocNamedColor (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					    RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int		retval;
+
+	xAllocNamedColorReply ancr;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocNamedColor request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	ancr.type = X_Reply;
+	ancr.length = 0;
+	ancr.sequenceNumber = client->sequence;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+	{
+	    ancr.screenRed = ancr.exactRed;
+	    ancr.screenGreen = ancr.exactGreen;
+	    ancr.screenBlue = ancr.exactBlue;
+	    ancr.pixel = 0;
+	    if( (retval = AllocColor(pcmp,
+	                 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+			 &ancr.pixel, client->index)) )
+	    {
+                if (client->noClientException != Success)
+                    return(client->noClientException);
+                else
+    	            return(retval);
+	    }
+#ifdef PANORAMIX
+	    if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+            WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+	    return (client->noClientException);
+	}
+	else
+	    return(BadName);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorCells (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorCellsReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorCellsReply	accr;
+	int			npixels, nmasks, retval;
+	long			length;
+	Pixel			*ppixels, *pmasks;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorCells request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	nmasks = stuff->planes;
+	length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	pmasks = ppixels + npixels;
+
+	if( (retval = AllocColorCells(client->index, pcmp, npixels, nmasks, 
+				    (Bool)stuff->contiguous, ppixels, pmasks)) )
+	{
+	    DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    accr.type = X_Reply;
+	    accr.length = length >> 2;
+	    accr.sequenceNumber = client->sequence;
+	    accr.nPixels = npixels;
+	    accr.nMasks = nmasks;
+	    WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcAllocColorPlanes(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xAllocColorPlanesReq);
+
+    REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xAllocColorPlanesReply	acpr;
+	int			npixels, retval;
+	long			length;
+	Pixel			*ppixels;
+
+#ifdef LBX
+	/*
+	 * If the colormap is grabbed by a proxy, the server will have
+	 * to regain control over the colormap.  This AllocColorPlanes request
+	 * will be handled after the server gets back the colormap control.
+	 */
+	if (LbxCheckColorRequest (client, pcmp, (xReq *) stuff))
+	    return Success;
+#endif
+	npixels = stuff->colors;
+	if (!npixels)
+	{
+	    client->errorValue = npixels;
+	    return (BadValue);
+	}
+	if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+	{
+	    client->errorValue = stuff->contiguous;
+	    return (BadValue);
+	}
+	acpr.type = X_Reply;
+	acpr.sequenceNumber = client->sequence;
+	acpr.nPixels = npixels;
+	length = (long)npixels * sizeof(Pixel);
+	ppixels = (Pixel *)ALLOCATE_LOCAL(length);
+	if(!ppixels)
+            return(BadAlloc);
+	if( (retval = AllocColorPlanes(client->index, pcmp, npixels,
+	    (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+	    (Bool)stuff->contiguous, ppixels,
+	    &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+	{
+            DEALLOCATE_LOCAL(ppixels);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	        return(retval);
+	}
+	acpr.length = length >> 2;
+#ifdef PANORAMIX
+	if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+	{
+	    WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+	    client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+	    WriteSwappedDataToClient(client, length, ppixels);
+	}
+	DEALLOCATE_LOCAL(ppixels);
+        return (client->noClientException);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcFreeColors(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xFreeColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+	if(pcmp->flags & AllAllocated)
+	    return(BadAccess);
+	count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+	retval =  FreeColors(pcmp, client->index, count,
+	    (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	int	count;
+        int     retval;
+
+        count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+	if (count % sizeof(xColorItem))
+	    return(BadLength);
+	count /= sizeof(xColorItem);
+	retval = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+        if (client->noClientException != Success)
+            return(client->noClientException);
+        else
+	{
+	    client->errorValue = clientErrorValue;
+            return(retval);
+	}
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcStoreNamedColor (register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xStoreNamedColorReq);
+
+    REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityWriteAccess);
+    if (pcmp)
+    {
+	xColorItem	def;
+        int             retval;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+	                 stuff->nbytes, &def.red, &def.green, &def.blue))
+	{
+	    def.flags = stuff->flags;
+	    def.pixel = stuff->pixel;
+	    retval = StoreColors(pcmp, 1, &def);
+            if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+		return(retval);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcQueryColors(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xQueryColorsReq);
+
+    REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	int			count, retval;
+	xrgb 			*prgbs;
+	xQueryColorsReply	qcr;
+
+	count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
+	prgbs = (xrgb *)ALLOCATE_LOCAL(count * sizeof(xrgb));
+	if(!prgbs && count)
+            return(BadAlloc);
+	if( (retval = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+	{
+   	    if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	    if (client->noClientException != Success)
+                return(client->noClientException);
+	    else
+	    {
+		client->errorValue = clientErrorValue;
+	        return (retval);
+	    }
+	}
+	qcr.type = X_Reply;
+	qcr.length = (count * sizeof(xrgb)) >> 2;
+	qcr.sequenceNumber = client->sequence;
+	qcr.nColors = count;
+	WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+	if (count)
+	{
+	    client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+	    WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+	}
+	if (prgbs) DEALLOCATE_LOCAL(prgbs);
+	return(client->noClientException);
+	
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+} 
+
+int
+ProcLookupColor(register ClientPtr client)
+{
+    ColormapPtr pcmp;
+    REQUEST(xLookupColorReq);
+
+    REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+    pcmp = (ColormapPtr)SecurityLookupIDByType(client, stuff->cmap,
+					RT_COLORMAP, SecurityReadAccess);
+    if (pcmp)
+    {
+	xLookupColorReply lcr;
+
+	if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+	                 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+	{
+	    lcr.type = X_Reply;
+	    lcr.length = 0;
+	    lcr.sequenceNumber = client->sequence;
+	    lcr.screenRed = lcr.exactRed;
+	    lcr.screenGreen = lcr.exactGreen;
+	    lcr.screenBlue = lcr.exactBlue;
+	    (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+	                                   &lcr.screenGreen,
+					   &lcr.screenBlue,
+					   pcmp->pVisual);
+	    WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+	    return(client->noClientException);
+	}
+        return (BadName);        
+    }
+    else
+    {
+        client->errorValue = stuff->cmap;
+        return (BadColor);
+    }
+}
+
+int
+ProcCreateCursor (register ClientPtr client)
+{
+    CursorPtr	pCursor;
+
+    register PixmapPtr 	src;
+    register PixmapPtr 	msk;
+    unsigned char *	srcbits;
+    unsigned char *	mskbits;
+    unsigned short	width, height;
+    long		n;
+    CursorMetricRec cm;
+
+
+    REQUEST(xCreateCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    src = (PixmapPtr)SecurityLookupIDByType(client, stuff->source,
+					      RT_PIXMAP, SecurityReadAccess);
+    msk = (PixmapPtr)SecurityLookupIDByType(client, stuff->mask,
+					      RT_PIXMAP, SecurityReadAccess);
+    if (   src == (PixmapPtr)NULL)
+    {
+	client->errorValue = stuff->source;
+	return (BadPixmap);
+    }
+    if ( msk == (PixmapPtr)NULL)
+    {
+	if (stuff->mask != None)
+	{
+	    client->errorValue = stuff->mask;
+	    return (BadPixmap);
+	}
+    }
+    else if (  src->drawable.width != msk->drawable.width
+	    || src->drawable.height != msk->drawable.height
+	    || src->drawable.depth != 1
+	    || msk->drawable.depth != 1)
+	return (BadMatch);
+
+    width = src->drawable.width;
+    height = src->drawable.height;
+
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+
+    n = BitmapBytePad(width)*height;
+    srcbits = (unsigned char *)xalloc(n);
+    if (!srcbits)
+	return (BadAlloc);
+    mskbits = (unsigned char *)xalloc(n);
+    if (!mskbits)
+    {
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+
+    /* zeroing the (pad) bits helps some ddx cursor handling */
+    bzero((char *)srcbits, n);
+    (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+					 XYPixmap, 1, (pointer)srcbits);
+    if ( msk == (PixmapPtr)NULL)
+    {
+	register unsigned char *bits = mskbits;
+	while (--n >= 0)
+	    *bits++ = ~0;
+    }
+    else
+    {
+	/* zeroing the (pad) bits helps some ddx cursor handling */
+	bzero((char *)mskbits, n);
+	(* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+					height, XYPixmap, 1, (pointer)mskbits);
+    }
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursor( srcbits, mskbits, &cm,
+	    stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+	    stuff->backRed, stuff->backGreen, stuff->backBlue);
+
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	    return (client->noClientException);
+    return BadAlloc;
+}
+
+int
+ProcCreateGlyphCursor (register ClientPtr client)
+{
+    CursorPtr pCursor;
+    int res;
+
+    REQUEST(xCreateGlyphCursorReq);
+
+    REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+    res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+			   stuff->mask, stuff->maskChar,
+			   stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+			   stuff->backRed, stuff->backGreen, stuff->backBlue,
+			   &pCursor, client);
+    if (res != Success)
+	return res;
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (register ClientPtr client)
+{
+    CursorPtr pCursor;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->id,
+					RT_CURSOR, SecurityDestroyAccess);
+    if (pCursor) 
+    {
+	FreeResource(stuff->id, RT_NONE);
+	return (client->noClientException);
+    }
+    else 
+    {
+	client->errorValue = stuff->id;
+	return (BadCursor);
+    }
+}
+
+int
+ProcQueryBestSize (register ClientPtr client)
+{
+    xQueryBestSizeReply	reply;
+    register DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    REQUEST(xQueryBestSizeReq);
+
+    REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+    if ((stuff->class != CursorShape) && 
+	(stuff->class != TileShape) && 
+	(stuff->class != StippleShape))
+    {
+	client->errorValue = stuff->class;
+        return(BadValue);
+    }
+    SECURITY_VERIFY_GEOMETRABLE (pDraw, stuff->drawable, client,
+				 SecurityReadAccess);
+    if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+	return (BadMatch);
+    pScreen = pDraw->pScreen;
+    (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+			       &stuff->height, pScreen);
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.width = stuff->width;
+    reply.height = stuff->height;
+    WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+    return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (register ClientPtr client)
+{
+    int blankingOption, exposureOption;
+    REQUEST(xSetScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+    blankingOption = stuff->preferBlank;
+    if ((blankingOption != DontPreferBlanking) &&
+        (blankingOption != PreferBlanking) &&
+        (blankingOption != DefaultBlanking))
+    {
+	client->errorValue = blankingOption;
+        return BadValue;
+    }
+    exposureOption = stuff->allowExpose;
+    if ((exposureOption != DontAllowExposures) &&
+        (exposureOption != AllowExposures) &&
+        (exposureOption != DefaultExposures))
+    {
+	client->errorValue = exposureOption;
+        return BadValue;
+    }
+    if (stuff->timeout < -1)
+    {
+	client->errorValue = stuff->timeout;
+        return BadValue;
+    }
+    if (stuff->interval < -1)
+    {
+	client->errorValue = stuff->interval;
+        return BadValue;
+    }
+
+    if (blankingOption == DefaultBlanking)
+	ScreenSaverBlanking = defaultScreenSaverBlanking;
+    else
+	ScreenSaverBlanking = blankingOption; 
+    if (exposureOption == DefaultExposures)
+	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+    else
+	ScreenSaverAllowExposures = exposureOption;
+
+    if (stuff->timeout >= 0)
+	ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+    else 
+	ScreenSaverTime = defaultScreenSaverTime;
+    if (stuff->interval >= 0)
+	ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+    else
+	ScreenSaverInterval = defaultScreenSaverInterval;
+
+    SetScreenSaverTimer();
+    return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(register ClientPtr client)
+{
+    xGetScreenSaverReply rep;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+    rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+    rep.preferBlanking = ScreenSaverBlanking;
+    rep.allowExposures = ScreenSaverAllowExposures;
+    WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+    return (client->noClientException);
+}
+
+int
+ProcChangeHosts(register ClientPtr client)
+{
+    REQUEST(xChangeHostsReq);
+    int result;
+
+    REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+    if(stuff->mode == HostInsert)
+	result = AddHost(client, (int)stuff->hostFamily,
+			 stuff->hostLength, (pointer)&stuff[1]);
+    else if (stuff->mode == HostDelete)
+	result = RemoveHost(client, (int)stuff->hostFamily, 
+			    stuff->hostLength, (pointer)&stuff[1]);  
+    else
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcListHosts(register ClientPtr client)
+{
+    xListHostsReply reply;
+    int	len, nHosts, result;
+    pointer	pdata;
+    /* REQUEST(xListHostsReq); */
+
+    REQUEST_SIZE_MATCH(xListHostsReq);
+#ifdef XCSECURITY
+    /* untrusted clients can't list hosts */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	SecurityAudit("client %d attempted to list hosts\n", client->index);
+	return BadAccess;
+    }
+#endif
+    result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+    if (result != Success)
+	return(result);
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.nHosts = nHosts;
+    reply.length = len >> 2;
+    WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+    if (nHosts)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+	WriteSwappedDataToClient(client, len, pdata);
+    }
+    xfree(pdata);
+    return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(register ClientPtr client)
+{
+    int result;
+    REQUEST(xSetAccessControlReq);
+
+    REQUEST_SIZE_MATCH(xSetAccessControlReq);
+    if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+    if (!result)
+	result = client->noClientException;
+    return (result);
+}
+
+int
+ProcKillClient(register ClientPtr client)
+{
+    REQUEST(xResourceReq);
+    ClientPtr	killclient;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    if (stuff->id == AllTemporary)
+    {
+	CloseDownRetainedResources();
+        return (client->noClientException);
+    }
+
+    if ((killclient = LookupClient(stuff->id, client)))
+    {
+	CloseDownClient(killclient);
+	/* if an LBX proxy gets killed, isItTimeToYield will be set */
+	if (isItTimeToYield || (client == killclient))
+	{
+	    /* force yield and return Success, so that Dispatch()
+	     * doesn't try to touch client
+	     */
+	    isItTimeToYield = TRUE;
+	    return (Success);
+	}
+	return (client->noClientException);
+    }
+    else
+    {
+	client->errorValue = stuff->id;
+	return (BadValue);
+    }
+}
+
+int
+ProcSetFontPath(register ClientPtr client)
+{
+    unsigned char *ptr;
+    unsigned long nbytes, total;
+    long nfonts;
+    int n, result;
+    int error;
+    REQUEST(xSetFontPathReq);
+    
+    REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+    
+    nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+    total = nbytes;
+    ptr = (unsigned char *)&stuff[1];
+    nfonts = stuff->nFonts;
+    while (--nfonts >= 0)
+    {
+	if ((total == 0) || (total < (n = (*ptr + 1))))
+	    return(BadLength);
+	total -= n;
+	ptr += n;
+    }
+    if (total >= 4)
+	return(BadLength);
+    result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+			 &error);
+    if (!result)
+    {
+	result = client->noClientException;
+	client->errorValue = error;
+    }
+    return (result);
+}
+
+int
+ProcGetFontPath(register ClientPtr client)
+{
+    xGetFontPathReply reply;
+    int stringLens, numpaths;
+    unsigned char *bufferStart;
+    /* REQUEST (xReq); */
+
+    REQUEST_SIZE_MATCH(xReq);
+    bufferStart = GetFontPath(&numpaths, &stringLens);
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = (stringLens + numpaths + 3) >> 2;
+    reply.nPaths = numpaths;
+
+    WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+    if (stringLens || numpaths)
+	(void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+    return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(register ClientPtr client)
+{
+    REQUEST(xSetCloseDownModeReq);
+
+    REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+    if ((stuff->mode == AllTemporary) ||
+	(stuff->mode == RetainPermanent) ||
+	(stuff->mode == RetainTemporary))
+    {
+	client->closeDownMode = stuff->mode;
+	return (client->noClientException);
+    }
+    else   
+    {
+	client->errorValue = stuff->mode;
+	return (BadValue);
+    }
+}
+
+int ProcForceScreenSaver(register ClientPtr client)
+{    
+    REQUEST(xForceScreenSaverReq);
+
+    REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+    
+    if ((stuff->mode != ScreenSaverReset) && 
+	(stuff->mode != ScreenSaverActive))
+    {
+	client->errorValue = stuff->mode;
+        return BadValue;
+    }
+    SaveScreens(SCREEN_SAVER_FORCER, (int)stuff->mode);
+    return client->noClientException;
+}
+
+int ProcNoOperation(register ClientPtr client)
+{
+    REQUEST_AT_LEAST_SIZE(xReq);
+    
+    /* noop -- don't do anything */
+    return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+    int i;
+    for (i = 0; i<256; i++)
+    {
+	if(!ProcVector[i])
+	{
+            ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+	    ReplySwapVector[i] = ReplyNotSwappd;
+	}
+#ifdef K5AUTH
+	if (!k5_Vector[i])
+	{
+	    k5_Vector[i] = k5_bad;
+	}
+#endif
+    }
+    for(i = LASTEvent; i < 128; i++)
+    {
+	EventSwapVector[i] = NotImplemented;
+    }
+    
+}
+
+/**********************
+ * CloseDownClient
+ *
+ *  Client can either mark his resources destroy or retain.  If retained and
+ *  then killed again, the client is really destroyed.
+ *********************/
+
+char dispatchExceptionAtReset = DE_RESET;
+
+void
+CloseDownClient(register ClientPtr client)
+{
+    Bool really_close_down = client->clientGone ||
+			     client->closeDownMode == DestroyAll;
+
+    if (!client->clientGone)
+    {
+	/* ungrab server if grabbing client dies */
+	if (grabState != GrabNone && grabClient == client)
+	{
+	    UngrabServer(client);
+	}
+	BITCLEAR(grabWaiters, client->index);
+	DeleteClientFromAnySelections(client);
+	ReleaseActiveGrabs(client);
+	DeleteClientFontStuff(client);
+	if (!really_close_down)
+	{
+	    /*  This frees resources that should never be retained
+	     *  no matter what the close down mode is.  Actually we
+	     *  could do this unconditionally, but it's probably
+	     *  better not to traverse all the client's resources
+	     *  twice (once here, once a few lines down in
+	     *  FreeClientResources) in the common case of
+	     *  really_close_down == TRUE.
+	     */
+	    FreeClientNeverRetainResources(client);
+	    client->clientState = ClientStateRetained;
+  	    if (ClientStateCallback)
+            {
+		NewClientInfoRec clientinfo;
+
+		clientinfo.client = client; 
+		clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+		clientinfo.setup = (xConnSetup *) NULL;
+		CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+            } 
+	}
+	client->clientGone = TRUE;  /* so events aren't sent to client */
+	if (ClientIsAsleep(client))
+	    ClientSignal (client);
+	ProcessWorkQueueZombies();
+#ifdef LBX
+	ProcessQTagZombies();
+#endif
+	CloseDownConnection(client);
+
+	/* If the client made it to the Running stage, nClients has
+	 * been incremented on its behalf, so we need to decrement it
+	 * now.  If it hasn't gotten to Running, nClients has *not*
+	 * been incremented, so *don't* decrement it.
+	 */
+	if (client->clientState != ClientStateInitial &&
+	    client->clientState != ClientStateAuthenticating )
+	{
+	    --nClients;
+	}
+    }
+
+    if (really_close_down)
+    {
+	if (client->clientState == ClientStateRunning && nClients == 0)
+	    dispatchException |= dispatchExceptionAtReset;
+
+	client->clientState = ClientStateGone;
+	if (ClientStateCallback)
+	{
+	    NewClientInfoRec clientinfo;
+
+	    clientinfo.client = client; 
+	    clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+	    clientinfo.setup = (xConnSetup *) NULL;
+	    CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+	} 	    
+	FreeClientResources(client);
+	if (client->index < nextFreeClientID)
+	    nextFreeClientID = client->index;
+	clients[client->index] = NullClient;
+#ifdef SMART_SCHEDULE
+	SmartLastClient = NullClient;
+#endif
+	xfree(client);
+
+	while (!clients[currentMaxClients-1])
+	    currentMaxClients--;
+    }
+}
+
+static void
+KillAllClients()
+{
+    int i;
+    for (i=1; i<currentMaxClients; i++)
+        if (clients[i]) {
+            /* Make sure Retained clients are released. */
+            clients[i]->closeDownMode = DestroyAll;
+            CloseDownClient(clients[i]);     
+        }
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ *    Find all clients that are gone and have terminated in RetainTemporary 
+ *    and  destroy their resources.
+ *********************/
+
+void
+CloseDownRetainedResources()
+{
+    register int i;
+    register ClientPtr client;
+
+    for (i=1; i<currentMaxClients; i++)
+    {
+        client = clients[i];
+        if (client && (client->closeDownMode == RetainTemporary)
+	    && (client->clientGone))
+	    CloseDownClient(client);
+    }
+}
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+    client->index = i;
+    client->sequence = 0; 
+    client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+    client->clientGone = FALSE;
+    if (i)
+    {
+	client->closeDownMode = DestroyAll;
+	client->lastDrawable = (DrawablePtr)WindowTable[0];
+	client->lastDrawableID = WindowTable[0]->drawable.id;
+    }
+    else
+    {
+	client->closeDownMode = RetainPermanent;
+	client->lastDrawable = (DrawablePtr)NULL;
+	client->lastDrawableID = INVALID;
+    }
+    client->lastGC = (GCPtr) NULL;
+    client->lastGCID = INVALID;
+    client->numSaved = 0;
+    client->saveSet = (SaveSetElt *)NULL;
+    client->noClientException = Success;
+#ifdef DEBUG
+    client->requestLogIndex = 0;
+#endif
+    client->requestVector = InitialVector;
+    client->osPrivate = ospriv;
+    client->swapped = FALSE;
+    client->big_requests = FALSE;
+    client->priority = 0;
+    client->clientState = ClientStateInitial;
+#ifdef XKB
+    if (!noXkbExtension) {
+	client->xkbClientFlags = 0;
+	client->mapNotifyMask = 0;
+	QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+    }
+#endif
+    client->replyBytesRemaining = 0;
+#ifdef LBX
+    client->readRequest = StandardReadRequestFromClient;
+#endif
+#ifdef XCSECURITY
+    client->trustLevel = XSecurityClientTrusted;
+    client->CheckAccess = NULL;
+    client->authId = 0;
+#endif
+#ifdef XAPPGROUP
+    client->appgroup = NULL;
+#endif
+    client->fontResFunc = NULL;
+#ifdef SMART_SCHEDULE
+    client->smart_priority = 0;
+    client->smart_start_tick = SmartScheduleTime;
+    client->smart_stop_tick = SmartScheduleTime;
+    client->smart_check_tick = SmartScheduleTime;
+#endif
+}
+
+extern int clientPrivateLen;
+extern unsigned *clientPrivateSizes;
+extern unsigned totalClientSize;
+
+int
+InitClientPrivates(ClientPtr client)
+{
+    register char *ptr;
+    DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    if (totalClientSize == sizeof(ClientRec))
+	ppriv = (DevUnion *)NULL;
+    else if (client->index)
+	ppriv = (DevUnion *)(client + 1);
+    else
+    {
+	ppriv = (DevUnion *)xalloc(totalClientSize - sizeof(ClientRec));
+	if (!ppriv)
+	    return 0;
+    }
+    client->devPrivates = ppriv;
+    sizes = clientPrivateSizes;
+    ptr = (char *)(ppriv + clientPrivateLen);
+    for (i = clientPrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return 1;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+    register int i;
+    register ClientPtr client;
+    xReq data;
+
+    i = nextFreeClientID;
+    if (i == MAXCLIENTS)
+	return (ClientPtr)NULL;
+    clients[i] = client = (ClientPtr)xalloc(totalClientSize);
+    if (!client)
+	return (ClientPtr)NULL;
+    InitClient(client, i, ospriv);
+    InitClientPrivates(client);
+    if (!InitClientResources(client))
+    {
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    data.reqType = 1;
+    data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+    if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+    {
+	FreeClientResources(client);
+	xfree(client);
+	return (ClientPtr)NULL;
+    }
+    if (i == currentMaxClients)
+	currentMaxClients++;
+    while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+	nextFreeClientID++;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = (xConnSetupPrefix *)NULL;  
+        clientinfo.setup = (xConnSetup *) NULL;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return(client);
+}
+
+int
+ProcInitialConnection(register ClientPtr client)
+{
+    REQUEST(xReq);
+    register xConnClientPrefix *prefix;
+    int whichbyte = 1;
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+	return (client->noClientException = -1);
+    if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+	(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+    {
+	client->swapped = TRUE;
+	SwapConnClientPrefix(prefix);
+    }
+    stuff->reqType = 2;
+    stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
+		     ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+    if (client->swapped)
+    {
+	swaps(&stuff->length, whichbyte);
+    }
+    ResetCurrentRequest(client);
+    return (client->noClientException);
+}
+
+#ifdef LBX
+void
+IncrementClientCount()
+{
+    nClients++;
+}
+#endif
+
+int
+SendConnSetup(register ClientPtr client, char *reason)
+{
+    register xWindowRoot *root;
+    register int i;
+    int numScreens;
+    char* lConnectionInfo;
+    xConnSetupPrefix* lconnSetupPrefix;
+
+    if (reason)
+    {
+	xConnSetupPrefix csp;
+
+	csp.success = xFalse;
+	csp.lengthReason = strlen(reason);
+	csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+	csp.majorVersion = X_PROTOCOL;
+	csp.minorVersion = X_PROTOCOL_REVISION;
+	if (client->swapped)
+	    WriteSConnSetupPrefix(client, &csp);
+	else
+	    (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+        (void)WriteToClient(client, (int)csp.lengthReason, reason);
+	return (client->noClientException = -1);
+    }
+
+    numScreens = screenInfo.numScreens;
+    lConnectionInfo = ConnectionInfo;
+    lconnSetupPrefix = &connSetupPrefix;
+
+    /* We're about to start speaking X protocol back to the client by
+     * sending the connection setup info.  This means the authorization
+     * step is complete, and we can count the client as an
+     * authorized one.
+     */
+    nClients++;
+
+    client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+    client->sequence = 0;
+#ifdef XAPPGROUP
+    XagConnectionInfo (client, &lconnSetupPrefix, &lConnectionInfo, &numScreens);
+#endif
+    ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+    ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+    ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+    ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+    /* fill in the "currentInputMask" */
+    root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+    for (i=0; i<numScreens; i++) 
+    {
+	register unsigned int j;
+	register xDepth *pDepth;
+
+        root->currentInputMask = WindowTable[i]->eventMask |
+			         wOtherEventMasks (WindowTable[i]);
+	pDepth = (xDepth *)(root + 1);
+	for (j = 0; j < root->nDepths; j++)
+	{
+	    pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+				pDepth->nVisuals * sizeof(xVisualType));
+	}
+	root = (xWindowRoot *)pDepth;
+    }
+
+    if (client->swapped)
+    {
+	WriteSConnSetupPrefix(client, lconnSetupPrefix);
+	WriteSConnectionInfo(client,
+			     (unsigned long)(lconnSetupPrefix->length << 2),
+			     lConnectionInfo);
+    }
+    else
+    {
+	(void)WriteToClient(client, sizeof(xConnSetupPrefix),
+			    (char *) lconnSetupPrefix);
+	(void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+			    lConnectionInfo);
+    }
+    client->clientState = ClientStateRunning;
+    if (ClientStateCallback)
+    {
+	NewClientInfoRec clientinfo;
+
+        clientinfo.client = client; 
+        clientinfo.prefix = lconnSetupPrefix;  
+        clientinfo.setup = (xConnSetup *)lConnectionInfo;
+	CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+    } 	
+    return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(register ClientPtr client)
+{
+    char *reason, *auth_proto, *auth_string;
+    register xConnClientPrefix *prefix;
+    REQUEST(xReq);
+
+    prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+    auth_proto = (char *)prefix + sz_xConnClientPrefix;
+    auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+    if ((prefix->majorVersion != X_PROTOCOL) ||
+	(prefix->minorVersion != X_PROTOCOL_REVISION))
+	reason = "Protocol version mismatch";
+    else
+	reason = ClientAuthorized(client,
+				  (unsigned short)prefix->nbytesAuthProto,
+				  auth_proto,
+				  (unsigned short)prefix->nbytesAuthString,
+				  auth_string);
+    /*
+     * If Kerberos is being used for this client, the clientState
+     * will be set to ClientStateAuthenticating at this point.
+     * More messages need to be exchanged among the X server, Kerberos
+     * server, and client to figure out if everyone is authorized.
+     * So we don't want to send the connection setup info yet, since
+     * the auth step isn't really done.
+     */
+    if (client->clientState == ClientStateCheckingSecurity)
+	client->clientState = ClientStateCheckedSecurity;
+    else if (client->clientState != ClientStateAuthenticating)
+	return(SendConnSetup(client, reason));
+    return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 
+                  XID resId, int errorCode)
+{
+    xError rep;
+
+    rep.type = X_Error;
+    rep.sequenceNumber = client->sequence;
+    rep.errorCode = errorCode;
+    rep.majorCode = majorCode;
+    rep.minorCode = minorCode;
+    rep.resourceID = resId;
+
+    WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+DeleteWindowFromAnySelections(WindowPtr pWin)
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].pWin == pWin)
+        {
+	    if (SelectionCallback)
+	    {
+	        SelectionInfoRec    info;
+
+		info.selection = &CurrentSelections[i];
+		info.kind = SelectionWindowDestroy;
+		CallCallbacks(&SelectionCallback, &info);
+	    }
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+static void
+DeleteClientFromAnySelections(ClientPtr client)
+{
+    register int i;
+
+    for (i = 0; i< NumCurrentSelections; i++)
+        if (CurrentSelections[i].client == client)
+        {
+	    if (SelectionCallback)
+	    {
+	        SelectionInfoRec    info;
+
+		info.selection = &CurrentSelections[i];
+		info.kind = SelectionWindowDestroy;
+		CallCallbacks(&SelectionCallback, &info);
+	    }
+            CurrentSelections[i].pWin = (WindowPtr)NULL;
+            CurrentSelections[i].window = None;
+	    CurrentSelections[i].client = NullClient;
+	}
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+    client->noClientException = -1;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
new file mode 100644
index 000000000..6dfff3776
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -0,0 +1,2797 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+/*
+#define NXAGENT_DEBUG
+*/
+
+#ifdef DEBUG
+#include	<stdio.h>
+#endif
+
+#include "Agent.h"
+#include "Font.h"
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+char _NXFontPath[1024];
+
+/*
+ * Override the default font path and make
+ * it configurable at run time, based on
+ * the NX_FONT environment.
+ */
+
+static const char *_NXGetFontPath(const char *path)
+{
+  const char *fontEnv;
+
+    /*
+     * Check the environment only once.
+     */
+
+    if (*_NXFontPath != '\0')
+    {
+        return _NXFontPath;
+    }
+
+    fontEnv = getenv("NX_FONT");
+
+    if (fontEnv != NULL && *fontEnv != '\0')
+    {
+        if (strlen(fontEnv) + 1 > 1024)
+        {
+#ifdef NX_TRANS_TEST
+            fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
+#endif
+            goto _NXGetFontPathError;
+        }
+
+        strcpy(_NXFontPath, fontEnv);
+
+#ifdef NX_TRANS_TEST
+        fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
+#endif
+
+        return _NXFontPath;
+    }
+
+_NXGetFontPathError:
+
+    strcpy(_NXFontPath, path);
+
+#ifdef NX_TRANS_TEST
+    fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
+#endif
+
+    return _NXFontPath;
+}
+
+#endif
+
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int  num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int  num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int  num_slept_fpes = 0;
+static int  size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+    int         err;
+{
+    switch (err) {
+    case Successful:
+	return Success;
+    case AllocError:
+	return BadAlloc;
+    case BadFontName:
+	return BadName;
+    case BadFontPath:
+    case BadFontFormat:	/* is there something better? */
+    case BadCharRange:
+	return BadValue;
+    default:
+	return err;
+    }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+    int         err;
+    FontPtr     pf;
+    XID         fid;
+
+    fid = FakeClientID(0);
+    err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+		   (unsigned) strlen(defaultfontname), defaultfontname);
+    if (err != Success)
+	return FALSE;
+    pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+    if (pf == (FontPtr) NULL)
+	return FALSE;
+    defaultFont = pf;
+    return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted.  this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+    int         i;
+    FontPathElementPtr *new;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+	    return;
+	}
+    }
+    if (num_slept_fpes == size_slept_fpes) {
+	new = (FontPathElementPtr *)
+	    xrealloc(slept_fpes,
+		     sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+	if (!new)
+	    return;
+	slept_fpes = new;
+	size_slept_fpes += 4;
+    }
+    slept_fpes[num_slept_fpes] = fpe;
+    num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+    int         i,
+                j;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+	    for (j = i; j < num_slept_fpes; j++) {
+		slept_fpes[j] = slept_fpes[j + 1];
+	    }
+	    num_slept_fpes--;
+	    return;
+	}
+    }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+    int         i;
+    FontPathElementPtr fpe;
+
+    if (count < 0)
+	return;
+    /* wake up any fpe's that may be waiting for information */
+    for (i = 0; i < num_slept_fpes; i++) {
+	fpe = slept_fpes[i];
+	(void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+    }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+    fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+    fpe->refcount--;
+    if (fpe->refcount == 0) {
+	(*fpe_functions[fpe->type].free_fpe) (fpe);
+	xfree(fpe->name);
+	xfree(fpe);
+    }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+    FontPtr     pfont = NullFont;
+    FontPathElementPtr fpe = NULL;
+    ScreenPtr   pScr;
+    int         err = Successful;
+    int         i;
+    char       *alias,
+               *newname;
+    int         newlen;
+    int		aliascount = 20;
+    char nxagentOrigFontName[256];
+    int nxagentOrigFontNameLen;
+
+    /*
+     * Decide at runtime what FontFormat to use.
+     */
+    Mask FontFormat = 
+
+	((screenInfo.imageByteOrder == LSBFirst) ?
+	    BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+	((screenInfo.bitmapBitOrder == LSBFirst) ?
+	    BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+	BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+	BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+	BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+	BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+	BitmapFormatScanlinePad64 |
+#endif
+
+	BitmapFormatScanlineUnit8;
+
+
+    nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
+
+    memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
+
+    nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    while (c->current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current_fpe];
+	err = (*fpe_functions[fpe->type].open_font)
+	    ((pointer) client, fpe, c->flags,
+	     c->fontname, c->fnamelen, FontFormat,
+	     BitmapFormatMaskByte |
+	     BitmapFormatMaskBit |
+	     BitmapFormatMaskImageRectangle |
+	     BitmapFormatMaskScanLinePad |
+	     BitmapFormatMaskScanLineUnit,
+	     c->fontid, &pfont, &alias,
+	     c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+		 c->non_cachable_font :
+		 (FontPtr)0);
+
+	if (err == FontNameAlias && alias) {
+	    newlen = strlen(alias);
+	    newname = (char *) xrealloc(c->fontname, newlen);
+	    if (!newname) {
+		err = AllocError;
+		break;
+	    }
+	    memmove(newname, alias, newlen);
+	    c->fontname = newname;
+	    c->fnamelen = newlen;
+	    c->current_fpe = 0;
+	    if (--aliascount <= 0)
+		break;
+	    continue;
+	}
+	if (err == BadFontName) {
+	    c->current_fpe++;
+	    continue;
+	}
+	if (err == Suspended) {
+	    if (!c->slept) {
+		c->slept = TRUE;
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+#ifdef NXAGENT_DEBUG
+                fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
+#endif
+	    }
+	    return TRUE;
+	}
+	break;
+    }
+
+    if (err != Successful)
+	goto bail;
+    if (!pfont) {
+	err = BadFontName;
+	goto bail;
+    }
+    if (!pfont->fpe)
+	pfont->fpe = fpe;
+    pfont->refcnt++;
+    if (pfont->refcnt == 1) {
+	UseFPE(pfont->fpe);
+	for (i = 0; i < screenInfo.numScreens; i++) {
+	    pScr = screenInfo.screens[i];
+	    if (pScr->RealizeFont)
+	    {
+
+                /* NXAGENT uses useless screen pointer to pass the original font name
+                *  to realizeFont, could be a source of problems in the future.
+                */
+
+		if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+		{
+		    CloseFont (pfont, (Font) 0);
+		    err=BadFontName;
+		    goto bail;
+		}
+	    }
+	}
+    }
+    if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+	err = AllocError;
+	goto bail;
+    }
+    if( nxagentFontPriv(pfont) -> mirrorID == 0 )
+    {
+      extern RESTYPE RT_NX_FONT;
+
+      nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
+      if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
+        FreeResource(c->fontid, RT_NONE);
+        err = AllocError;
+        goto bail;
+      }
+    }
+    if (patternCache && pfont != c->non_cachable_font)
+	CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+			 pfont);
+bail:
+    if (err != Successful && c->client != serverClient) {
+	SendErrorToClient(c->client, X_OpenFont, 0,
+			  c->fontid, FontToXError(err));
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++) {
+	FreeFPE(c->fpe_list[i]);
+    }
+    xfree(c->fpe_list);
+    xfree(c->fontname);
+    xfree(c);
+    return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+    OFclosurePtr c;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!c)
+	return BadAlloc;
+    c->fontname = (char *) xalloc(lenfname);
+    c->origFontName = pfontname;
+    c->origFontNameLen = lenfname;
+    if (!c->fontname) {
+	xfree(c);
+	return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c->fontname);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove(c->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->fontid = fid;
+    c->current_fpe = 0;
+    c->num_fpes = num_fpes;
+    c->fnamelen = lenfname;
+    c->slept = FALSE;
+    c->flags = flags;
+    c->non_cachable_font = cached;
+
+    (void) doOpenFont(client, c);
+    return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+CloseFont(pointer value, XID fid)
+{
+    int         nscr;
+    ScreenPtr   pscr;
+    FontPathElementPtr fpe;
+    FontPtr     pfont = (FontPtr)value;
+
+    if (pfont == NullFont)
+	return (Success);
+    if (--pfont->refcnt == 0) {
+	if (patternCache)
+	    RemoveCachedFontPattern (patternCache, pfont);
+	/*
+	 * since the last reference is gone, ask each screen to free any
+	 * storage it may have allocated locally for it.
+	 */
+	for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+	    pscr = screenInfo.screens[nscr];
+	    if (pscr->UnrealizeFont)
+		(*pscr->UnrealizeFont) (pscr, pfont);
+	}
+	if (pfont == defaultFont)
+	    defaultFont = NULL;
+#ifdef LBX
+	LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+        {
+           extern void XF86BigfontFreeFontShm(FontPtr);
+           XF86BigfontFreeFontShm(pfont);
+        }
+#endif
+	fpe = pfont->fpe;
+	(*fpe_functions[fpe->type].close_font) (fpe, pfont);
+	FreeFPE(fpe);
+    }
+    return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ *  \param pReply caller must allocate this storage
+  */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+    FontPropPtr      pFP;
+    int              r,
+                     c,
+                     i;
+    xFontProp       *prFP;
+    xCharInfo       *prCI;
+    xCharInfo       *charInfos[256];
+    unsigned char    chars[512];
+    int              ninfos;
+    unsigned long    ncols;
+    unsigned long    count;
+
+    /* pr->length set in dispatch */
+    pReply->minCharOrByte2 = pFont->info.firstCol;
+    pReply->defaultChar = pFont->info.defaultCh;
+    pReply->maxCharOrByte2 = pFont->info.lastCol;
+    pReply->drawDirection = pFont->info.drawDirection;
+    pReply->allCharsExist = pFont->info.allExist;
+    pReply->minByte1 = pFont->info.firstRow;
+    pReply->maxByte1 = pFont->info.lastRow;
+    pReply->fontAscent = pFont->info.fontAscent;
+    pReply->fontDescent = pFont->info.fontDescent;
+
+    pReply->minBounds = pFont->info.ink_minbounds;
+    pReply->maxBounds = pFont->info.ink_maxbounds;
+
+    pReply->nFontProps = pFont->info.nprops;
+    pReply->nCharInfos = nProtoCCIStructs;
+
+    for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+	    i < pFont->info.nprops;
+	    i++, pFP++, prFP++) {
+	prFP->name = pFP->name;
+	prFP->value = pFP->value;
+    }
+
+    ninfos = 0;
+    ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+    prCI = (xCharInfo *) (prFP);
+    for (r = pFont->info.firstRow;
+	    ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+	    r++) {
+	i = 0;
+	for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+	    chars[i++] = r;
+	    chars[i++] = c;
+	}
+	(*pFont->get_metrics) (pFont, ncols, chars, 
+				TwoD16Bit, &count, charInfos);
+	i = 0;
+	for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+	    *prCI = *charInfos[i];
+	    prCI++;
+	    ninfos++;
+	}
+    }
+    return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    FontNamesPtr names = NULL;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int		nnames;
+    int         stringLens;
+    int         i;
+    xListFontsReply reply;
+    char	*bufptr;
+    char	*bufferStart;
+    int		aliascount = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)doListFontsAndAliases,
+			(pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+			memmove(resolved, tmpname, resolvedlen + 1);
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+			(void)AddFontNamesName(c->names, c->savedName,
+					       c->savedNameLen);
+		}
+		else
+		    (void)AddFontNamesName(c->names, name, namelen);
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+			memmove(c->savedName, name, namelen + 1);
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+    if (err != Successful) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+	goto bail;
+    }
+
+finish:
+
+    names = c->names;
+    nnames = names->nnames;
+    client = c->client;
+    stringLens = 0;
+    for (i = 0; i < nnames; i++)
+	stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+    reply.type = X_Reply;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    reply.nFonts = nnames;
+    reply.sequenceNumber = client->sequence;
+
+    bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+    if (!bufptr && reply.length) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+	goto bail;
+    }
+    /*
+     * since WriteToClient long word aligns things, copy to temp buffer and
+     * write all at once
+     */
+    for (i = 0; i < nnames; i++) {
+	if (names->length[i] > 255)
+	    reply.nFonts--;
+	else
+	{
+	    {
+	      /* dirty hack: don't list to client fonts not existing on the remote side */
+	      char tmp[256];
+
+	      memcpy(tmp, names->names[i], names->length[i]);
+	      tmp[ names->length[i] ] = 0;
+
+	      if (nxagentFontLookUp(tmp) == 0)
+		{
+#ifdef NXAGENT_FONTMATCH_DEBUG
+		  fprintf(stderr, "doListFontsAndAliases:\n");
+		  fprintf(stderr, "      removing font: %s \n", tmp);
+#endif
+		  reply.nFonts--;
+		  stringLens -= names->length[i];
+		  continue;
+		}
+	    }
+	    *bufptr++ = names->length[i];
+	    memmove( bufptr, names->names[i], names->length[i]);
+	    bufptr += names->length[i];
+	}
+    }
+    nnames = reply.nFonts;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+    WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+    (void) WriteToClient(client, stringLens + nnames, bufferStart);
+    DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(names);
+    xfree(c);
+    if (resolved) xfree(resolved);
+    return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, 
+          unsigned max_names)
+{
+    int         i;
+    LFclosurePtr c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+	return BadAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsAndAliases(client, c);
+    return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name;
+    int         namelen;
+    int         numFonts;
+    FontInfoRec fontInfo,
+               *pFontInfo;
+    xListFontsWithInfoReply *reply;
+    int         length;
+    xFontProp  *pFP;
+    int         i;
+    int		aliascount = 0;
+    xListFontsWithInfoReply finalReply;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+ 	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+    if (!c->current.patlen)
+	goto finish;
+    while (c->current.current_fpe < c->num_fpes)
+    {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+	if (!c->current.list_started)
+ 	{
+	    err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+		(client, fpe, c->current.pattern, c->current.patlen,
+		 c->current.max_names, &c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	    if (err == Successful)
+		c->current.list_started = TRUE;
+	}
+	if (err == Successful)
+ 	{
+	    name = 0;
+	    pFontInfo = &fontInfo;
+	    err = (*fpe_functions[fpe->type].list_next_font_with_info)
+		(client, fpe, &name, &namelen, &pFontInfo,
+		 &numFonts, c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doListFontsWithInfo,
+			     c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	}
+	/*
+	 * When we get an alias back, save our state and reset back to the
+	 * start of the FPE looking for the specified name.  As soon as a real
+	 * font is found for the alias, pop back to the old state
+	 */
+	if (err == FontNameAlias)
+ 	{
+	    /*
+	     * when an alias recurses, we need to give
+	     * the last FPE a chance to clean up; so we call
+	     * it again, and assume that the error returned
+	     * is BadFontName, indicating the alias resolution
+	     * is complete.
+	     */
+	    if (c->haveSaved)
+	    {
+		char	*tmpname;
+		int	tmpnamelen;
+		FontInfoPtr tmpFontInfo;
+
+	    	tmpname = 0;
+	    	tmpFontInfo = &fontInfo;
+	    	(void) (*fpe_functions[fpe->type].list_next_font_with_info)
+		    (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+		     &numFonts, c->current.private);
+		if (--aliascount <= 0)
+		{
+		    err = BadFontName;
+		    goto ContBadFontName;
+		}
+	    }
+	    else
+	    {
+		c->saved = c->current;
+		c->haveSaved = TRUE;
+		c->savedNumFonts = numFonts;
+		if (c->savedName)
+		  xfree(c->savedName);
+		c->savedName = (char *)xalloc(namelen + 1);
+		if (c->savedName)
+		  memmove(c->savedName, name, namelen + 1);
+		aliascount = 20;
+	    }
+	    memmove(c->current.pattern, name, namelen);
+	    c->current.patlen = namelen;
+	    c->current.max_names = 1;
+	    c->current.current_fpe = 0;
+	    c->current.private = 0;
+	    c->current.list_started = FALSE;
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back.  If we've sent enough font
+	 * names, quit.  Always wait for BadFontName to let the FPE
+	 * have a chance to clean up.
+	 */
+	else if (err == BadFontName)
+ 	{
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+ 	    {
+		if (c->current.max_names == 0 ||
+			c->current.current_fpe == c->num_fpes)
+ 		{
+		    c->haveSaved = FALSE;
+		    c->saved.max_names -= (1 - c->current.max_names);
+		    c->current = c->saved;
+		}
+	    }
+	    else if (c->current.max_names == 0)
+		break;
+	}
+ 	else if (err == Successful)
+ 	{
+
+	    if (c->haveSaved)
+ 	    {
+		numFonts = c->savedNumFonts;
+		name = c->savedName;
+		namelen = strlen(name);
+	    }
+
+	   if (nxagentFontLookUp(name) == 0)
+	   {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "doListFontsAndAliases (with info):\n");
+	      fprintf(stderr, "      removing font: %s \n", name);
+#endif
+	       continue;
+           }
+
+	    length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+	    reply = c->reply;
+	    if (c->length < length)
+ 	    {
+		reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+		if (!reply)
+ 		{
+		    err = AllocError;
+		    break;
+		}
+		c->reply = reply;
+		c->length = length;
+	    }
+	    reply->type = X_Reply;
+	    reply->length = (sizeof *reply - sizeof(xGenericReply) +
+			     pFontInfo->nprops * sizeof(xFontProp) +
+			     namelen + 3) >> 2;
+	    reply->sequenceNumber = client->sequence;
+	    reply->nameLength = namelen;
+	    reply->minBounds = pFontInfo->ink_minbounds;
+	    reply->maxBounds = pFontInfo->ink_maxbounds;
+	    reply->minCharOrByte2 = pFontInfo->firstCol;
+	    reply->maxCharOrByte2 = pFontInfo->lastCol;
+	    reply->defaultChar = pFontInfo->defaultCh;
+	    reply->nFontProps = pFontInfo->nprops;
+	    reply->drawDirection = pFontInfo->drawDirection;
+	    reply->minByte1 = pFontInfo->firstRow;
+	    reply->maxByte1 = pFontInfo->lastRow;
+	    reply->allCharsExist = pFontInfo->allExist;
+	    reply->fontAscent = pFontInfo->fontAscent;
+	    reply->fontDescent = pFontInfo->fontDescent;
+	    reply->nReplies = numFonts;
+	    pFP = (xFontProp *) (reply + 1);
+	    for (i = 0; i < pFontInfo->nprops; i++)
+ 	    {
+		pFP->name = pFontInfo->props[i].name;
+		pFP->value = pFontInfo->props[i].value;
+		pFP++;
+	    }
+	    WriteSwappedDataToClient(client, length, reply);
+	    (void) WriteToClient(client, namelen, name);
+	    if (pFontInfo == &fontInfo)
+ 	    {
+		xfree(fontInfo.props);
+		xfree(fontInfo.isStringProp);
+	    }
+	    --c->current.max_names;
+	}
+    }
+finish:
+    length = sizeof(xListFontsWithInfoReply);
+    bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+    finalReply.type = X_Reply;
+    finalReply.sequenceNumber = client->sequence;
+    finalReply.length = (sizeof(xListFontsWithInfoReply)
+		     - sizeof(xGenericReply)) >> 2;
+    WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->reply);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    xfree(c);
+    return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, 
+                       int max_names)
+{
+    int		    i;
+    LFWIclosurePtr  c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+	goto badAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list)
+    {
+	xfree(c);
+	goto badAlloc;
+    }
+    memmove(c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++)
+    {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->reply = 0;
+    c->length = 0;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->savedNumFonts = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsWithInfo(client, c);
+    return Success;
+badAlloc:
+    return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+    register FontPtr pFont = c->pGC->font, oldpFont;
+    Font	fid, oldfid;
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+    FontPathElementPtr fpe;
+    GC *origGC = NULL;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+	if (c->slept)
+	{
+	    /* Client has died, but we cannot bail out right now.  We
+	       need to clean up after the work we did when going to
+	       sleep.  Setting the drawable pointer to 0 makes this
+	       happen without any attempts to render or perform other
+	       unnecessary activities.  */
+	    c->pDraw = (DrawablePtr)0;
+	}
+	else
+	{
+	    err = Success;
+	    goto bail;
+	}
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client and avoid further
+	   rendering while we clean up after ourself.  */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	c->pDraw = (DrawablePtr)0;
+    }
+
+    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+    while (c->endReq - c->pElt > TextEltHeader)
+    {
+	if (*c->pElt == FontChange)
+        {
+	    if (c->endReq - c->pElt < FontShiftSize)
+	    {
+		 err = BadLength;
+		 goto bail;
+	    }
+
+	    oldpFont = pFont;
+	    oldfid = fid;
+
+	    fid =  ((Font)*(c->pElt+4))		/* big-endian */
+		 | ((Font)*(c->pElt+3)) << 8
+		 | ((Font)*(c->pElt+2)) << 16
+		 | ((Font)*(c->pElt+1)) << 24;
+	    pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+						    SecurityReadAccess);
+	    if (!pFont)
+	    {
+		client->errorValue = fid;
+		err = BadFont;
+		/* restore pFont and fid for step 4 (described below) */
+		pFont = oldpFont;
+		fid = oldfid;
+
+		/* If we're in START_SLEEP mode, the following step
+		   shortens the request...  in the unlikely event that
+		   the fid somehow becomes valid before we come through
+		   again to actually execute the polytext, which would
+		   then mess up our refcounting scheme badly.  */
+		c->err = err;
+		c->endReq = c->pElt;
+
+		goto bail;
+	    }
+
+	    /* Step 3 (described below) on our new font */
+	    if (client_state == START_SLEEP)
+		pFont->refcnt++;
+	    else
+	    {
+		if (pFont != c->pGC->font && c->pDraw)
+		{
+		    ChangeGC( c->pGC, GCFont, &fid);
+		    ValidateGC(c->pDraw, c->pGC);
+		    if (c->reqType == X_PolyText8)
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+		    else
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+		}
+
+		/* Undo the refcnt++ we performed when going to sleep */
+		if (client_state == SLEEPING)
+		    (void)CloseFont(c->pGC->font, (Font)0);
+	    }
+	    c->pElt += FontShiftSize;
+	}
+	else	/* print a string */
+	{
+	    unsigned char *pNextElt;
+	    pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+	    if ( pNextElt > c->endReq)
+	    {
+		err = BadLength;
+		goto bail;
+	    }
+	    if (client_state == START_SLEEP)
+	    {
+		c->pElt = pNextElt;
+		continue;
+	    }
+	    if (c->pDraw)
+	    {
+		lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+				   c->pElt + TextEltHeader);
+	    }
+	    else lgerr = Successful;
+
+	    if (lgerr == Suspended)
+	    {
+		if (!c->slept) {
+		    int len;
+		    GC *pGC;
+		    PTclosurePtr new_closure;
+
+    /*  We're putting the client to sleep.  We need to do a few things
+	to ensure successful and atomic-appearing execution of the
+	remainder of the request.  First, copy the remainder of the
+	request into a safe malloc'd area.  Second, create a scratch GC
+	to use for the remainder of the request.  Third, mark all fonts
+	referenced in the remainder of the request to prevent their
+	deallocation.  Fourth, make the original GC look like the
+	request has completed...  set its font to the final font value
+	from this request.  These GC manipulations are for the unlikely
+	(but possible) event that some other client is using the GC.
+	Steps 3 and 4 are performed by running this procedure through
+	the remainder of the request in a special no-render mode
+	indicated by client_state = START_SLEEP.  */
+
+		    /* Step 1 */
+		    /* Allocate a malloc'd closure structure to replace
+		       the local one we were passed */
+		    new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+		    if (!new_closure)
+		    {
+			err = BadAlloc;
+			goto bail;
+		    }
+		    *new_closure = *c;
+		    c = new_closure;
+
+		    len = c->endReq - c->pElt;
+		    c->data = (unsigned char *)xalloc(len);
+		    if (!c->data)
+		    {
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    memmove(c->data, c->pElt, len);
+		    c->pElt = c->data;
+		    c->endReq = c->pElt + len;
+
+		    /* Step 2 */
+
+		    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+		    if (!pGC)
+		    {
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+
+                    pGC->tileIsPixel = TRUE;
+                    pGC->tile.pixel = 0;
+                    pGC->stipple = NullPixmap;
+
+		    if ((err = CopyGC(c->pGC, pGC, GCFunction |
+				      GCPlaneMask | GCForeground |
+				      GCBackground | GCFillStyle |
+				      GCTile | GCStipple |
+				      GCTileStipXOrigin |
+				      GCTileStipYOrigin | GCFont |
+				      GCSubwindowMode | GCClipXOrigin |
+				      GCClipYOrigin | GCClipMask)) !=
+				      Success)
+		    {
+			FreeScratchGC(pGC);
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    origGC = c->pGC;
+		    c->pGC = pGC;
+		    ValidateGC(c->pDraw, c->pGC);
+		    
+		    c->slept = TRUE;
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doPolyText,
+			     (pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
+#endif
+
+		    /* Set up to perform steps 3 and 4 */
+		    client_state = START_SLEEP;
+		    continue;	/* on to steps 3 and 4 */
+		}
+		return TRUE;
+	    }
+	    else if (lgerr != Successful)
+	    {
+		err = FontToXError(lgerr);
+		goto bail;
+	    }
+	    if (c->pDraw)
+	    {
+		c->xorg += *((INT8 *)(c->pElt + 1));	/* must be signed */
+		c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+		    *c->pElt, c->pElt + TextEltHeader);
+	    }
+	    c->pElt = pNextElt;
+	}
+    }
+
+bail:
+
+    if (client_state == START_SLEEP)
+    {
+	/* Step 4 */
+	if (pFont != origGC->font)
+	{
+	    ChangeGC(origGC, GCFont, &fid);
+	    ValidateGC(c->pDraw, origGC);
+	}
+
+	/* restore pElt pointer for execution of remainder of the request */
+	c->pElt = c->data;
+	return TRUE;
+    }
+
+    if (c->err != Success) err = c->err;
+    if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+        if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt, 
+         unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+    PTclosureRec local_closure;
+
+    local_closure.pElt = pElt;
+    local_closure.endReq = endReq;
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_PolyText8)
+    {
+	local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.polyText =  (PolyTextPtr) pGC->ops->PolyText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.pGC = pGC;
+    local_closure.did = did;
+    local_closure.err = Success;
+    local_closure.slept = FALSE;
+
+    (void) doPolyText(client, &local_closure);
+    return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    FontPathElementPtr fpe;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client. */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+    if (lgerr == Suspended)
+    {
+        if (!c->slept) {
+	    GC *pGC;
+	    unsigned char *data;
+	    ITclosurePtr new_closure;
+
+	    /* We're putting the client to sleep.  We need to
+	       save some state.  Similar problem to that handled
+	       in doPolyText, but much simpler because the
+	       request structure is much simpler. */
+
+	    new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+	    if (!new_closure)
+	    {
+		err = BadAlloc;
+		goto bail;
+	    }
+	    *new_closure = *c;
+	    c = new_closure;
+
+	    data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+	    if (!data)
+	    {
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    memmove(data, c->data, c->nChars * c->itemSize);
+	    c->data = data;
+
+	    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+	    if (!pGC)
+	    {
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+
+            pGC->tileIsPixel = TRUE;
+            pGC->tile.pixel = 0;
+            pGC->stipple = NullPixmap;
+
+	    if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+			      GCForeground | GCBackground | GCFillStyle |
+			      GCTile | GCStipple | GCTileStipXOrigin |
+			      GCTileStipYOrigin | GCFont |
+			      GCSubwindowMode | GCClipXOrigin |
+			      GCClipYOrigin | GCClipMask)) != Success)
+	    {
+		FreeScratchGC(pGC);
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    c->pGC = pGC;
+	    ValidateGC(c->pDraw, c->pGC);
+
+	    c->slept = TRUE;
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+#ifdef NXAGENT_DEBUG
+            fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
+#endif
+
+        }
+        return TRUE;
+    }
+    else if (lgerr != Successful)
+    {
+        err = FontToXError(lgerr);
+        goto bail;
+    }
+    if (c->pDraw)
+    {
+	(* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+	    c->nChars, c->data);
+    }
+
+bail:
+
+    if (err != Success && c->client != serverClient) {
+	SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars, 
+          unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+    ITclosureRec local_closure;
+
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.pGC = pGC;
+    local_closure.nChars = nChars;
+    local_closure.data = data;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_ImageText8)
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.did = did;
+    local_closure.slept = FALSE;
+
+    (void) doImageText(client, &local_closure);
+    return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+    int         i;
+
+    for (i = 0; i < num_fpe_types; i++) {
+	if ((*fpe_functions[i].name_check) (pathname))
+	    return i;
+    }
+    return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+    int         i;
+
+    for (i = 0; i < n; i++) {
+	if (force) {
+	    /* Sanity check that all refcounts will be 0 by the time
+	       we get to the end of the list. */
+	    int found = 1;	/* the first reference is us */
+	    int j;
+	    for (j = i+1; j < n; j++) {
+		if (list[j] == list[i])
+		    found++;
+	    }
+	    if (list[i]->refcount != found) {
+		ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+		       list[i]->name_length, list[i]->name,
+		       list[i]->refcount, found);
+		list[i]->refcount = found; /* ensure it will get freed */
+	    }
+	}
+	FreeFPE(list[i]);
+    }
+    xfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+    FontPathElementPtr fpe;
+    int         i;
+
+    for (i = 0; i < num; i++) {
+	fpe = list[i];
+	if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+	    return fpe;
+    }
+    return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+    int         i, err = 0;
+    int         valid_paths = 0;
+    unsigned int len;
+    unsigned char *cp = paths;
+    FontPathElementPtr fpe = NULL, *fplist;
+
+    fplist = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * npaths);
+    if (!fplist) {
+	*bad = 0;
+	return BadAlloc;
+    }
+    for (i = 0; i < num_fpe_types; i++) {
+	if (fpe_functions[i].set_path_hook)
+	    (*fpe_functions[i].set_path_hook) ();
+    }
+    for (i = 0; i < npaths; i++) 
+    {
+	len = (unsigned int) (*cp++);
+
+	if (len == 0) 
+	{
+	    if (persist)
+		ErrorF ("Removing empty element from the valid list of fontpaths\n");
+	    err = BadValue;
+	}
+	else
+	{
+	    /* if it's already in our active list, just reset it */
+	    /*
+	     * note that this can miss FPE's in limbo -- may be worth catching
+	     * them, though it'd muck up refcounting
+	     */
+	    fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+	    if (fpe) 
+	    {
+		err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+		if (err == Successful) 
+		{
+		    UseFPE(fpe);/* since it'll be decref'd later when freed
+				 * from the old list */
+		}
+		else
+		    fpe = 0;
+	    }
+	    /* if error or can't do it, act like it's a new one */
+	    if (!fpe)
+	    {
+		fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+		if (!fpe) 
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->name = (char *) xalloc(len + 1);
+		if (!fpe->name) 
+		{
+		    xfree(fpe);
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->refcount = 1;
+    
+		strncpy(fpe->name, (char *) cp, (int) len);
+		fpe->name[len] = '\0';
+		fpe->name_length = len;
+		fpe->type = DetermineFPEType(fpe->name);
+		if (fpe->type == -1)
+		    err = BadValue;
+		else
+		    err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+		if (err != Successful)
+		{
+                    #ifndef NXAGENT_SERVER
+		    if (persist)
+		    {
+			ErrorF("Could not init font path element %s, removing from list!\n",
+			       fpe->name);
+		    }
+                    #endif
+		    xfree (fpe->name);
+		    xfree (fpe);
+		}
+	    }
+	}
+	if (err != Successful)
+	{
+	    if (!persist)
+		goto bail;
+	}
+	else
+	{
+	    fplist[valid_paths++] = fpe;
+	}
+	cp += len;
+    }
+
+    FreeFontPath(font_path_elements, num_fpes, FALSE);
+    font_path_elements = fplist;
+    if (patternCache)
+	EmptyFontPatternCache(patternCache);
+    num_fpes = valid_paths;
+
+    return Success;
+bail:
+    *bad = i;
+    while (--valid_paths >= 0)
+	FreeFPE(fplist[valid_paths]);
+    xfree(fplist);
+    return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+    int   err = Success;
+
+    if (npaths == 0) {
+	if (SetDefaultFontPath(defaultFontPath) != Success)
+	    return BadValue;
+    } else {
+	err = SetFontPathElements(npaths, paths, error, FALSE);
+    }
+    return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+    unsigned char *cp,
+               *pp,
+               *nump,
+               *newpath;
+    int         num = 1,
+                len,
+                err,
+                size = 0,
+                bad;
+
+    /* get enough for string, plus values -- use up commas */
+#ifdef NX_TRANS_SOCKET
+    len = strlen(_NXGetFontPath(path)) + 1;
+#else
+    len = strlen(path) + 1;
+#endif
+    nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+    if (!newpath)
+	return BadAlloc;
+#ifdef NX_TRANS_SOCKET
+    pp = (unsigned char *) _NXGetFontPath(path);
+#else
+    pp = (unsigned char *) path;
+#endif
+    cp++;
+    while (*pp) {
+	if (*pp == ',') {
+	    *nump = (unsigned char) size;
+	    nump = cp++;
+	    pp++;
+	    num++;
+	    size = 0;
+	} else {
+	    *cp++ = *pp++;
+	    size++;
+	}
+    }
+    *nump = (unsigned char) size;
+
+    err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+    DEALLOCATE_LOCAL(newpath);
+
+    return err;
+}
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+    int			i;
+    unsigned char       *c;
+    int			len;
+    FontPathElementPtr	fpe;
+
+    len = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	len += fpe->name_length + 1;
+    }
+    font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+    if (!font_path_string)
+	return NULL;
+
+    c = font_path_string;
+    *length = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	*c = fpe->name_length;
+	*length += *c++;
+	memmove(c, fpe->name, fpe->name_length);
+	c += fpe->name_length;
+    }
+    *count = num_fpes;
+    return font_path_string;
+}
+
+int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+    if (fpe_functions[pfont->fpe->type].load_glyphs)
+	return (*fpe_functions[pfont->fpe->type].load_glyphs)
+	    (client, pfont, 0, nchars, item_size, data);
+    else
+	return Successful;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+    int			i;
+    FontPathElementPtr	fpe;
+
+    for (i = 0; i < num_fpes; i++)
+    {
+	fpe = font_path_elements[i];
+	if (fpe_functions[fpe->type].client_died)
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+    }
+}
+
+void
+InitFonts ()
+{
+    patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+    if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+	PrinterFontRegisterFpeFunctions();
+	FontFileCheckRegisterFpeFunctions();
+	check_fs_register_fpe_functions();
+    } else 
+#endif
+    {
+#ifdef KDRIVESERVER
+	BuiltinRegisterFpeFunctions();
+#endif
+	FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+	fs_register_fpe_functions();
+#endif
+    }
+}
+
+int
+GetDefaultPointSize ()
+{
+    return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+    if (requestingClient && requestingClient->fontResFunc != NULL &&
+	!requestingClient->clientGone)
+    {
+	return (*requestingClient->fontResFunc)(requestingClient, num);
+    }
+    else {
+	static struct _FontResolution res;
+	ScreenPtr   pScreen;
+
+	pScreen = screenInfo.screens[0];
+	res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+	/*
+	 * XXX - we'll want this as long as bitmap instances are prevalent 
+	 so that we can match them from scalable fonts
+	 */
+	if (res.x_resolution < 88)
+	    res.x_resolution = 75;
+	else
+	    res.x_resolution = 100;
+	res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+	if (res.y_resolution < 88)
+	    res.y_resolution = 75;
+	else
+	    res.y_resolution = 100;
+	res.point_size = 120;
+	*num = 1;
+	return &res;
+    }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func, 
+		     InitFpeFunc init_func, 
+		     FreeFpeFunc free_func, 
+		     ResetFpeFunc reset_func, 
+		     OpenFontFunc open_func, 
+		     CloseFontFunc close_func, 
+		     ListFontsFunc list_func, 
+		     StartLfwiFunc start_lfwi_func, 
+		     NextLfwiFunc next_lfwi_func, 
+		     WakeupFpeFunc wakeup_func, 
+		     ClientDiedFunc client_died, 
+		     LoadGlyphsFunc load_glyphs, 
+		     StartLaFunc start_list_alias_func, 
+		     NextLaFunc next_list_alias_func, 
+		     SetPathFunc set_path_func)
+{
+    FPEFunctions *new;
+
+    /* grow the list */
+    new = (FPEFunctions *) xrealloc(fpe_functions,
+				 (num_fpe_types + 1) * sizeof(FPEFunctions));
+    if (!new)
+	return -1;
+    fpe_functions = new;
+
+    fpe_functions[num_fpe_types].name_check = name_func;
+    fpe_functions[num_fpe_types].open_font = open_func;
+    fpe_functions[num_fpe_types].close_font = close_func;
+    fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+    fpe_functions[num_fpe_types].list_fonts = list_func;
+    fpe_functions[num_fpe_types].start_list_fonts_with_info =
+	start_lfwi_func;
+    fpe_functions[num_fpe_types].list_next_font_with_info =
+	next_lfwi_func;
+    fpe_functions[num_fpe_types].init_fpe = init_func;
+    fpe_functions[num_fpe_types].free_fpe = free_func;
+    fpe_functions[num_fpe_types].reset_fpe = reset_func;
+    fpe_functions[num_fpe_types].client_died = client_died;
+    fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+    fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+	start_list_alias_func;
+    fpe_functions[num_fpe_types].list_next_font_or_alias =
+	next_list_alias_func;
+    fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+    return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+    if (patternCache) {
+	FreeFontPatternCache(patternCache);
+	patternCache = 0;
+    }
+    FreeFontPath(font_path_elements, num_fpes, TRUE);
+    font_path_elements = 0;
+    num_fpes = 0;
+    xfree(fpe_functions);
+    num_fpe_types = 0;
+    fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+    return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+					    SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+    return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+    return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+    FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+    return 0;
+}
+
+static int  fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+    /* if server has reset, make sure the b&w handlers are reinstalled */
+    if (last_server_gen < serverGeneration) {
+	last_server_gen = serverGeneration;
+	fs_handlers_installed = 0;
+    }
+    if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+	if (!RegisterBlockAndWakeupHandlers(block_handler,
+					    FontWakeup, (pointer) 0))
+	    return AllocError;
+	fs_handlers_installed++;
+    }
+    QueueFontWakeup(fpe);
+    return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+    if (all) {
+	/* remove the handlers if no one else is using them */
+	if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+	    RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+					 (pointer) 0);
+	}
+    }
+    RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+	((nbytes) == 1 ? (((bits)+7)>>3)        /* pad to 1 byte */ \
+	:(nbytes) == 2 ? ((((bits)+15)>>3)&~1)  /* pad to 2 bytes */ \
+	:(nbytes) == 4 ? ((((bits)+31)>>3)&~3)  /* pad to 4 bytes */ \
+	:(nbytes) == 8 ? ((((bits)+63)>>3)&~7)  /* pad to 8 bytes */ \
+	: 0)
+
+#define GLYPH_SIZE(ch, nbytes)          \
+	GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+			(ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+    int         r,
+                l;
+    int         bpr;
+    int         byte;
+    static unsigned maskTab[] = {
+	(1 << 7), (1 << 6), (1 << 5), (1 << 4),
+	(1 << 3), (1 << 2), (1 << 1), (1 << 0),
+    };
+
+    bpr = GLYPH_SIZE(cip, 4);
+    for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+	pointer     row = (pointer) cip->bits + r * bpr;
+
+	byte = 0;
+	for (l = 0; l <= (cip->metrics.rightSideBearing -
+			  cip->metrics.leftSideBearing); l++) {
+	    if (maskTab[l & 7] & row[l >> 3])
+		putchar('X');
+	    else
+		putchar('.');
+	}
+	putchar('\n');
+    }
+}
+
+#endif
+
+
+typedef struct
+{
+   LFclosurePtr c;
+   OFclosurePtr oc;
+} nxFs,*nxFsPtr;
+
+static Bool
+#if NeedFunctionPrototypes
+nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
+#else
+nxdoListFontsAndAliases(client, fss)
+    ClientPtr   client;
+    nxFsPtr fss;
+#endif
+{
+    LFclosurePtr c=fss->c;
+    OFclosurePtr oc=fss->oc;
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int         i;
+    int		aliascount = 0;
+    char        tmp[256];
+    tmp[0]=0;
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)nxdoListFontsAndAliases,
+			(pointer) fss);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+                    {
+                        memmove(resolved, tmpname, resolvedlen);
+                        resolved[resolvedlen] = '\0';
+                    }
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+		    {
+		       memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
+		       tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
+		       if (nxagentFontLookUp(tmp))
+		          break;
+			else tmp[0]=0;
+		    }
+		}
+		else
+		{
+		   memcpy(tmp,name,namelen>255?255:namelen);
+		   tmp[namelen>255?256:namelen]=0;
+		   if (nxagentFontLookUp(tmp))
+		      break;
+		   else tmp[0]=0;
+		}
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+                    {
+                        memmove(c->savedName, name, namelen);
+                        c->savedName[namelen] = '\0';
+                    }
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+bail:
+finish:
+    if (strlen(tmp))
+    {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+      fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
+#endif
+      memcpy(oc->fontname, tmp, strlen(tmp));
+      oc->fnamelen = strlen(tmp);
+
+      oc->origFontName = oc->fontname;
+      oc->origFontNameLen = oc->fnamelen;
+
+    }
+    else
+    {
+        for (i = 0; i < c->names->nnames; i++)
+	{
+	  if (c->names->length[i] > 255)
+	     continue;
+	  else
+	  {
+	      memcpy(tmp, c->names->names[i], c->names->length[i]);
+	      tmp[ c->names->length[i] ] = 0;
+	      if (nxagentFontLookUp(tmp) == 0)
+		continue;
+	      memcpy(oc->fontname, tmp, strlen(tmp));
+	      oc->fnamelen = strlen(tmp);
+
+              oc->origFontName = oc->fontname;
+              oc->origFontNameLen = oc->fnamelen;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
+#endif
+	      break;
+	  }
+	}
+    }
+
+    if (c->slept)
+    {
+       ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+       fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(c->names);
+    xfree(c);
+    xfree(fss);
+    if (resolved) xfree(resolved);
+
+    return doOpenFont(client, oc);
+}
+
+int
+nxOpenFont(client, fid, flags, lenfname, pfontname)
+    ClientPtr   client;
+    XID         fid;
+    Mask        flags;
+    unsigned    lenfname;
+    char       *pfontname;
+{
+    nxFsPtr      fss;
+    LFclosurePtr c;
+    OFclosurePtr oc;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
+        return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+    {
+	xfree(fss);
+	return BadAlloc;
+    }
+        c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(100);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = lenfname;
+    c->current.current_fpe = 0;
+    c->current.max_names = nxagentMaxFontNames;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+
+    oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!oc)
+    {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(fss);
+      return BadAlloc;
+    }
+    oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
+    oc->origFontName = pfontname;
+    oc->origFontNameLen = lenfname;
+    if (!oc->fontname) {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(oc);
+      xfree(fss);
+      return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    oc->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!oc->fpe_list) {
+	xfree(oc->fontname);
+	xfree(oc);
+      for (i = 0; i < c->num_fpes; i++)
+         FreeFPE(c->fpe_list[i]);
+       xfree(c->fpe_list);
+       xfree(c);
+       xfree(fss);
+       return BadAlloc;
+    }
+    memmove(oc->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	oc->fpe_list[i] = font_path_elements[i];
+	UseFPE(oc->fpe_list[i]);
+    }
+    oc->client = client;
+    oc->fontid = fid;
+    oc->current_fpe = 0;
+    oc->num_fpes = num_fpes;
+    oc->fnamelen = lenfname;
+    oc->slept = FALSE;
+    oc->flags = flags;
+    oc->non_cachable_font = cached;
+    fss->c=c;
+    fss->oc=oc;
+    nxdoListFontsAndAliases(client, fss);
+    return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
new file mode 100644
index 000000000..6dfff3776
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -0,0 +1,2797 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+/*
+#define NXAGENT_DEBUG
+*/
+
+#ifdef DEBUG
+#include	<stdio.h>
+#endif
+
+#include "Agent.h"
+#include "Font.h"
+
+#ifndef NX_TRANS_SOCKET
+
+#define NX_TRANS_SOCKET
+
+#endif
+
+#ifdef NX_TRANS_SOCKET
+
+char _NXFontPath[1024];
+
+/*
+ * Override the default font path and make
+ * it configurable at run time, based on
+ * the NX_FONT environment.
+ */
+
+static const char *_NXGetFontPath(const char *path)
+{
+  const char *fontEnv;
+
+    /*
+     * Check the environment only once.
+     */
+
+    if (*_NXFontPath != '\0')
+    {
+        return _NXFontPath;
+    }
+
+    fontEnv = getenv("NX_FONT");
+
+    if (fontEnv != NULL && *fontEnv != '\0')
+    {
+        if (strlen(fontEnv) + 1 > 1024)
+        {
+#ifdef NX_TRANS_TEST
+            fprintf(stderr, "_NXGetFontPath: WARNING! Maximum length of font path exceeded.\n");
+#endif
+            goto _NXGetFontPathError;
+        }
+
+        strcpy(_NXFontPath, fontEnv);
+
+#ifdef NX_TRANS_TEST
+        fprintf(stderr, "_NXGetFontPath: Using NX font path [%s].\n", _NXFontPath);
+#endif
+
+        return _NXFontPath;
+    }
+
+_NXGetFontPathError:
+
+    strcpy(_NXFontPath, path);
+
+#ifdef NX_TRANS_TEST
+    fprintf(stderr, "_NXGetFontPath: Using default font path [%s].\n", _NXFontPath);
+#endif
+
+    return _NXFontPath;
+}
+
+#endif
+
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int  num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int  num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int  num_slept_fpes = 0;
+static int  size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+    int         err;
+{
+    switch (err) {
+    case Successful:
+	return Success;
+    case AllocError:
+	return BadAlloc;
+    case BadFontName:
+	return BadName;
+    case BadFontPath:
+    case BadFontFormat:	/* is there something better? */
+    case BadCharRange:
+	return BadValue;
+    default:
+	return err;
+    }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+    int         err;
+    FontPtr     pf;
+    XID         fid;
+
+    fid = FakeClientID(0);
+    err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+		   (unsigned) strlen(defaultfontname), defaultfontname);
+    if (err != Success)
+	return FALSE;
+    pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+    if (pf == (FontPtr) NULL)
+	return FALSE;
+    defaultFont = pf;
+    return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted.  this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+    int         i;
+    FontPathElementPtr *new;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+	    return;
+	}
+    }
+    if (num_slept_fpes == size_slept_fpes) {
+	new = (FontPathElementPtr *)
+	    xrealloc(slept_fpes,
+		     sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+	if (!new)
+	    return;
+	slept_fpes = new;
+	size_slept_fpes += 4;
+    }
+    slept_fpes[num_slept_fpes] = fpe;
+    num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+    int         i,
+                j;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+	    for (j = i; j < num_slept_fpes; j++) {
+		slept_fpes[j] = slept_fpes[j + 1];
+	    }
+	    num_slept_fpes--;
+	    return;
+	}
+    }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+    int         i;
+    FontPathElementPtr fpe;
+
+    if (count < 0)
+	return;
+    /* wake up any fpe's that may be waiting for information */
+    for (i = 0; i < num_slept_fpes; i++) {
+	fpe = slept_fpes[i];
+	(void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+    }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+    fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+    fpe->refcount--;
+    if (fpe->refcount == 0) {
+	(*fpe_functions[fpe->type].free_fpe) (fpe);
+	xfree(fpe->name);
+	xfree(fpe);
+    }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+    FontPtr     pfont = NullFont;
+    FontPathElementPtr fpe = NULL;
+    ScreenPtr   pScr;
+    int         err = Successful;
+    int         i;
+    char       *alias,
+               *newname;
+    int         newlen;
+    int		aliascount = 20;
+    char nxagentOrigFontName[256];
+    int nxagentOrigFontNameLen;
+
+    /*
+     * Decide at runtime what FontFormat to use.
+     */
+    Mask FontFormat = 
+
+	((screenInfo.imageByteOrder == LSBFirst) ?
+	    BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+	((screenInfo.bitmapBitOrder == LSBFirst) ?
+	    BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+	BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+	BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+	BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+	BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+	BitmapFormatScanlinePad64 |
+#endif
+
+	BitmapFormatScanlineUnit8;
+
+
+    nxagentOrigFontNameLen = (c -> origFontNameLen < 256) ? c -> origFontNameLen : 255;
+
+    memcpy(nxagentOrigFontName, c -> origFontName, nxagentOrigFontNameLen);
+
+    nxagentOrigFontName[nxagentOrigFontNameLen] = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    while (c->current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current_fpe];
+	err = (*fpe_functions[fpe->type].open_font)
+	    ((pointer) client, fpe, c->flags,
+	     c->fontname, c->fnamelen, FontFormat,
+	     BitmapFormatMaskByte |
+	     BitmapFormatMaskBit |
+	     BitmapFormatMaskImageRectangle |
+	     BitmapFormatMaskScanLinePad |
+	     BitmapFormatMaskScanLineUnit,
+	     c->fontid, &pfont, &alias,
+	     c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+		 c->non_cachable_font :
+		 (FontPtr)0);
+
+	if (err == FontNameAlias && alias) {
+	    newlen = strlen(alias);
+	    newname = (char *) xrealloc(c->fontname, newlen);
+	    if (!newname) {
+		err = AllocError;
+		break;
+	    }
+	    memmove(newname, alias, newlen);
+	    c->fontname = newname;
+	    c->fnamelen = newlen;
+	    c->current_fpe = 0;
+	    if (--aliascount <= 0)
+		break;
+	    continue;
+	}
+	if (err == BadFontName) {
+	    c->current_fpe++;
+	    continue;
+	}
+	if (err == Suspended) {
+	    if (!c->slept) {
+		c->slept = TRUE;
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+#ifdef NXAGENT_DEBUG
+                fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] sleeping.\n", client);
+#endif
+	    }
+	    return TRUE;
+	}
+	break;
+    }
+
+    if (err != Successful)
+	goto bail;
+    if (!pfont) {
+	err = BadFontName;
+	goto bail;
+    }
+    if (!pfont->fpe)
+	pfont->fpe = fpe;
+    pfont->refcnt++;
+    if (pfont->refcnt == 1) {
+	UseFPE(pfont->fpe);
+	for (i = 0; i < screenInfo.numScreens; i++) {
+	    pScr = screenInfo.screens[i];
+	    if (pScr->RealizeFont)
+	    {
+
+                /* NXAGENT uses useless screen pointer to pass the original font name
+                *  to realizeFont, could be a source of problems in the future.
+                */
+
+		if (!(*pScr->RealizeFont) ((ScreenPtr)nxagentOrigFontName, pfont))
+		{
+		    CloseFont (pfont, (Font) 0);
+		    err=BadFontName;
+		    goto bail;
+		}
+	    }
+	}
+    }
+    if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+	err = AllocError;
+	goto bail;
+    }
+    if( nxagentFontPriv(pfont) -> mirrorID == 0 )
+    {
+      extern RESTYPE RT_NX_FONT;
+
+      nxagentFontPriv(pfont) -> mirrorID = FakeClientID(0);
+      if (!AddResource(nxagentFontPriv(pfont) -> mirrorID, RT_NX_FONT, (pointer) pfont)) {
+        FreeResource(c->fontid, RT_NONE);
+        err = AllocError;
+        goto bail;
+      }
+    }
+    if (patternCache && pfont != c->non_cachable_font)
+	CacheFontPattern(patternCache, nxagentOrigFontName, nxagentOrigFontNameLen,
+			 pfont);
+bail:
+    if (err != Successful && c->client != serverClient) {
+	SendErrorToClient(c->client, X_OpenFont, 0,
+			  c->fontid, FontToXError(err));
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doOpenFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++) {
+	FreeFPE(c->fpe_list[i]);
+    }
+    xfree(c->fpe_list);
+    xfree(c->fontname);
+    xfree(c);
+    return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+    OFclosurePtr c;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!c)
+	return BadAlloc;
+    c->fontname = (char *) xalloc(lenfname);
+    c->origFontName = pfontname;
+    c->origFontNameLen = lenfname;
+    if (!c->fontname) {
+	xfree(c);
+	return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c->fontname);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove(c->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->fontid = fid;
+    c->current_fpe = 0;
+    c->num_fpes = num_fpes;
+    c->fnamelen = lenfname;
+    c->slept = FALSE;
+    c->flags = flags;
+    c->non_cachable_font = cached;
+
+    (void) doOpenFont(client, c);
+    return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+CloseFont(pointer value, XID fid)
+{
+    int         nscr;
+    ScreenPtr   pscr;
+    FontPathElementPtr fpe;
+    FontPtr     pfont = (FontPtr)value;
+
+    if (pfont == NullFont)
+	return (Success);
+    if (--pfont->refcnt == 0) {
+	if (patternCache)
+	    RemoveCachedFontPattern (patternCache, pfont);
+	/*
+	 * since the last reference is gone, ask each screen to free any
+	 * storage it may have allocated locally for it.
+	 */
+	for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+	    pscr = screenInfo.screens[nscr];
+	    if (pscr->UnrealizeFont)
+		(*pscr->UnrealizeFont) (pscr, pfont);
+	}
+	if (pfont == defaultFont)
+	    defaultFont = NULL;
+#ifdef LBX
+	LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+        {
+           extern void XF86BigfontFreeFontShm(FontPtr);
+           XF86BigfontFreeFontShm(pfont);
+        }
+#endif
+	fpe = pfont->fpe;
+	(*fpe_functions[fpe->type].close_font) (fpe, pfont);
+	FreeFPE(fpe);
+    }
+    return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ *  \param pReply caller must allocate this storage
+  */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+    FontPropPtr      pFP;
+    int              r,
+                     c,
+                     i;
+    xFontProp       *prFP;
+    xCharInfo       *prCI;
+    xCharInfo       *charInfos[256];
+    unsigned char    chars[512];
+    int              ninfos;
+    unsigned long    ncols;
+    unsigned long    count;
+
+    /* pr->length set in dispatch */
+    pReply->minCharOrByte2 = pFont->info.firstCol;
+    pReply->defaultChar = pFont->info.defaultCh;
+    pReply->maxCharOrByte2 = pFont->info.lastCol;
+    pReply->drawDirection = pFont->info.drawDirection;
+    pReply->allCharsExist = pFont->info.allExist;
+    pReply->minByte1 = pFont->info.firstRow;
+    pReply->maxByte1 = pFont->info.lastRow;
+    pReply->fontAscent = pFont->info.fontAscent;
+    pReply->fontDescent = pFont->info.fontDescent;
+
+    pReply->minBounds = pFont->info.ink_minbounds;
+    pReply->maxBounds = pFont->info.ink_maxbounds;
+
+    pReply->nFontProps = pFont->info.nprops;
+    pReply->nCharInfos = nProtoCCIStructs;
+
+    for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+	    i < pFont->info.nprops;
+	    i++, pFP++, prFP++) {
+	prFP->name = pFP->name;
+	prFP->value = pFP->value;
+    }
+
+    ninfos = 0;
+    ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+    prCI = (xCharInfo *) (prFP);
+    for (r = pFont->info.firstRow;
+	    ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+	    r++) {
+	i = 0;
+	for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+	    chars[i++] = r;
+	    chars[i++] = c;
+	}
+	(*pFont->get_metrics) (pFont, ncols, chars, 
+				TwoD16Bit, &count, charInfos);
+	i = 0;
+	for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+	    *prCI = *charInfos[i];
+	    prCI++;
+	    ninfos++;
+	}
+    }
+    return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    FontNamesPtr names = NULL;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int		nnames;
+    int         stringLens;
+    int         i;
+    xListFontsReply reply;
+    char	*bufptr;
+    char	*bufferStart;
+    int		aliascount = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)doListFontsAndAliases,
+			(pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (2): client [%lx] sleeping.\n", client);
+#endif
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: doListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+			memmove(resolved, tmpname, resolvedlen + 1);
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+			(void)AddFontNamesName(c->names, c->savedName,
+					       c->savedNameLen);
+		}
+		else
+		    (void)AddFontNamesName(c->names, name, namelen);
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+			memmove(c->savedName, name, namelen + 1);
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+    if (err != Successful) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+	goto bail;
+    }
+
+finish:
+
+    names = c->names;
+    nnames = names->nnames;
+    client = c->client;
+    stringLens = 0;
+    for (i = 0; i < nnames; i++)
+	stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+    reply.type = X_Reply;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    reply.nFonts = nnames;
+    reply.sequenceNumber = client->sequence;
+
+    bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+    if (!bufptr && reply.length) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+	goto bail;
+    }
+    /*
+     * since WriteToClient long word aligns things, copy to temp buffer and
+     * write all at once
+     */
+    for (i = 0; i < nnames; i++) {
+	if (names->length[i] > 255)
+	    reply.nFonts--;
+	else
+	{
+	    {
+	      /* dirty hack: don't list to client fonts not existing on the remote side */
+	      char tmp[256];
+
+	      memcpy(tmp, names->names[i], names->length[i]);
+	      tmp[ names->length[i] ] = 0;
+
+	      if (nxagentFontLookUp(tmp) == 0)
+		{
+#ifdef NXAGENT_FONTMATCH_DEBUG
+		  fprintf(stderr, "doListFontsAndAliases:\n");
+		  fprintf(stderr, "      removing font: %s \n", tmp);
+#endif
+		  reply.nFonts--;
+		  stringLens -= names->length[i];
+		  continue;
+		}
+	    }
+	    *bufptr++ = names->length[i];
+	    memmove( bufptr, names->names[i], names->length[i]);
+	    bufptr += names->length[i];
+	}
+    }
+    nnames = reply.nFonts;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+    WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+    (void) WriteToClient(client, stringLens + nnames, bufferStart);
+    DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(names);
+    xfree(c);
+    if (resolved) xfree(resolved);
+    return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, 
+          unsigned max_names)
+{
+    int         i;
+    LFclosurePtr c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+	return BadAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(max_names < nxagentMaxFontNames ? max_names : nxagentMaxFontNames);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsAndAliases(client, c);
+    return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name;
+    int         namelen;
+    int         numFonts;
+    FontInfoRec fontInfo,
+               *pFontInfo;
+    xListFontsWithInfoReply *reply;
+    int         length;
+    xFontProp  *pFP;
+    int         i;
+    int		aliascount = 0;
+    xListFontsWithInfoReply finalReply;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+ 	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+    if (!c->current.patlen)
+	goto finish;
+    while (c->current.current_fpe < c->num_fpes)
+    {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+	if (!c->current.list_started)
+ 	{
+	    err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+		(client, fpe, c->current.pattern, c->current.patlen,
+		 c->current.max_names, &c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	    if (err == Successful)
+		c->current.list_started = TRUE;
+	}
+	if (err == Successful)
+ 	{
+	    name = 0;
+	    pFontInfo = &fontInfo;
+	    err = (*fpe_functions[fpe->type].list_next_font_with_info)
+		(client, fpe, &name, &namelen, &pFontInfo,
+		 &numFonts, c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doListFontsWithInfo,
+			     c);
+		    c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doListFontWinfo (2): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+	}
+	/*
+	 * When we get an alias back, save our state and reset back to the
+	 * start of the FPE looking for the specified name.  As soon as a real
+	 * font is found for the alias, pop back to the old state
+	 */
+	if (err == FontNameAlias)
+ 	{
+	    /*
+	     * when an alias recurses, we need to give
+	     * the last FPE a chance to clean up; so we call
+	     * it again, and assume that the error returned
+	     * is BadFontName, indicating the alias resolution
+	     * is complete.
+	     */
+	    if (c->haveSaved)
+	    {
+		char	*tmpname;
+		int	tmpnamelen;
+		FontInfoPtr tmpFontInfo;
+
+	    	tmpname = 0;
+	    	tmpFontInfo = &fontInfo;
+	    	(void) (*fpe_functions[fpe->type].list_next_font_with_info)
+		    (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+		     &numFonts, c->current.private);
+		if (--aliascount <= 0)
+		{
+		    err = BadFontName;
+		    goto ContBadFontName;
+		}
+	    }
+	    else
+	    {
+		c->saved = c->current;
+		c->haveSaved = TRUE;
+		c->savedNumFonts = numFonts;
+		if (c->savedName)
+		  xfree(c->savedName);
+		c->savedName = (char *)xalloc(namelen + 1);
+		if (c->savedName)
+		  memmove(c->savedName, name, namelen + 1);
+		aliascount = 20;
+	    }
+	    memmove(c->current.pattern, name, namelen);
+	    c->current.patlen = namelen;
+	    c->current.max_names = 1;
+	    c->current.current_fpe = 0;
+	    c->current.private = 0;
+	    c->current.list_started = FALSE;
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back.  If we've sent enough font
+	 * names, quit.  Always wait for BadFontName to let the FPE
+	 * have a chance to clean up.
+	 */
+	else if (err == BadFontName)
+ 	{
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+ 	    {
+		if (c->current.max_names == 0 ||
+			c->current.current_fpe == c->num_fpes)
+ 		{
+		    c->haveSaved = FALSE;
+		    c->saved.max_names -= (1 - c->current.max_names);
+		    c->current = c->saved;
+		}
+	    }
+	    else if (c->current.max_names == 0)
+		break;
+	}
+ 	else if (err == Successful)
+ 	{
+
+	    if (c->haveSaved)
+ 	    {
+		numFonts = c->savedNumFonts;
+		name = c->savedName;
+		namelen = strlen(name);
+	    }
+
+	   if (nxagentFontLookUp(name) == 0)
+	   {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "doListFontsAndAliases (with info):\n");
+	      fprintf(stderr, "      removing font: %s \n", name);
+#endif
+	       continue;
+           }
+
+	    length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+	    reply = c->reply;
+	    if (c->length < length)
+ 	    {
+		reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+		if (!reply)
+ 		{
+		    err = AllocError;
+		    break;
+		}
+		c->reply = reply;
+		c->length = length;
+	    }
+	    reply->type = X_Reply;
+	    reply->length = (sizeof *reply - sizeof(xGenericReply) +
+			     pFontInfo->nprops * sizeof(xFontProp) +
+			     namelen + 3) >> 2;
+	    reply->sequenceNumber = client->sequence;
+	    reply->nameLength = namelen;
+	    reply->minBounds = pFontInfo->ink_minbounds;
+	    reply->maxBounds = pFontInfo->ink_maxbounds;
+	    reply->minCharOrByte2 = pFontInfo->firstCol;
+	    reply->maxCharOrByte2 = pFontInfo->lastCol;
+	    reply->defaultChar = pFontInfo->defaultCh;
+	    reply->nFontProps = pFontInfo->nprops;
+	    reply->drawDirection = pFontInfo->drawDirection;
+	    reply->minByte1 = pFontInfo->firstRow;
+	    reply->maxByte1 = pFontInfo->lastRow;
+	    reply->allCharsExist = pFontInfo->allExist;
+	    reply->fontAscent = pFontInfo->fontAscent;
+	    reply->fontDescent = pFontInfo->fontDescent;
+	    reply->nReplies = numFonts;
+	    pFP = (xFontProp *) (reply + 1);
+	    for (i = 0; i < pFontInfo->nprops; i++)
+ 	    {
+		pFP->name = pFontInfo->props[i].name;
+		pFP->value = pFontInfo->props[i].value;
+		pFP++;
+	    }
+	    WriteSwappedDataToClient(client, length, reply);
+	    (void) WriteToClient(client, namelen, name);
+	    if (pFontInfo == &fontInfo)
+ 	    {
+		xfree(fontInfo.props);
+		xfree(fontInfo.isStringProp);
+	    }
+	    --c->current.max_names;
+	}
+    }
+finish:
+    length = sizeof(xListFontsWithInfoReply);
+    bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+    finalReply.type = X_Reply;
+    finalReply.sequenceNumber = client->sequence;
+    finalReply.length = (sizeof(xListFontsWithInfoReply)
+		     - sizeof(xGenericReply)) >> 2;
+    WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+    if (c->slept)
+    {
+	ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doListFontWinfo: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->reply);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    xfree(c);
+    return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, 
+                       int max_names)
+{
+    int		    i;
+    LFWIclosurePtr  c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+	goto badAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list)
+    {
+	xfree(c);
+	goto badAlloc;
+    }
+    memmove(c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++)
+    {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->reply = 0;
+    c->length = 0;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->savedNumFonts = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsWithInfo(client, c);
+    return Success;
+badAlloc:
+    return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+    register FontPtr pFont = c->pGC->font, oldpFont;
+    Font	fid, oldfid;
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+    FontPathElementPtr fpe;
+    GC *origGC = NULL;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+	if (c->slept)
+	{
+	    /* Client has died, but we cannot bail out right now.  We
+	       need to clean up after the work we did when going to
+	       sleep.  Setting the drawable pointer to 0 makes this
+	       happen without any attempts to render or perform other
+	       unnecessary activities.  */
+	    c->pDraw = (DrawablePtr)0;
+	}
+	else
+	{
+	    err = Success;
+	    goto bail;
+	}
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client and avoid further
+	   rendering while we clean up after ourself.  */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	c->pDraw = (DrawablePtr)0;
+    }
+
+    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+    while (c->endReq - c->pElt > TextEltHeader)
+    {
+	if (*c->pElt == FontChange)
+        {
+	    if (c->endReq - c->pElt < FontShiftSize)
+	    {
+		 err = BadLength;
+		 goto bail;
+	    }
+
+	    oldpFont = pFont;
+	    oldfid = fid;
+
+	    fid =  ((Font)*(c->pElt+4))		/* big-endian */
+		 | ((Font)*(c->pElt+3)) << 8
+		 | ((Font)*(c->pElt+2)) << 16
+		 | ((Font)*(c->pElt+1)) << 24;
+	    pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+						    SecurityReadAccess);
+	    if (!pFont)
+	    {
+		client->errorValue = fid;
+		err = BadFont;
+		/* restore pFont and fid for step 4 (described below) */
+		pFont = oldpFont;
+		fid = oldfid;
+
+		/* If we're in START_SLEEP mode, the following step
+		   shortens the request...  in the unlikely event that
+		   the fid somehow becomes valid before we come through
+		   again to actually execute the polytext, which would
+		   then mess up our refcounting scheme badly.  */
+		c->err = err;
+		c->endReq = c->pElt;
+
+		goto bail;
+	    }
+
+	    /* Step 3 (described below) on our new font */
+	    if (client_state == START_SLEEP)
+		pFont->refcnt++;
+	    else
+	    {
+		if (pFont != c->pGC->font && c->pDraw)
+		{
+		    ChangeGC( c->pGC, GCFont, &fid);
+		    ValidateGC(c->pDraw, c->pGC);
+		    if (c->reqType == X_PolyText8)
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+		    else
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+		}
+
+		/* Undo the refcnt++ we performed when going to sleep */
+		if (client_state == SLEEPING)
+		    (void)CloseFont(c->pGC->font, (Font)0);
+	    }
+	    c->pElt += FontShiftSize;
+	}
+	else	/* print a string */
+	{
+	    unsigned char *pNextElt;
+	    pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+	    if ( pNextElt > c->endReq)
+	    {
+		err = BadLength;
+		goto bail;
+	    }
+	    if (client_state == START_SLEEP)
+	    {
+		c->pElt = pNextElt;
+		continue;
+	    }
+	    if (c->pDraw)
+	    {
+		lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+				   c->pElt + TextEltHeader);
+	    }
+	    else lgerr = Successful;
+
+	    if (lgerr == Suspended)
+	    {
+		if (!c->slept) {
+		    int len;
+		    GC *pGC;
+		    PTclosurePtr new_closure;
+
+    /*  We're putting the client to sleep.  We need to do a few things
+	to ensure successful and atomic-appearing execution of the
+	remainder of the request.  First, copy the remainder of the
+	request into a safe malloc'd area.  Second, create a scratch GC
+	to use for the remainder of the request.  Third, mark all fonts
+	referenced in the remainder of the request to prevent their
+	deallocation.  Fourth, make the original GC look like the
+	request has completed...  set its font to the final font value
+	from this request.  These GC manipulations are for the unlikely
+	(but possible) event that some other client is using the GC.
+	Steps 3 and 4 are performed by running this procedure through
+	the remainder of the request in a special no-render mode
+	indicated by client_state = START_SLEEP.  */
+
+		    /* Step 1 */
+		    /* Allocate a malloc'd closure structure to replace
+		       the local one we were passed */
+		    new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+		    if (!new_closure)
+		    {
+			err = BadAlloc;
+			goto bail;
+		    }
+		    *new_closure = *c;
+		    c = new_closure;
+
+		    len = c->endReq - c->pElt;
+		    c->data = (unsigned char *)xalloc(len);
+		    if (!c->data)
+		    {
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    memmove(c->data, c->pElt, len);
+		    c->pElt = c->data;
+		    c->endReq = c->pElt + len;
+
+		    /* Step 2 */
+
+		    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+		    if (!pGC)
+		    {
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+
+                    pGC->tileIsPixel = TRUE;
+                    pGC->tile.pixel = 0;
+                    pGC->stipple = NullPixmap;
+
+		    if ((err = CopyGC(c->pGC, pGC, GCFunction |
+				      GCPlaneMask | GCForeground |
+				      GCBackground | GCFillStyle |
+				      GCTile | GCStipple |
+				      GCTileStipXOrigin |
+				      GCTileStipYOrigin | GCFont |
+				      GCSubwindowMode | GCClipXOrigin |
+				      GCClipYOrigin | GCClipMask)) !=
+				      Success)
+		    {
+			FreeScratchGC(pGC);
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    origGC = c->pGC;
+		    c->pGC = pGC;
+		    ValidateGC(c->pDraw, c->pGC);
+		    
+		    c->slept = TRUE;
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doPolyText,
+			     (pointer) c);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: doPolyText (1): client [%lx] sleeping.\n", client);
+#endif
+
+		    /* Set up to perform steps 3 and 4 */
+		    client_state = START_SLEEP;
+		    continue;	/* on to steps 3 and 4 */
+		}
+		return TRUE;
+	    }
+	    else if (lgerr != Successful)
+	    {
+		err = FontToXError(lgerr);
+		goto bail;
+	    }
+	    if (c->pDraw)
+	    {
+		c->xorg += *((INT8 *)(c->pElt + 1));	/* must be signed */
+		c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+		    *c->pElt, c->pElt + TextEltHeader);
+	    }
+	    c->pElt = pNextElt;
+	}
+    }
+
+bail:
+
+    if (client_state == START_SLEEP)
+    {
+	/* Step 4 */
+	if (pFont != origGC->font)
+	{
+	    ChangeGC(origGC, GCFont, &fid);
+	    ValidateGC(c->pDraw, origGC);
+	}
+
+	/* restore pElt pointer for execution of remainder of the request */
+	c->pElt = c->data;
+	return TRUE;
+    }
+
+    if (c->err != Success) err = c->err;
+    if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+        if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doPolytext: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt, 
+         unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+    PTclosureRec local_closure;
+
+    local_closure.pElt = pElt;
+    local_closure.endReq = endReq;
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_PolyText8)
+    {
+	local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.polyText =  (PolyTextPtr) pGC->ops->PolyText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.pGC = pGC;
+    local_closure.did = did;
+    local_closure.err = Success;
+    local_closure.slept = FALSE;
+
+    (void) doPolyText(client, &local_closure);
+    return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    FontPathElementPtr fpe;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client. */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+    if (lgerr == Suspended)
+    {
+        if (!c->slept) {
+	    GC *pGC;
+	    unsigned char *data;
+	    ITclosurePtr new_closure;
+
+	    /* We're putting the client to sleep.  We need to
+	       save some state.  Similar problem to that handled
+	       in doPolyText, but much simpler because the
+	       request structure is much simpler. */
+
+	    new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+	    if (!new_closure)
+	    {
+		err = BadAlloc;
+		goto bail;
+	    }
+	    *new_closure = *c;
+	    c = new_closure;
+
+	    data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+	    if (!data)
+	    {
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    memmove(data, c->data, c->nChars * c->itemSize);
+	    c->data = data;
+
+	    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+	    if (!pGC)
+	    {
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+
+            pGC->tileIsPixel = TRUE;
+            pGC->tile.pixel = 0;
+            pGC->stipple = NullPixmap;
+
+	    if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+			      GCForeground | GCBackground | GCFillStyle |
+			      GCTile | GCStipple | GCTileStipXOrigin |
+			      GCTileStipYOrigin | GCFont |
+			      GCSubwindowMode | GCClipXOrigin |
+			      GCClipYOrigin | GCClipMask)) != Success)
+	    {
+		FreeScratchGC(pGC);
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    c->pGC = pGC;
+	    ValidateGC(c->pDraw, c->pGC);
+
+	    c->slept = TRUE;
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+#ifdef NXAGENT_DEBUG
+            fprintf(stderr, " NXdixfonts: doImageText (1): client [%lx] sleeping.\n", client);
+#endif
+
+        }
+        return TRUE;
+    }
+    else if (lgerr != Successful)
+    {
+        err = FontToXError(lgerr);
+        goto bail;
+    }
+    if (c->pDraw)
+    {
+	(* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+	    c->nChars, c->data);
+    }
+
+bail:
+
+    if (err != Success && c->client != serverClient) {
+	SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+#ifdef NXAGENT_DEBUG
+        fprintf(stderr, " NXdixfonts: doImageText: client [%lx] wakeup.\n", client);
+#endif
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars, 
+          unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+    ITclosureRec local_closure;
+
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.pGC = pGC;
+    local_closure.nChars = nChars;
+    local_closure.data = data;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_ImageText8)
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.did = did;
+    local_closure.slept = FALSE;
+
+    (void) doImageText(client, &local_closure);
+    return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+    int         i;
+
+    for (i = 0; i < num_fpe_types; i++) {
+	if ((*fpe_functions[i].name_check) (pathname))
+	    return i;
+    }
+    return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+    int         i;
+
+    for (i = 0; i < n; i++) {
+	if (force) {
+	    /* Sanity check that all refcounts will be 0 by the time
+	       we get to the end of the list. */
+	    int found = 1;	/* the first reference is us */
+	    int j;
+	    for (j = i+1; j < n; j++) {
+		if (list[j] == list[i])
+		    found++;
+	    }
+	    if (list[i]->refcount != found) {
+		ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+		       list[i]->name_length, list[i]->name,
+		       list[i]->refcount, found);
+		list[i]->refcount = found; /* ensure it will get freed */
+	    }
+	}
+	FreeFPE(list[i]);
+    }
+    xfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+    FontPathElementPtr fpe;
+    int         i;
+
+    for (i = 0; i < num; i++) {
+	fpe = list[i];
+	if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+	    return fpe;
+    }
+    return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+    int         i, err = 0;
+    int         valid_paths = 0;
+    unsigned int len;
+    unsigned char *cp = paths;
+    FontPathElementPtr fpe = NULL, *fplist;
+
+    fplist = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * npaths);
+    if (!fplist) {
+	*bad = 0;
+	return BadAlloc;
+    }
+    for (i = 0; i < num_fpe_types; i++) {
+	if (fpe_functions[i].set_path_hook)
+	    (*fpe_functions[i].set_path_hook) ();
+    }
+    for (i = 0; i < npaths; i++) 
+    {
+	len = (unsigned int) (*cp++);
+
+	if (len == 0) 
+	{
+	    if (persist)
+		ErrorF ("Removing empty element from the valid list of fontpaths\n");
+	    err = BadValue;
+	}
+	else
+	{
+	    /* if it's already in our active list, just reset it */
+	    /*
+	     * note that this can miss FPE's in limbo -- may be worth catching
+	     * them, though it'd muck up refcounting
+	     */
+	    fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+	    if (fpe) 
+	    {
+		err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+		if (err == Successful) 
+		{
+		    UseFPE(fpe);/* since it'll be decref'd later when freed
+				 * from the old list */
+		}
+		else
+		    fpe = 0;
+	    }
+	    /* if error or can't do it, act like it's a new one */
+	    if (!fpe)
+	    {
+		fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+		if (!fpe) 
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->name = (char *) xalloc(len + 1);
+		if (!fpe->name) 
+		{
+		    xfree(fpe);
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->refcount = 1;
+    
+		strncpy(fpe->name, (char *) cp, (int) len);
+		fpe->name[len] = '\0';
+		fpe->name_length = len;
+		fpe->type = DetermineFPEType(fpe->name);
+		if (fpe->type == -1)
+		    err = BadValue;
+		else
+		    err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+		if (err != Successful)
+		{
+                    #ifndef NXAGENT_SERVER
+		    if (persist)
+		    {
+			ErrorF("Could not init font path element %s, removing from list!\n",
+			       fpe->name);
+		    }
+                    #endif
+		    xfree (fpe->name);
+		    xfree (fpe);
+		}
+	    }
+	}
+	if (err != Successful)
+	{
+	    if (!persist)
+		goto bail;
+	}
+	else
+	{
+	    fplist[valid_paths++] = fpe;
+	}
+	cp += len;
+    }
+
+    FreeFontPath(font_path_elements, num_fpes, FALSE);
+    font_path_elements = fplist;
+    if (patternCache)
+	EmptyFontPatternCache(patternCache);
+    num_fpes = valid_paths;
+
+    return Success;
+bail:
+    *bad = i;
+    while (--valid_paths >= 0)
+	FreeFPE(fplist[valid_paths]);
+    xfree(fplist);
+    return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+    int   err = Success;
+
+    if (npaths == 0) {
+	if (SetDefaultFontPath(defaultFontPath) != Success)
+	    return BadValue;
+    } else {
+	err = SetFontPathElements(npaths, paths, error, FALSE);
+    }
+    return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+    unsigned char *cp,
+               *pp,
+               *nump,
+               *newpath;
+    int         num = 1,
+                len,
+                err,
+                size = 0,
+                bad;
+
+    /* get enough for string, plus values -- use up commas */
+#ifdef NX_TRANS_SOCKET
+    len = strlen(_NXGetFontPath(path)) + 1;
+#else
+    len = strlen(path) + 1;
+#endif
+    nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+    if (!newpath)
+	return BadAlloc;
+#ifdef NX_TRANS_SOCKET
+    pp = (unsigned char *) _NXGetFontPath(path);
+#else
+    pp = (unsigned char *) path;
+#endif
+    cp++;
+    while (*pp) {
+	if (*pp == ',') {
+	    *nump = (unsigned char) size;
+	    nump = cp++;
+	    pp++;
+	    num++;
+	    size = 0;
+	} else {
+	    *cp++ = *pp++;
+	    size++;
+	}
+    }
+    *nump = (unsigned char) size;
+
+    err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+    DEALLOCATE_LOCAL(newpath);
+
+    return err;
+}
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+    int			i;
+    unsigned char       *c;
+    int			len;
+    FontPathElementPtr	fpe;
+
+    len = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	len += fpe->name_length + 1;
+    }
+    font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+    if (!font_path_string)
+	return NULL;
+
+    c = font_path_string;
+    *length = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	*c = fpe->name_length;
+	*length += *c++;
+	memmove(c, fpe->name, fpe->name_length);
+	c += fpe->name_length;
+    }
+    *count = num_fpes;
+    return font_path_string;
+}
+
+int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+    if (fpe_functions[pfont->fpe->type].load_glyphs)
+	return (*fpe_functions[pfont->fpe->type].load_glyphs)
+	    (client, pfont, 0, nchars, item_size, data);
+    else
+	return Successful;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+    int			i;
+    FontPathElementPtr	fpe;
+
+    for (i = 0; i < num_fpes; i++)
+    {
+	fpe = font_path_elements[i];
+	if (fpe_functions[fpe->type].client_died)
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+    }
+}
+
+void
+InitFonts ()
+{
+    patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+    if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+	PrinterFontRegisterFpeFunctions();
+	FontFileCheckRegisterFpeFunctions();
+	check_fs_register_fpe_functions();
+    } else 
+#endif
+    {
+#ifdef KDRIVESERVER
+	BuiltinRegisterFpeFunctions();
+#endif
+	FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+	fs_register_fpe_functions();
+#endif
+    }
+}
+
+int
+GetDefaultPointSize ()
+{
+    return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+    if (requestingClient && requestingClient->fontResFunc != NULL &&
+	!requestingClient->clientGone)
+    {
+	return (*requestingClient->fontResFunc)(requestingClient, num);
+    }
+    else {
+	static struct _FontResolution res;
+	ScreenPtr   pScreen;
+
+	pScreen = screenInfo.screens[0];
+	res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+	/*
+	 * XXX - we'll want this as long as bitmap instances are prevalent 
+	 so that we can match them from scalable fonts
+	 */
+	if (res.x_resolution < 88)
+	    res.x_resolution = 75;
+	else
+	    res.x_resolution = 100;
+	res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+	if (res.y_resolution < 88)
+	    res.y_resolution = 75;
+	else
+	    res.y_resolution = 100;
+	res.point_size = 120;
+	*num = 1;
+	return &res;
+    }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func, 
+		     InitFpeFunc init_func, 
+		     FreeFpeFunc free_func, 
+		     ResetFpeFunc reset_func, 
+		     OpenFontFunc open_func, 
+		     CloseFontFunc close_func, 
+		     ListFontsFunc list_func, 
+		     StartLfwiFunc start_lfwi_func, 
+		     NextLfwiFunc next_lfwi_func, 
+		     WakeupFpeFunc wakeup_func, 
+		     ClientDiedFunc client_died, 
+		     LoadGlyphsFunc load_glyphs, 
+		     StartLaFunc start_list_alias_func, 
+		     NextLaFunc next_list_alias_func, 
+		     SetPathFunc set_path_func)
+{
+    FPEFunctions *new;
+
+    /* grow the list */
+    new = (FPEFunctions *) xrealloc(fpe_functions,
+				 (num_fpe_types + 1) * sizeof(FPEFunctions));
+    if (!new)
+	return -1;
+    fpe_functions = new;
+
+    fpe_functions[num_fpe_types].name_check = name_func;
+    fpe_functions[num_fpe_types].open_font = open_func;
+    fpe_functions[num_fpe_types].close_font = close_func;
+    fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+    fpe_functions[num_fpe_types].list_fonts = list_func;
+    fpe_functions[num_fpe_types].start_list_fonts_with_info =
+	start_lfwi_func;
+    fpe_functions[num_fpe_types].list_next_font_with_info =
+	next_lfwi_func;
+    fpe_functions[num_fpe_types].init_fpe = init_func;
+    fpe_functions[num_fpe_types].free_fpe = free_func;
+    fpe_functions[num_fpe_types].reset_fpe = reset_func;
+    fpe_functions[num_fpe_types].client_died = client_died;
+    fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+    fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+	start_list_alias_func;
+    fpe_functions[num_fpe_types].list_next_font_or_alias =
+	next_list_alias_func;
+    fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+    return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+    if (patternCache) {
+	FreeFontPatternCache(patternCache);
+	patternCache = 0;
+    }
+    FreeFontPath(font_path_elements, num_fpes, TRUE);
+    font_path_elements = 0;
+    num_fpes = 0;
+    xfree(fpe_functions);
+    num_fpe_types = 0;
+    fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+    return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+					    SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+    return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+    return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+    FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+    return 0;
+}
+
+static int  fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+    /* if server has reset, make sure the b&w handlers are reinstalled */
+    if (last_server_gen < serverGeneration) {
+	last_server_gen = serverGeneration;
+	fs_handlers_installed = 0;
+    }
+    if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+	if (!RegisterBlockAndWakeupHandlers(block_handler,
+					    FontWakeup, (pointer) 0))
+	    return AllocError;
+	fs_handlers_installed++;
+    }
+    QueueFontWakeup(fpe);
+    return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+    if (all) {
+	/* remove the handlers if no one else is using them */
+	if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+	    RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+					 (pointer) 0);
+	}
+    }
+    RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+	((nbytes) == 1 ? (((bits)+7)>>3)        /* pad to 1 byte */ \
+	:(nbytes) == 2 ? ((((bits)+15)>>3)&~1)  /* pad to 2 bytes */ \
+	:(nbytes) == 4 ? ((((bits)+31)>>3)&~3)  /* pad to 4 bytes */ \
+	:(nbytes) == 8 ? ((((bits)+63)>>3)&~7)  /* pad to 8 bytes */ \
+	: 0)
+
+#define GLYPH_SIZE(ch, nbytes)          \
+	GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+			(ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+    int         r,
+                l;
+    int         bpr;
+    int         byte;
+    static unsigned maskTab[] = {
+	(1 << 7), (1 << 6), (1 << 5), (1 << 4),
+	(1 << 3), (1 << 2), (1 << 1), (1 << 0),
+    };
+
+    bpr = GLYPH_SIZE(cip, 4);
+    for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+	pointer     row = (pointer) cip->bits + r * bpr;
+
+	byte = 0;
+	for (l = 0; l <= (cip->metrics.rightSideBearing -
+			  cip->metrics.leftSideBearing); l++) {
+	    if (maskTab[l & 7] & row[l >> 3])
+		putchar('X');
+	    else
+		putchar('.');
+	}
+	putchar('\n');
+    }
+}
+
+#endif
+
+
+typedef struct
+{
+   LFclosurePtr c;
+   OFclosurePtr oc;
+} nxFs,*nxFsPtr;
+
+static Bool
+#if NeedFunctionPrototypes
+nxdoListFontsAndAliases(ClientPtr client, nxFsPtr fss)
+#else
+nxdoListFontsAndAliases(client, fss)
+    ClientPtr   client;
+    nxFsPtr fss;
+#endif
+{
+    LFclosurePtr c=fss->c;
+    OFclosurePtr oc=fss->oc;
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int         i;
+    int		aliascount = 0;
+    char        tmp[256];
+    tmp[0]=0;
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)nxdoListFontsAndAliases,
+			(pointer) fss);
+#ifdef NXAGENT_DEBUG
+                    fprintf(stderr, " NXdixfonts: nxdoListFont (1): client [%lx] sleeping.\n", client);
+#endif
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (2): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)nxdoListFontsAndAliases,
+				    (pointer) fss);
+			c->slept = TRUE;
+#ifdef NXAGENT_DEBUG
+                        fprintf(stderr, " NXdixfonts: nxdoListFont (3): client [%lx] sleeping.\n", client);
+#endif
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+                    {
+                        memmove(resolved, tmpname, resolvedlen);
+                        resolved[resolvedlen] = '\0';
+                    }
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+		    {
+		       memcpy(tmp,c->savedName,c->savedNameLen>255?255:c->savedNameLen);
+		       tmp[c->savedNameLen>255?256:c->savedNameLen]=0;
+		       if (nxagentFontLookUp(tmp))
+		          break;
+			else tmp[0]=0;
+		    }
+		}
+		else
+		{
+		   memcpy(tmp,name,namelen>255?255:namelen);
+		   tmp[namelen>255?256:namelen]=0;
+		   if (nxagentFontLookUp(tmp))
+		      break;
+		   else tmp[0]=0;
+		}
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+                    {
+                        memmove(c->savedName, name, namelen);
+                        c->savedName[namelen] = '\0';
+                    }
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+bail:
+finish:
+    if (strlen(tmp))
+    {
+#ifdef NXAGENT_FONTMATCH_DEBUG
+      fprintf(stderr, "nxListFont changed (0) font to %s\n",tmp);
+#endif
+      memcpy(oc->fontname, tmp, strlen(tmp));
+      oc->fnamelen = strlen(tmp);
+
+      oc->origFontName = oc->fontname;
+      oc->origFontNameLen = oc->fnamelen;
+
+    }
+    else
+    {
+        for (i = 0; i < c->names->nnames; i++)
+	{
+	  if (c->names->length[i] > 255)
+	     continue;
+	  else
+	  {
+	      memcpy(tmp, c->names->names[i], c->names->length[i]);
+	      tmp[ c->names->length[i] ] = 0;
+	      if (nxagentFontLookUp(tmp) == 0)
+		continue;
+	      memcpy(oc->fontname, tmp, strlen(tmp));
+	      oc->fnamelen = strlen(tmp);
+
+              oc->origFontName = oc->fontname;
+              oc->origFontNameLen = oc->fnamelen;
+
+#ifdef NXAGENT_FONTMATCH_DEBUG
+	      fprintf(stderr, "nxListFont changed (1) font to %s\n",tmp);
+#endif
+	      break;
+	  }
+	}
+    }
+
+    if (c->slept)
+    {
+       ClientWakeup(client);
+#ifdef NXAGENT_DEBUG
+       fprintf(stderr, " NXdixfonts: nxdoListFont: client [%lx] wakeup.\n", client);
+#endif
+    }
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(c->names);
+    xfree(c);
+    xfree(fss);
+    if (resolved) xfree(resolved);
+
+    return doOpenFont(client, oc);
+}
+
+int
+nxOpenFont(client, fid, flags, lenfname, pfontname)
+    ClientPtr   client;
+    XID         fid;
+    Mask        flags;
+    unsigned    lenfname;
+    char       *pfontname;
+{
+    nxFsPtr      fss;
+    LFclosurePtr c;
+    OFclosurePtr oc;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    if (!(fss = (nxFsPtr) xalloc(sizeof(nxFs))))
+        return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+    {
+	xfree(fss);
+	return BadAlloc;
+    }
+        c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(100);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	xfree(fss);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = lenfname;
+    c->current.current_fpe = 0;
+    c->current.max_names = nxagentMaxFontNames;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+
+    oc = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!oc)
+    {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(fss);
+      return BadAlloc;
+    }
+    oc->fontname = (char *) xalloc(256);/* I don't want to deal with future reallocs errors */
+    oc->origFontName = pfontname;
+    oc->origFontNameLen = lenfname;
+    if (!oc->fontname) {
+      for (i = 0; i < c->num_fpes; i++)
+        FreeFPE(c->fpe_list[i]);
+      xfree(c->fpe_list);
+      xfree(c);
+      xfree(oc);
+      xfree(fss);
+      return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    oc->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!oc->fpe_list) {
+	xfree(oc->fontname);
+	xfree(oc);
+      for (i = 0; i < c->num_fpes; i++)
+         FreeFPE(c->fpe_list[i]);
+       xfree(c->fpe_list);
+       xfree(c);
+       xfree(fss);
+       return BadAlloc;
+    }
+    memmove(oc->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	oc->fpe_list[i] = font_path_elements[i];
+	UseFPE(oc->fpe_list[i]);
+    }
+    oc->client = client;
+    oc->fontid = fid;
+    oc->current_fpe = 0;
+    oc->num_fpes = num_fpes;
+    oc->fnamelen = lenfname;
+    oc->slept = FALSE;
+    oc->flags = flags;
+    oc->non_cachable_font = cached;
+    fss->c=c;
+    fss->oc=oc;
+    nxdoListFontsAndAliases(client, fss);
+    return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
new file mode 100644
index 000000000..9de998417
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
@@ -0,0 +1,2143 @@
+/* $XdotOrg: xc/programs/Xserver/dix/dixfonts.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/dixfonts.c,v 3.28 2003/11/08 02:02:03 dawes Exp $ */
+/************************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+/* $Xorg: dixfonts.c,v 1.4 2000/08/17 19:48:18 cpqbld Exp $ */
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+
+#ifdef DEBUG
+#include	<stdio.h>
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr)  *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int  num_fpes = 0;
+FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int  num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int  num_slept_fpes = 0;
+static int  size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+int
+FontToXError(err)
+    int         err;
+{
+    switch (err) {
+    case Successful:
+	return Success;
+    case AllocError:
+	return BadAlloc;
+    case BadFontName:
+	return BadName;
+    case BadFontPath:
+    case BadFontFormat:	/* is there something better? */
+    case BadCharRange:
+	return BadValue;
+    default:
+	return err;
+    }
+}
+
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+    int         err;
+    FontPtr     pf;
+    XID         fid;
+
+    fid = FakeClientID(0);
+    err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+		   (unsigned) strlen(defaultfontname), defaultfontname);
+    if (err != Success)
+	return FALSE;
+    pf = (FontPtr) LookupIDByType(fid, RT_FONT);
+    if (pf == (FontPtr) NULL)
+	return FALSE;
+    defaultFont = pf;
+    return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted.  this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+    int         i;
+    FontPathElementPtr *new;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "re-queueing fpe wakeup\n");
+#endif
+
+	    return;
+	}
+    }
+    if (num_slept_fpes == size_slept_fpes) {
+	new = (FontPathElementPtr *)
+	    xrealloc(slept_fpes,
+		     sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+	if (!new)
+	    return;
+	slept_fpes = new;
+	size_slept_fpes += 4;
+    }
+    slept_fpes[num_slept_fpes] = fpe;
+    num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+    int         i,
+                j;
+
+    for (i = 0; i < num_slept_fpes; i++) {
+	if (slept_fpes[i] == fpe) {
+	    for (j = i; j < num_slept_fpes; j++) {
+		slept_fpes[j] = slept_fpes[j + 1];
+	    }
+	    num_slept_fpes--;
+	    return;
+	}
+    }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+    int         i;
+    FontPathElementPtr fpe;
+
+    if (count < 0)
+	return;
+    /* wake up any fpe's that may be waiting for information */
+    for (i = 0; i < num_slept_fpes; i++) {
+	fpe = slept_fpes[i];
+	(void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+    }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+    fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+    fpe->refcount--;
+    if (fpe->refcount == 0) {
+	(*fpe_functions[fpe->type].free_fpe) (fpe);
+	xfree(fpe->name);
+	xfree(fpe);
+    }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+    FontPtr     pfont = NullFont;
+    FontPathElementPtr fpe = NULL;
+    ScreenPtr   pScr;
+    int         err = Successful;
+    int         i;
+    char       *alias,
+               *newname;
+    int         newlen;
+    int		aliascount = 20;
+    /*
+     * Decide at runtime what FontFormat to use.
+     */
+    Mask FontFormat = 
+
+	((screenInfo.imageByteOrder == LSBFirst) ?
+	    BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+	((screenInfo.bitmapBitOrder == LSBFirst) ?
+	    BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+	BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+	BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+	BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+	BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+	BitmapFormatScanlinePad64 |
+#endif
+
+	BitmapFormatScanlineUnit8;
+
+    if (client->clientGone)
+    {
+	if (c->current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    while (c->current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current_fpe];
+	err = (*fpe_functions[fpe->type].open_font)
+	    ((pointer) client, fpe, c->flags,
+	     c->fontname, c->fnamelen, FontFormat,
+	     BitmapFormatMaskByte |
+	     BitmapFormatMaskBit |
+	     BitmapFormatMaskImageRectangle |
+	     BitmapFormatMaskScanLinePad |
+	     BitmapFormatMaskScanLineUnit,
+	     c->fontid, &pfont, &alias,
+	     c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+		 c->non_cachable_font :
+		 (FontPtr)0);
+
+	if (err == FontNameAlias && alias) {
+	    newlen = strlen(alias);
+	    newname = (char *) xrealloc(c->fontname, newlen);
+	    if (!newname) {
+		err = AllocError;
+		break;
+	    }
+	    memmove(newname, alias, newlen);
+	    c->fontname = newname;
+	    c->fnamelen = newlen;
+	    c->current_fpe = 0;
+	    if (--aliascount <= 0)
+		break;
+	    continue;
+	}
+	if (err == BadFontName) {
+	    c->current_fpe++;
+	    continue;
+	}
+	if (err == Suspended) {
+	    if (!c->slept) {
+		c->slept = TRUE;
+		ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+	    }
+	    return TRUE;
+	}
+	break;
+    }
+
+    if (err != Successful)
+	goto bail;
+    if (!pfont) {
+	err = BadFontName;
+	goto bail;
+    }
+    if (!pfont->fpe)
+	pfont->fpe = fpe;
+    pfont->refcnt++;
+    if (pfont->refcnt == 1) {
+	UseFPE(pfont->fpe);
+	for (i = 0; i < screenInfo.numScreens; i++) {
+	    pScr = screenInfo.screens[i];
+	    if (pScr->RealizeFont)
+	    {
+		if (!(*pScr->RealizeFont) (pScr, pfont))
+		{
+		    CloseFont (pfont, (Font) 0);
+		    err = AllocError;
+		    goto bail;
+		}
+	    }
+	}
+    }
+    if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+	err = AllocError;
+	goto bail;
+    }
+    if (patternCache && pfont != c->non_cachable_font)
+	CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
+			 pfont);
+bail:
+    if (err != Successful && c->client != serverClient) {
+	SendErrorToClient(c->client, X_OpenFont, 0,
+			  c->fontid, FontToXError(err));
+    }
+    if (c->slept)
+	ClientWakeup(c->client);
+    for (i = 0; i < c->num_fpes; i++) {
+	FreeFPE(c->fpe_list[i]);
+    }
+    xfree(c->fpe_list);
+    xfree(c->fontname);
+    xfree(c);
+    return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+    OFclosurePtr c;
+    int         i;
+    FontPtr     cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+    char *f;
+    f = (char *)xalloc(lenfname + 1);
+    memmove(f, pfontname, lenfname);
+    f[lenfname] = '\0';
+    ErrorF("OpenFont: fontname is \"%s\"\n", f);
+    xfree(f);
+#endif
+    if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+	return BadName;
+    if (patternCache)
+    {
+
+    /*
+    ** Check name cache.  If we find a cached version of this font that
+    ** is cachable, immediately satisfy the request with it.  If we find
+    ** a cached version of this font that is non-cachable, we do not
+    ** satisfy the request with it.  Instead, we pass the FontPtr to the
+    ** FPE's open_font code (the fontfile FPE in turn passes the
+    ** information to the rasterizer; the fserve FPE ignores it).
+    **
+    ** Presumably, the font is marked non-cachable because the FPE has
+    ** put some licensing restrictions on it.  If the FPE, using
+    ** whatever logic it relies on, determines that it is willing to
+    ** share this existing font with the client, then it has the option
+    ** to return the FontPtr we passed it as the newly-opened font.
+    ** This allows the FPE to exercise its licensing logic without
+    ** having to create another instance of a font that already exists.
+    */
+
+	cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+	if (cached && cached->info.cachable)
+	{
+	    if (!AddResource(fid, RT_FONT, (pointer) cached))
+		return BadAlloc;
+	    cached->refcnt++;
+	    return Success;
+	}
+    }
+    c = (OFclosurePtr) xalloc(sizeof(OFclosureRec));
+    if (!c)
+	return BadAlloc;
+    c->fontname = (char *) xalloc(lenfname);
+    c->origFontName = pfontname;
+    c->origFontNameLen = lenfname;
+    if (!c->fontname) {
+	xfree(c);
+	return BadAlloc;
+    }
+    /*
+     * copy the current FPE list, so that if it gets changed by another client
+     * while we're blocking, the request still appears atomic
+     */
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c->fontname);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove(c->fontname, pfontname, lenfname);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->fontid = fid;
+    c->current_fpe = 0;
+    c->num_fpes = num_fpes;
+    c->fnamelen = lenfname;
+    c->slept = FALSE;
+    c->flags = flags;
+    c->non_cachable_font = cached;
+
+    (void) doOpenFont(client, c);
+    return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+CloseFont(pointer value, XID fid)
+{
+    int         nscr;
+    ScreenPtr   pscr;
+    FontPathElementPtr fpe;
+    FontPtr     pfont = (FontPtr)value;
+
+    if (pfont == NullFont)
+	return (Success);
+    if (--pfont->refcnt == 0) {
+	if (patternCache)
+	    RemoveCachedFontPattern (patternCache, pfont);
+	/*
+	 * since the last reference is gone, ask each screen to free any
+	 * storage it may have allocated locally for it.
+	 */
+	for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+	    pscr = screenInfo.screens[nscr];
+	    if (pscr->UnrealizeFont)
+		(*pscr->UnrealizeFont) (pscr, pfont);
+	}
+	if (pfont == defaultFont)
+	    defaultFont = NULL;
+#ifdef LBX
+	LbxFreeFontTag(pfont);
+#endif
+#ifdef XF86BIGFONT
+	XF86BigfontFreeFontShm(pfont);
+#endif
+	fpe = pfont->fpe;
+	(*fpe_functions[fpe->type].close_font) (fpe, pfont);
+	FreeFPE(fpe);
+    }
+    return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ *  \param pReply caller must allocate this storage
+  */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+    FontPropPtr      pFP;
+    int              r,
+                     c,
+                     i;
+    xFontProp       *prFP;
+    xCharInfo       *prCI;
+    xCharInfo       *charInfos[256];
+    unsigned char    chars[512];
+    int              ninfos;
+    unsigned long    ncols;
+    unsigned long    count;
+
+    /* pr->length set in dispatch */
+    pReply->minCharOrByte2 = pFont->info.firstCol;
+    pReply->defaultChar = pFont->info.defaultCh;
+    pReply->maxCharOrByte2 = pFont->info.lastCol;
+    pReply->drawDirection = pFont->info.drawDirection;
+    pReply->allCharsExist = pFont->info.allExist;
+    pReply->minByte1 = pFont->info.firstRow;
+    pReply->maxByte1 = pFont->info.lastRow;
+    pReply->fontAscent = pFont->info.fontAscent;
+    pReply->fontDescent = pFont->info.fontDescent;
+
+    pReply->minBounds = pFont->info.ink_minbounds;
+    pReply->maxBounds = pFont->info.ink_maxbounds;
+
+    pReply->nFontProps = pFont->info.nprops;
+    pReply->nCharInfos = nProtoCCIStructs;
+
+    for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+	    i < pFont->info.nprops;
+	    i++, pFP++, prFP++) {
+	prFP->name = pFP->name;
+	prFP->value = pFP->value;
+    }
+
+    ninfos = 0;
+    ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+    prCI = (xCharInfo *) (prFP);
+    for (r = pFont->info.firstRow;
+	    ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+	    r++) {
+	i = 0;
+	for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+	    chars[i++] = r;
+	    chars[i++] = c;
+	}
+	(*pFont->get_metrics) (pFont, ncols, chars, 
+				TwoD16Bit, &count, charInfos);
+	i = 0;
+	for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+	    *prCI = *charInfos[i];
+	    prCI++;
+	    ninfos++;
+	}
+    }
+    return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    FontNamesPtr names = NULL;
+    char       *name, *resolved=NULL;
+    int         namelen, resolvedlen;
+    int		nnames;
+    int         stringLens;
+    int         i;
+    xListFontsReply reply;
+    char	*bufptr;
+    char	*bufferStart;
+    int		aliascount = 0;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+
+    if (!c->current.patlen)
+	goto finish;
+
+    while (c->current.current_fpe < c->num_fpes) {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+
+	if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+	{
+	    /* This FPE doesn't support/require list_fonts_and_aliases */
+
+	    err = (*fpe_functions[fpe->type].list_fonts)
+		((pointer) c->client, fpe, c->current.pattern,
+		 c->current.patlen, c->current.max_names - c->names->nnames,
+		 c->names);
+
+	    if (err == Suspended) {
+		if (!c->slept) {
+		    c->slept = TRUE;
+		    ClientSleep(client,
+			(ClientSleepProcPtr)doListFontsAndAliases,
+			(pointer) c);
+		}
+		return TRUE;
+	    }
+
+	    err = BadFontName;
+	}
+	else
+	{
+	    /* Start of list_fonts_and_aliases functionality.  Modeled
+	       after list_fonts_with_info in that it resolves aliases,
+	       except that the information collected from FPEs is just
+	       names, not font info.  Each list_next_font_or_alias()
+	       returns either a name into name/namelen or an alias into
+	       name/namelen and its target name into resolved/resolvedlen.
+	       The code at this level then resolves the alias by polling
+	       the FPEs.  */
+
+	    if (!c->current.list_started) {
+		err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+		    ((pointer) c->client, fpe, c->current.pattern,
+		     c->current.patlen, c->current.max_names - c->names->nnames,
+		     &c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+		    }
+		    return TRUE;
+		}
+		if (err == Successful)
+		    c->current.list_started = TRUE;
+	    }
+	    if (err == Successful) {
+		char    *tmpname;
+		name = 0;
+		err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+		    ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+		     &resolvedlen, c->current.private);
+		if (err == Suspended) {
+		    if (!c->slept) {
+			ClientSleep(client,
+				    (ClientSleepProcPtr)doListFontsAndAliases,
+				    (pointer) c);
+			c->slept = TRUE;
+		    }
+		    return TRUE;
+		}
+		if (err == FontNameAlias) {
+		    if (resolved) xfree(resolved);
+		    resolved = (char *) xalloc(resolvedlen + 1);
+		    if (resolved)
+			memmove(resolved, tmpname, resolvedlen + 1);
+		}
+	    }
+
+	    if (err == Successful)
+	    {
+		if (c->haveSaved)
+		{
+		    if (c->savedName)
+			(void)AddFontNamesName(c->names, c->savedName,
+					       c->savedNameLen);
+		}
+		else
+		    (void)AddFontNamesName(c->names, name, namelen);
+	    }
+
+	    /*
+	     * When we get an alias back, save our state and reset back to
+	     * the start of the FPE looking for the specified name.  As
+	     * soon as a real font is found for the alias, pop back to the
+	     * old state
+	     */
+	    else if (err == FontNameAlias) {
+		char	tmp_pattern[XLFDMAXFONTNAMELEN];
+		/*
+		 * when an alias recurses, we need to give
+		 * the last FPE a chance to clean up; so we call
+		 * it again, and assume that the error returned
+		 * is BadFontName, indicating the alias resolution
+		 * is complete.
+		 */
+		memmove(tmp_pattern, resolved, resolvedlen);
+		if (c->haveSaved)
+		{
+		    char    *tmpname;
+		    int     tmpnamelen;
+
+		    tmpname = 0;
+		    (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+			((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+			 &tmpname, &tmpnamelen, c->current.private);
+		    if (--aliascount <= 0)
+		    {
+			err = BadFontName;
+			goto ContBadFontName;
+		    }
+		}
+		else
+		{
+		    c->saved = c->current;
+		    c->haveSaved = TRUE;
+		    if (c->savedName)
+			xfree(c->savedName);
+		    c->savedName = (char *)xalloc(namelen + 1);
+		    if (c->savedName)
+			memmove(c->savedName, name, namelen + 1);
+		    c->savedNameLen = namelen;
+		    aliascount = 20;
+		}
+		memmove(c->current.pattern, tmp_pattern, resolvedlen);
+		c->current.patlen = resolvedlen;
+		c->current.max_names = c->names->nnames + 1;
+		c->current.current_fpe = -1;
+		c->current.private = 0;
+		err = BadFontName;
+	    }
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back. If we've collected enough
+	 * font names, quit.
+	 */
+	if (err == BadFontName) {
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+	    {
+		if (c->names->nnames == c->current.max_names ||
+			c->current.current_fpe == c->num_fpes) {
+		    c->haveSaved = FALSE;
+		    c->current = c->saved;
+		    /* Give the saved namelist a chance to clean itself up */
+		    continue;
+		}
+	    }
+	    if (c->names->nnames == c->current.max_names)
+		break;
+	}
+    }
+
+    /*
+     * send the reply
+     */
+    if (err != Successful) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+	goto bail;
+    }
+
+finish:
+
+    names = c->names;
+    nnames = names->nnames;
+    client = c->client;
+    stringLens = 0;
+    for (i = 0; i < nnames; i++)
+	stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+    reply.type = X_Reply;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    reply.nFonts = nnames;
+    reply.sequenceNumber = client->sequence;
+
+    bufptr = bufferStart = (char *) ALLOCATE_LOCAL(reply.length << 2);
+
+    if (!bufptr && reply.length) {
+	SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+	goto bail;
+    }
+    /*
+     * since WriteToClient long word aligns things, copy to temp buffer and
+     * write all at once
+     */
+    for (i = 0; i < nnames; i++) {
+	if (names->length[i] > 255)
+	    reply.nFonts--;
+	else
+	{
+	    *bufptr++ = names->length[i];
+	    memmove( bufptr, names->names[i], names->length[i]);
+	    bufptr += names->length[i];
+	}
+    }
+    nnames = reply.nFonts;
+    reply.length = (stringLens + nnames + 3) >> 2;
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+    WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+    (void) WriteToClient(client, stringLens + nnames, bufferStart);
+    DEALLOCATE_LOCAL(bufferStart);
+
+bail:
+    if (c->slept)
+	ClientWakeup(client);
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    FreeFontNames(names);
+    xfree(c);
+    if (resolved) xfree(resolved);
+    return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, 
+          unsigned max_names)
+{
+    int         i;
+    LFclosurePtr c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFclosurePtr) xalloc(sizeof *c)))
+	return BadAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list) {
+	xfree(c);
+	return BadAlloc;
+    }
+    c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
+    if (!c->names)
+    {
+	xfree(c->fpe_list);
+	xfree(c);
+	return BadAlloc;
+    }
+    memmove( c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++) {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsAndAliases(client, c);
+    return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+    FontPathElementPtr fpe;
+    int         err = Successful;
+    char       *name;
+    int         namelen;
+    int         numFonts;
+    FontInfoRec fontInfo,
+               *pFontInfo;
+    xListFontsWithInfoReply *reply;
+    int         length;
+    xFontProp  *pFP;
+    int         i;
+    int		aliascount = 0;
+    xListFontsWithInfoReply finalReply;
+
+    if (client->clientGone)
+    {
+	if (c->current.current_fpe < c->num_fpes)
+ 	{
+	    fpe = c->fpe_list[c->current.current_fpe];
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	}
+	err = Successful;
+	goto bail;
+    }
+    client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+    if (!c->current.patlen)
+	goto finish;
+    while (c->current.current_fpe < c->num_fpes)
+    {
+	fpe = c->fpe_list[c->current.current_fpe];
+	err = Successful;
+	if (!c->current.list_started)
+ 	{
+	    err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+		(client, fpe, c->current.pattern, c->current.patlen,
+		 c->current.max_names, &c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+		    c->slept = TRUE;
+		}
+		return TRUE;
+	    }
+	    if (err == Successful)
+		c->current.list_started = TRUE;
+	}
+	if (err == Successful)
+ 	{
+	    name = 0;
+	    pFontInfo = &fontInfo;
+	    err = (*fpe_functions[fpe->type].list_next_font_with_info)
+		(client, fpe, &name, &namelen, &pFontInfo,
+		 &numFonts, c->current.private);
+	    if (err == Suspended)
+ 	    {
+		if (!c->slept)
+ 		{
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doListFontsWithInfo,
+			     c);
+		    c->slept = TRUE;
+		}
+		return TRUE;
+	    }
+	}
+	/*
+	 * When we get an alias back, save our state and reset back to the
+	 * start of the FPE looking for the specified name.  As soon as a real
+	 * font is found for the alias, pop back to the old state
+	 */
+	if (err == FontNameAlias)
+ 	{
+	    /*
+	     * when an alias recurses, we need to give
+	     * the last FPE a chance to clean up; so we call
+	     * it again, and assume that the error returned
+	     * is BadFontName, indicating the alias resolution
+	     * is complete.
+	     */
+	    if (c->haveSaved)
+	    {
+		char	*tmpname;
+		int	tmpnamelen;
+		FontInfoPtr tmpFontInfo;
+
+	    	tmpname = 0;
+	    	tmpFontInfo = &fontInfo;
+	    	(void) (*fpe_functions[fpe->type].list_next_font_with_info)
+		    (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+		     &numFonts, c->current.private);
+		if (--aliascount <= 0)
+		{
+		    err = BadFontName;
+		    goto ContBadFontName;
+		}
+	    }
+	    else
+	    {
+		c->saved = c->current;
+		c->haveSaved = TRUE;
+		c->savedNumFonts = numFonts;
+		if (c->savedName)
+		  xfree(c->savedName);
+		c->savedName = (char *)xalloc(namelen + 1);
+		if (c->savedName)
+		  memmove(c->savedName, name, namelen + 1);
+		aliascount = 20;
+	    }
+	    memmove(c->current.pattern, name, namelen);
+	    c->current.patlen = namelen;
+	    c->current.max_names = 1;
+	    c->current.current_fpe = 0;
+	    c->current.private = 0;
+	    c->current.list_started = FALSE;
+	}
+	/*
+	 * At the end of this FPE, step to the next.  If we've finished
+	 * processing an alias, pop state back.  If we've sent enough font
+	 * names, quit.  Always wait for BadFontName to let the FPE
+	 * have a chance to clean up.
+	 */
+	else if (err == BadFontName)
+ 	{
+	  ContBadFontName: ;
+	    c->current.list_started = FALSE;
+	    c->current.current_fpe++;
+	    err = Successful;
+	    if (c->haveSaved)
+ 	    {
+		if (c->current.max_names == 0 ||
+			c->current.current_fpe == c->num_fpes)
+ 		{
+		    c->haveSaved = FALSE;
+		    c->saved.max_names -= (1 - c->current.max_names);
+		    c->current = c->saved;
+		}
+	    }
+	    else if (c->current.max_names == 0)
+		break;
+	}
+ 	else if (err == Successful)
+ 	{
+	    length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+	    reply = c->reply;
+	    if (c->length < length)
+ 	    {
+		reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+		if (!reply)
+ 		{
+		    err = AllocError;
+		    break;
+		}
+		c->reply = reply;
+		c->length = length;
+	    }
+	    if (c->haveSaved)
+ 	    {
+		numFonts = c->savedNumFonts;
+		name = c->savedName;
+		namelen = strlen(name);
+	    }
+	    reply->type = X_Reply;
+	    reply->length = (sizeof *reply - sizeof(xGenericReply) +
+			     pFontInfo->nprops * sizeof(xFontProp) +
+			     namelen + 3) >> 2;
+	    reply->sequenceNumber = client->sequence;
+	    reply->nameLength = namelen;
+	    reply->minBounds = pFontInfo->ink_minbounds;
+	    reply->maxBounds = pFontInfo->ink_maxbounds;
+	    reply->minCharOrByte2 = pFontInfo->firstCol;
+	    reply->maxCharOrByte2 = pFontInfo->lastCol;
+	    reply->defaultChar = pFontInfo->defaultCh;
+	    reply->nFontProps = pFontInfo->nprops;
+	    reply->drawDirection = pFontInfo->drawDirection;
+	    reply->minByte1 = pFontInfo->firstRow;
+	    reply->maxByte1 = pFontInfo->lastRow;
+	    reply->allCharsExist = pFontInfo->allExist;
+	    reply->fontAscent = pFontInfo->fontAscent;
+	    reply->fontDescent = pFontInfo->fontDescent;
+	    reply->nReplies = numFonts;
+	    pFP = (xFontProp *) (reply + 1);
+	    for (i = 0; i < pFontInfo->nprops; i++)
+ 	    {
+		pFP->name = pFontInfo->props[i].name;
+		pFP->value = pFontInfo->props[i].value;
+		pFP++;
+	    }
+	    WriteSwappedDataToClient(client, length, reply);
+	    (void) WriteToClient(client, namelen, name);
+	    if (pFontInfo == &fontInfo)
+ 	    {
+		xfree(fontInfo.props);
+		xfree(fontInfo.isStringProp);
+	    }
+	    --c->current.max_names;
+	}
+    }
+finish:
+    length = sizeof(xListFontsWithInfoReply);
+    bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+    finalReply.type = X_Reply;
+    finalReply.sequenceNumber = client->sequence;
+    finalReply.length = (sizeof(xListFontsWithInfoReply)
+		     - sizeof(xGenericReply)) >> 2;
+    WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+    if (c->slept)
+	ClientWakeup(client);
+    for (i = 0; i < c->num_fpes; i++)
+	FreeFPE(c->fpe_list[i]);
+    xfree(c->reply);
+    xfree(c->fpe_list);
+    if (c->savedName) xfree(c->savedName);
+    xfree(c);
+    return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, 
+                       int max_names)
+{
+    int		    i;
+    LFWIclosurePtr  c;
+
+    /* 
+     * The right error to return here would be BadName, however the
+     * specification does not allow for a Name error on this request.
+     * Perhaps a better solution would be to return a nil list, i.e.
+     * a list containing zero fontnames.
+     */
+    if (length > XLFDMAXFONTNAMELEN)
+	return BadAlloc;
+
+    if (!(c = (LFWIclosurePtr) xalloc(sizeof *c)))
+	goto badAlloc;
+    c->fpe_list = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * num_fpes);
+    if (!c->fpe_list)
+    {
+	xfree(c);
+	goto badAlloc;
+    }
+    memmove(c->current.pattern, pattern, length);
+    for (i = 0; i < num_fpes; i++)
+    {
+	c->fpe_list[i] = font_path_elements[i];
+	UseFPE(c->fpe_list[i]);
+    }
+    c->client = client;
+    c->num_fpes = num_fpes;
+    c->reply = 0;
+    c->length = 0;
+    c->current.patlen = length;
+    c->current.current_fpe = 0;
+    c->current.max_names = max_names;
+    c->current.list_started = FALSE;
+    c->current.private = 0;
+    c->savedNumFonts = 0;
+    c->haveSaved = FALSE;
+    c->slept = FALSE;
+    c->savedName = 0;
+    doListFontsWithInfo(client, c);
+    return Success;
+badAlloc:
+    return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, register PTclosurePtr c)
+{
+    register FontPtr pFont = c->pGC->font, oldpFont;
+    Font	fid, oldfid;
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+    FontPathElementPtr fpe;
+    GC *origGC = NULL;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+	if (c->slept)
+	{
+	    /* Client has died, but we cannot bail out right now.  We
+	       need to clean up after the work we did when going to
+	       sleep.  Setting the drawable pointer to 0 makes this
+	       happen without any attempts to render or perform other
+	       unnecessary activities.  */
+	    c->pDraw = (DrawablePtr)0;
+	}
+	else
+	{
+	    err = Success;
+	    goto bail;
+	}
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client and avoid further
+	   rendering while we clean up after ourself.  */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	c->pDraw = (DrawablePtr)0;
+    }
+
+    client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+    while (c->endReq - c->pElt > TextEltHeader)
+    {
+	if (*c->pElt == FontChange)
+        {
+	    if (c->endReq - c->pElt < FontShiftSize)
+	    {
+		 err = BadLength;
+		 goto bail;
+	    }
+
+	    oldpFont = pFont;
+	    oldfid = fid;
+
+	    fid =  ((Font)*(c->pElt+4))		/* big-endian */
+		 | ((Font)*(c->pElt+3)) << 8
+		 | ((Font)*(c->pElt+2)) << 16
+		 | ((Font)*(c->pElt+1)) << 24;
+	    pFont = (FontPtr)SecurityLookupIDByType(client, fid, RT_FONT,
+						    SecurityReadAccess);
+	    if (!pFont)
+	    {
+		client->errorValue = fid;
+		err = BadFont;
+		/* restore pFont and fid for step 4 (described below) */
+		pFont = oldpFont;
+		fid = oldfid;
+
+		/* If we're in START_SLEEP mode, the following step
+		   shortens the request...  in the unlikely event that
+		   the fid somehow becomes valid before we come through
+		   again to actually execute the polytext, which would
+		   then mess up our refcounting scheme badly.  */
+		c->err = err;
+		c->endReq = c->pElt;
+
+		goto bail;
+	    }
+
+	    /* Step 3 (described below) on our new font */
+	    if (client_state == START_SLEEP)
+		pFont->refcnt++;
+	    else
+	    {
+		if (pFont != c->pGC->font && c->pDraw)
+		{
+		    ChangeGC( c->pGC, GCFont, &fid);
+		    ValidateGC(c->pDraw, c->pGC);
+		    if (c->reqType == X_PolyText8)
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+		    else
+			c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+		}
+
+		/* Undo the refcnt++ we performed when going to sleep */
+		if (client_state == SLEEPING)
+		    (void)CloseFont(c->pGC->font, (Font)0);
+	    }
+	    c->pElt += FontShiftSize;
+	}
+	else	/* print a string */
+	{
+	    unsigned char *pNextElt;
+	    pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+	    if ( pNextElt > c->endReq)
+	    {
+		err = BadLength;
+		goto bail;
+	    }
+	    if (client_state == START_SLEEP)
+	    {
+		c->pElt = pNextElt;
+		continue;
+	    }
+	    if (c->pDraw)
+	    {
+		lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+				   c->pElt + TextEltHeader);
+	    }
+	    else lgerr = Successful;
+
+	    if (lgerr == Suspended)
+	    {
+		if (!c->slept) {
+		    int len;
+		    GC *pGC;
+		    PTclosurePtr new_closure;
+
+    /*  We're putting the client to sleep.  We need to do a few things
+	to ensure successful and atomic-appearing execution of the
+	remainder of the request.  First, copy the remainder of the
+	request into a safe malloc'd area.  Second, create a scratch GC
+	to use for the remainder of the request.  Third, mark all fonts
+	referenced in the remainder of the request to prevent their
+	deallocation.  Fourth, make the original GC look like the
+	request has completed...  set its font to the final font value
+	from this request.  These GC manipulations are for the unlikely
+	(but possible) event that some other client is using the GC.
+	Steps 3 and 4 are performed by running this procedure through
+	the remainder of the request in a special no-render mode
+	indicated by client_state = START_SLEEP.  */
+
+		    /* Step 1 */
+		    /* Allocate a malloc'd closure structure to replace
+		       the local one we were passed */
+		    new_closure = (PTclosurePtr) xalloc(sizeof(PTclosureRec));
+		    if (!new_closure)
+		    {
+			err = BadAlloc;
+			goto bail;
+		    }
+		    *new_closure = *c;
+		    c = new_closure;
+
+		    len = c->endReq - c->pElt;
+		    c->data = (unsigned char *)xalloc(len);
+		    if (!c->data)
+		    {
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    memmove(c->data, c->pElt, len);
+		    c->pElt = c->data;
+		    c->endReq = c->pElt + len;
+
+		    /* Step 2 */
+
+		    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+		    if (!pGC)
+		    {
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    if ((err = CopyGC(c->pGC, pGC, GCFunction |
+				      GCPlaneMask | GCForeground |
+				      GCBackground | GCFillStyle |
+				      GCTile | GCStipple |
+				      GCTileStipXOrigin |
+				      GCTileStipYOrigin | GCFont |
+				      GCSubwindowMode | GCClipXOrigin |
+				      GCClipYOrigin | GCClipMask)) !=
+				      Success)
+		    {
+			FreeScratchGC(pGC);
+			xfree(c->data);
+			xfree(c);
+			err = BadAlloc;
+			goto bail;
+		    }
+		    origGC = c->pGC;
+		    c->pGC = pGC;
+		    ValidateGC(c->pDraw, c->pGC);
+		    
+		    c->slept = TRUE;
+		    ClientSleep(client,
+		    	     (ClientSleepProcPtr)doPolyText,
+			     (pointer) c);
+
+		    /* Set up to perform steps 3 and 4 */
+		    client_state = START_SLEEP;
+		    continue;	/* on to steps 3 and 4 */
+		}
+		return TRUE;
+	    }
+	    else if (lgerr != Successful)
+	    {
+		err = FontToXError(lgerr);
+		goto bail;
+	    }
+	    if (c->pDraw)
+	    {
+		c->xorg += *((INT8 *)(c->pElt + 1));	/* must be signed */
+		c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+		    *c->pElt, c->pElt + TextEltHeader);
+	    }
+	    c->pElt = pNextElt;
+	}
+    }
+
+bail:
+
+    if (client_state == START_SLEEP)
+    {
+	/* Step 4 */
+	if (pFont != origGC->font)
+	{
+	    ChangeGC(origGC, GCFont, &fid);
+	    ValidateGC(c->pDraw, origGC);
+	}
+
+	/* restore pElt pointer for execution of remainder of the request */
+	c->pElt = c->data;
+	return TRUE;
+    }
+
+    if (c->err != Success) err = c->err;
+    if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+        if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+	    SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt, 
+         unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+    PTclosureRec local_closure;
+
+    local_closure.pElt = pElt;
+    local_closure.endReq = endReq;
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_PolyText8)
+    {
+	local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.polyText =  (PolyTextPtr) pGC->ops->PolyText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.pGC = pGC;
+    local_closure.did = did;
+    local_closure.err = Success;
+    local_closure.slept = FALSE;
+
+    (void) doPolyText(client, &local_closure);
+    return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, register ITclosurePtr c)
+{
+    int err = Success, lgerr;	/* err is in X error, not font error, space */
+    FontPathElementPtr fpe;
+
+    if (client->clientGone)
+    {
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    /* Make sure our drawable hasn't disappeared while we slept. */
+    if (c->slept &&
+	c->pDraw &&
+	c->pDraw != (DrawablePtr)SecurityLookupIDByClass(client, c->did,
+					RC_DRAWABLE, SecurityWriteAccess))
+    {
+	/* Our drawable has disappeared.  Treat like client died... ask
+	   the FPE code to clean up after client. */
+	fpe = c->pGC->font->fpe;
+	(*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+	err = Success;
+	goto bail;
+    }
+
+    lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+    if (lgerr == Suspended)
+    {
+        if (!c->slept) {
+	    GC *pGC;
+	    unsigned char *data;
+	    ITclosurePtr new_closure;
+
+	    /* We're putting the client to sleep.  We need to
+	       save some state.  Similar problem to that handled
+	       in doPolyText, but much simpler because the
+	       request structure is much simpler. */
+
+	    new_closure = (ITclosurePtr) xalloc(sizeof(ITclosureRec));
+	    if (!new_closure)
+	    {
+		err = BadAlloc;
+		goto bail;
+	    }
+	    *new_closure = *c;
+	    c = new_closure;
+
+	    data = (unsigned char *)xalloc(c->nChars * c->itemSize);
+	    if (!data)
+	    {
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    memmove(data, c->data, c->nChars * c->itemSize);
+	    c->data = data;
+
+	    pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+	    if (!pGC)
+	    {
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+			      GCForeground | GCBackground | GCFillStyle |
+			      GCTile | GCStipple | GCTileStipXOrigin |
+			      GCTileStipYOrigin | GCFont |
+			      GCSubwindowMode | GCClipXOrigin |
+			      GCClipYOrigin | GCClipMask)) != Success)
+	    {
+		FreeScratchGC(pGC);
+		xfree(c->data);
+		xfree(c);
+		err = BadAlloc;
+		goto bail;
+	    }
+	    c->pGC = pGC;
+	    ValidateGC(c->pDraw, c->pGC);
+
+	    c->slept = TRUE;
+            ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+        }
+        return TRUE;
+    }
+    else if (lgerr != Successful)
+    {
+        err = FontToXError(lgerr);
+        goto bail;
+    }
+    if (c->pDraw)
+    {
+	(* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+	    c->nChars, c->data);
+    }
+
+bail:
+
+    if (err != Success && c->client != serverClient) {
+	SendErrorToClient(c->client, c->reqType, 0, 0, err);
+    }
+    if (c->slept)
+    {
+	ClientWakeup(c->client);
+	ChangeGC(c->pGC, clearGCmask, clearGC);
+
+	/* Unreference the font from the scratch GC */
+	CloseFont(c->pGC->font, (Font)0);
+	c->pGC->font = NullFont;
+
+	FreeScratchGC(c->pGC);
+	xfree(c->data);
+	xfree(c);
+    }
+    return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars, 
+          unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+    ITclosureRec local_closure;
+
+    local_closure.client = client;
+    local_closure.pDraw = pDraw;
+    local_closure.pGC = pGC;
+    local_closure.nChars = nChars;
+    local_closure.data = data;
+    local_closure.xorg = xorg;
+    local_closure.yorg = yorg;
+    if ((local_closure.reqType = reqType) == X_ImageText8)
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+	local_closure.itemSize = 1;
+    }
+    else
+    {
+	local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+	local_closure.itemSize = 2;
+    }
+    local_closure.did = did;
+    local_closure.slept = FALSE;
+
+    (void) doImageText(client, &local_closure);
+    return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+    int         i;
+
+    for (i = 0; i < num_fpe_types; i++) {
+	if ((*fpe_functions[i].name_check) (pathname))
+	    return i;
+    }
+    return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+    int         i;
+
+    for (i = 0; i < n; i++) {
+	if (force) {
+	    /* Sanity check that all refcounts will be 0 by the time
+	       we get to the end of the list. */
+	    int found = 1;	/* the first reference is us */
+	    int j;
+	    for (j = i+1; j < n; j++) {
+		if (list[j] == list[i])
+		    found++;
+	    }
+	    if (list[i]->refcount != found) {
+		ErrorF("FreeFontPath: FPE \"%.*s\" refcount is %d, should be %d; fixing.\n",
+		       list[i]->name_length, list[i]->name,
+		       list[i]->refcount, found);
+		list[i]->refcount = found; /* ensure it will get freed */
+	    }
+	}
+	FreeFPE(list[i]);
+    }
+    xfree((char *) list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+    FontPathElementPtr fpe;
+    int         i;
+
+    for (i = 0; i < num; i++) {
+	fpe = list[i];
+	if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+	    return fpe;
+    }
+    return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+    int         i, err = 0;
+    int         valid_paths = 0;
+    unsigned int len;
+    unsigned char *cp = paths;
+    FontPathElementPtr fpe = NULL, *fplist;
+
+    fplist = (FontPathElementPtr *)
+	xalloc(sizeof(FontPathElementPtr) * npaths);
+    if (!fplist) {
+	*bad = 0;
+	return BadAlloc;
+    }
+    for (i = 0; i < num_fpe_types; i++) {
+	if (fpe_functions[i].set_path_hook)
+	    (*fpe_functions[i].set_path_hook) ();
+    }
+    for (i = 0; i < npaths; i++) 
+    {
+	len = (unsigned int) (*cp++);
+
+	if (len == 0) 
+	{
+	    if (persist)
+		ErrorF ("Removing empty element from the valid list of fontpaths\n");
+	    err = BadValue;
+	}
+	else
+	{
+	    /* if it's already in our active list, just reset it */
+	    /*
+	     * note that this can miss FPE's in limbo -- may be worth catching
+	     * them, though it'd muck up refcounting
+	     */
+	    fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+	    if (fpe) 
+	    {
+		err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+		if (err == Successful) 
+		{
+		    UseFPE(fpe);/* since it'll be decref'd later when freed
+				 * from the old list */
+		}
+		else
+		    fpe = 0;
+	    }
+	    /* if error or can't do it, act like it's a new one */
+	    if (!fpe)
+	    {
+		fpe = (FontPathElementPtr) xalloc(sizeof(FontPathElementRec));
+		if (!fpe) 
+		{
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->name = (char *) xalloc(len + 1);
+		if (!fpe->name) 
+		{
+		    xfree(fpe);
+		    err = BadAlloc;
+		    goto bail;
+		}
+		fpe->refcount = 1;
+    
+		strncpy(fpe->name, (char *) cp, (int) len);
+		fpe->name[len] = '\0';
+		fpe->name_length = len;
+		fpe->type = DetermineFPEType(fpe->name);
+		if (fpe->type == -1)
+		    err = BadValue;
+		else
+		    err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+		if (err != Successful)
+		{
+		    if (persist)
+		    {
+			ErrorF("Could not init font path element %s, removing from list!\n",
+			       fpe->name);
+		    }
+		    xfree (fpe->name);
+		    xfree (fpe);
+		}
+	    }
+	}
+	if (err != Successful)
+	{
+	    if (!persist)
+		goto bail;
+	}
+	else
+	{
+	    fplist[valid_paths++] = fpe;
+	}
+	cp += len;
+    }
+
+    FreeFontPath(font_path_elements, num_fpes, FALSE);
+    font_path_elements = fplist;
+    if (patternCache)
+	EmptyFontPatternCache(patternCache);
+    num_fpes = valid_paths;
+
+    return Success;
+bail:
+    *bad = i;
+    while (--valid_paths >= 0)
+	FreeFPE(fplist[valid_paths]);
+    xfree(fplist);
+    return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+    int   err = Success;
+
+    if (npaths == 0) {
+	if (SetDefaultFontPath(defaultFontPath) != Success)
+	    return BadValue;
+    } else {
+	err = SetFontPathElements(npaths, paths, error, FALSE);
+    }
+    return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+    unsigned char *cp,
+               *pp,
+               *nump,
+               *newpath;
+    int         num = 1,
+                len,
+                err,
+                size = 0,
+                bad;
+
+    /* get enough for string, plus values -- use up commas */
+    len = strlen(path) + 1;
+    nump = cp = newpath = (unsigned char *) ALLOCATE_LOCAL(len);
+    if (!newpath)
+	return BadAlloc;
+    pp = (unsigned char *) path;
+    cp++;
+    while (*pp) {
+	if (*pp == ',') {
+	    *nump = (unsigned char) size;
+	    nump = cp++;
+	    pp++;
+	    num++;
+	    size = 0;
+	} else {
+	    *cp++ = *pp++;
+	    size++;
+	}
+    }
+    *nump = (unsigned char) size;
+
+    err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+    DEALLOCATE_LOCAL(newpath);
+
+    return err;
+}
+
+unsigned char *
+GetFontPath(int *count, int *length)
+{
+    int			i;
+    unsigned char       *c;
+    int			len;
+    FontPathElementPtr	fpe;
+
+    len = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	len += fpe->name_length + 1;
+    }
+    font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+    if (!font_path_string)
+	return NULL;
+
+    c = font_path_string;
+    *length = 0;
+    for (i = 0; i < num_fpes; i++) {
+	fpe = font_path_elements[i];
+	*c = fpe->name_length;
+	*length += *c++;
+	memmove(c, fpe->name, fpe->name_length);
+	c += fpe->name_length;
+    }
+    *count = num_fpes;
+    return font_path_string;
+}
+
+int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, unsigned char *data)
+{
+    if (fpe_functions[pfont->fpe->type].load_glyphs)
+	return (*fpe_functions[pfont->fpe->type].load_glyphs)
+	    (client, pfont, 0, nchars, item_size, data);
+    else
+	return Successful;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+    int			i;
+    FontPathElementPtr	fpe;
+
+    for (i = 0; i < num_fpes; i++)
+    {
+	fpe = font_path_elements[i];
+	if (fpe_functions[fpe->type].client_died)
+	    (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+    }
+}
+
+void
+InitFonts ()
+{
+    patternCache = MakeFontPatternCache();
+
+#ifndef KDRIVESERVER
+    if (screenInfo.numScreens > screenInfo.numVideoScreens) {
+	PrinterFontRegisterFpeFunctions();
+	FontFileCheckRegisterFpeFunctions();
+	check_fs_register_fpe_functions();
+    } else 
+#endif
+    {
+#ifdef KDRIVESERVER
+	BuiltinRegisterFpeFunctions();
+#endif
+	FontFileRegisterFpeFunctions();
+#ifndef NOFONTSERVERACCESS
+	fs_register_fpe_functions();
+#endif
+    }
+}
+
+int
+GetDefaultPointSize ()
+{
+    return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+    if (requestingClient && requestingClient->fontResFunc != NULL &&
+	!requestingClient->clientGone)
+    {
+	return (*requestingClient->fontResFunc)(requestingClient, num);
+    }
+    else {
+	static struct _FontResolution res;
+	ScreenPtr   pScreen;
+
+	pScreen = screenInfo.screens[0];
+	res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+	/*
+	 * XXX - we'll want this as long as bitmap instances are prevalent 
+	 so that we can match them from scalable fonts
+	 */
+	if (res.x_resolution < 88)
+	    res.x_resolution = 75;
+	else
+	    res.x_resolution = 100;
+	res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+	if (res.y_resolution < 88)
+	    res.y_resolution = 75;
+	else
+	    res.y_resolution = 100;
+	res.point_size = 120;
+	*num = 1;
+	return &res;
+    }
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func, 
+		     InitFpeFunc init_func, 
+		     FreeFpeFunc free_func, 
+		     ResetFpeFunc reset_func, 
+		     OpenFontFunc open_func, 
+		     CloseFontFunc close_func, 
+		     ListFontsFunc list_func, 
+		     StartLfwiFunc start_lfwi_func, 
+		     NextLfwiFunc next_lfwi_func, 
+		     WakeupFpeFunc wakeup_func, 
+		     ClientDiedFunc client_died, 
+		     LoadGlyphsFunc load_glyphs, 
+		     StartLaFunc start_list_alias_func, 
+		     NextLaFunc next_list_alias_func, 
+		     SetPathFunc set_path_func)
+{
+    FPEFunctions *new;
+
+    /* grow the list */
+    new = (FPEFunctions *) xrealloc(fpe_functions,
+				 (num_fpe_types + 1) * sizeof(FPEFunctions));
+    if (!new)
+	return -1;
+    fpe_functions = new;
+
+    fpe_functions[num_fpe_types].name_check = name_func;
+    fpe_functions[num_fpe_types].open_font = open_func;
+    fpe_functions[num_fpe_types].close_font = close_func;
+    fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+    fpe_functions[num_fpe_types].list_fonts = list_func;
+    fpe_functions[num_fpe_types].start_list_fonts_with_info =
+	start_lfwi_func;
+    fpe_functions[num_fpe_types].list_next_font_with_info =
+	next_lfwi_func;
+    fpe_functions[num_fpe_types].init_fpe = init_func;
+    fpe_functions[num_fpe_types].free_fpe = free_func;
+    fpe_functions[num_fpe_types].reset_fpe = reset_func;
+    fpe_functions[num_fpe_types].client_died = client_died;
+    fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+    fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+	start_list_alias_func;
+    fpe_functions[num_fpe_types].list_next_font_or_alias =
+	next_list_alias_func;
+    fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+    return num_fpe_types++;
+}
+
+void
+FreeFonts()
+{
+    if (patternCache) {
+	FreeFontPatternCache(patternCache);
+	patternCache = 0;
+    }
+    FreeFontPath(font_path_elements, num_fpes, TRUE);
+    font_path_elements = 0;
+    num_fpes = 0;
+    xfree(fpe_functions);
+    num_fpe_types = 0;
+    fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+    return (FontPtr) SecurityLookupIDByType(NullClient, id, RT_NONE,
+					    SecurityUnknownAccess);
+}
+
+Font
+GetNewFontClientID()
+{
+    return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+    return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+    FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+    return 0;
+}
+
+static int  fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+    /* if server has reset, make sure the b&w handlers are reinstalled */
+    if (last_server_gen < serverGeneration) {
+	last_server_gen = serverGeneration;
+	fs_handlers_installed = 0;
+    }
+    if (fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	fprintf(stderr, "adding FS b & w handlers\n");
+#endif
+
+	if (!RegisterBlockAndWakeupHandlers(block_handler,
+					    FontWakeup, (pointer) 0))
+	    return AllocError;
+	fs_handlers_installed++;
+    }
+    QueueFontWakeup(fpe);
+    return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+    if (all) {
+	/* remove the handlers if no one else is using them */
+	if (--fs_handlers_installed == 0) {
+
+#ifdef DEBUG
+	    fprintf(stderr, "removing FS b & w handlers\n");
+#endif
+
+	    RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+					 (pointer) 0);
+	}
+    }
+    RemoveFontWakeup(fpe);
+}
+
+#ifdef DEBUG
+#define GLWIDTHBYTESPADDED(bits,nbytes) \
+	((nbytes) == 1 ? (((bits)+7)>>3)        /* pad to 1 byte */ \
+	:(nbytes) == 2 ? ((((bits)+15)>>3)&~1)  /* pad to 2 bytes */ \
+	:(nbytes) == 4 ? ((((bits)+31)>>3)&~3)  /* pad to 4 bytes */ \
+	:(nbytes) == 8 ? ((((bits)+63)>>3)&~7)  /* pad to 8 bytes */ \
+	: 0)
+
+#define GLYPH_SIZE(ch, nbytes)          \
+	GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \
+			(ch)->metrics.leftSideBearing, (nbytes))
+void
+dump_char_ascii(CharInfoPtr cip)
+{
+    int         r,
+                l;
+    int         bpr;
+    int         byte;
+    static unsigned maskTab[] = {
+	(1 << 7), (1 << 6), (1 << 5), (1 << 4),
+	(1 << 3), (1 << 2), (1 << 1), (1 << 0),
+    };
+
+    bpr = GLYPH_SIZE(cip, 4);
+    for (r = 0; r < (cip->metrics.ascent + cip->metrics.descent); r++) {
+	pointer     row = (pointer) cip->bits + r * bpr;
+
+	byte = 0;
+	for (l = 0; l <= (cip->metrics.rightSideBearing -
+			  cip->metrics.leftSideBearing); l++) {
+	    if (maskTab[l & 7] & row[l >> 3])
+		putchar('X');
+	    else
+		putchar('.');
+	}
+	putchar('\n');
+    }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
new file mode 100644
index 000000000..91e290996
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -0,0 +1,4827 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.17 2005/08/25 22:11:04 anholt Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "Xlib.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#ifdef XEVIE
+extern WindowPtr *WindowTable;
+extern int       xevieFlag;
+extern int       xevieClientIndex;
+extern DeviceIntPtr     xeviemouse;
+extern DeviceIntPtr     xeviekb;
+extern Mask      xevieMask;
+extern Mask      xevieFilters[128];
+extern int       xevieEventSent;
+extern int       xevieKBEventSent;
+int    xeviegrabState = 0;
+xEvent *xeviexE;
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "../../dix/dispatch.h"
+
+#include "NXlib.h"
+
+#include "Events.h"
+#include "Windows.h"
+#include "Args.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
+
+#define EXTENSION_EVENT_BASE  64
+
+#define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+	Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+	PointerMotionMask | Button1MotionMask | \
+	Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+	Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+	KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+	MotionMask )
+#define PointerGrabMask ( \
+	ButtonPressMask | ButtonReleaseMask | \
+	EnterWindowMask | LeaveWindowMask | \
+	PointerMotionHintMask | KeymapStateMask | \
+	MotionMask )
+#define AllModifiersMask ( \
+	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+	Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+			      (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+    QdEventPtr		pending, *pendtail;
+    DeviceIntPtr	replayDev;	/* kludgy rock to put flag for */
+    WindowPtr		replayWin;	/*   ComputeFreezes            */
+    Bool		playingEvents;
+    TimeStamp		time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static  struct {
+    CursorPtr	current;
+    BoxRec	hotLimits;	/* logical constraints of hot spot */
+    Bool	confined;	/* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+    RegionPtr	hotShape;	/* additional logical shape constraint */
+#endif
+    BoxRec	physLimits;	/* physical constraints of hot spot */
+    WindowPtr	win;		/* window of logical position */
+    HotSpot	hot;		/* logical pointer position */
+    HotSpot	hotPhys;	/* physical pointer position */
+#ifdef PANORAMIX
+    ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
+    RegionRec   Reg1;	        /* Region 1 for confining motion */
+    RegionRec   Reg2;		/* Region 2 for confining virtual motion */
+    WindowPtr   windows[MAXSCREENS];
+    WindowPtr	confineWin;	/* confine window */ 
+#endif
+} sprite;			/* info about the cursor sprite */
+
+#ifdef XEVIE
+WindowPtr xeviewin;
+HotSpot xeviehot;
+#endif
+
+static void DoEnterLeaveEvents(
+    WindowPtr fromWin,
+    WindowPtr toWin,
+    int mode
+);
+
+static WindowPtr XYToWindow(
+    int x,
+    int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+	NoSuchEvent,		       /* 0 */
+	NoSuchEvent,		       /* 1 */
+	KeyPressMask,		       /* KeyPress */
+	KeyReleaseMask,		       /* KeyRelease */
+	ButtonPressMask,	       /* ButtonPress */
+	ButtonReleaseMask,	       /* ButtonRelease */
+	PointerMotionMask,	       /* MotionNotify (initial state) */
+	EnterWindowMask,	       /* EnterNotify */
+	LeaveWindowMask,	       /* LeaveNotify */
+	FocusChangeMask,	       /* FocusIn */
+	FocusChangeMask,	       /* FocusOut */
+	KeymapStateMask,	       /* KeymapNotify */
+	ExposureMask,		       /* Expose */
+	CantBeFiltered,		       /* GraphicsExpose */
+	CantBeFiltered,		       /* NoExpose */
+	VisibilityChangeMask,	       /* VisibilityNotify */
+	SubstructureNotifyMask,	       /* CreateNotify */
+	StructureAndSubMask,	       /* DestroyNotify */
+	StructureAndSubMask,	       /* UnmapNotify */
+	StructureAndSubMask,	       /* MapNotify */
+	SubstructureRedirectMask,      /* MapRequest */
+	StructureAndSubMask,	       /* ReparentNotify */
+	StructureAndSubMask,	       /* ConfigureNotify */
+	SubstructureRedirectMask,      /* ConfigureRequest */
+	StructureAndSubMask,	       /* GravityNotify */
+	ResizeRedirectMask,	       /* ResizeRequest */
+	StructureAndSubMask,	       /* CirculateNotify */
+	SubstructureRedirectMask,      /* CirculateRequest */
+	PropertyChangeMask,	       /* PropertyNotify */
+	CantBeFiltered,		       /* SelectionClear */
+	CantBeFiltered,		       /* SelectionRequest */
+	CantBeFiltered,		       /* SelectionNotify */
+	ColormapChangeMask,	       /* ColormapNotify */
+	CantBeFiltered,		       /* ClientMessage */
+	CantBeFiltered		       /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+    0x7c				/* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+    int x, 
+    int y, 
+    Bool generateEvent
+){
+    ScreenPtr pScreen;
+    BoxRec box;
+    int i;
+
+    /* x,y are in Screen 0 coordinates.  We need to decide what Screen
+       to send the message too and what the coordinates relative to 
+       that screen are. */
+
+    pScreen = sprite.screen;
+    x += panoramiXdataPtr[0].x;
+    y += panoramiXdataPtr[0].y;
+
+    if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+								x, y, &box)) 
+    {
+	FOR_NSCREENS(i) 
+	{
+	    if(i == pScreen->myNum) 
+		continue;
+	    if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+	    {
+		pScreen = screenInfo.screens[i];
+		break;
+	    }
+	}
+    }
+
+    sprite.screen = pScreen;
+    sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+    sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+    x -= panoramiXdataPtr[pScreen->myNum].x;
+    y -= panoramiXdataPtr[pScreen->myNum].y;
+
+    return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+    ScreenPtr pScreen = sprite.screen;
+    BoxRec newBox = sprite.physLimits;
+
+    /* Translate the constraining box to the screen
+       the sprite is actually on */
+    newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+    newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+    (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents
+){
+    HotSpot new;
+
+    if (!cursor)
+	return;
+ 
+    new = sprite.hotPhys;
+
+    /* I don't care what the DDX has to say about it */
+    sprite.physLimits = sprite.hotLimits;
+
+    /* constrain the pointer to those limits */
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+
+    if (sprite.hotShape)  /* more work if the shape is a mess */
+	ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+    if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	XineramaSetCursorPosition (new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+
+    /* Tell DDX what the limits are */
+    XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+    if(pWin == WindowTable[0]) {
+	    memcpy(sprite.windows, WindowTable, 
+				PanoramiXNumScreens*sizeof(WindowPtr));
+    } else {
+	PanoramiXRes *win;
+	int i;
+
+	win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+	if(!win)
+	    return FALSE;
+
+	for(i = 0; i < PanoramiXNumScreens; i++) {
+	   sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+	   if(!sprite.windows[i])  /* window is being unmapped */
+		return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+   QdEventPtr qe,
+   WindowPtr pWin
+){
+
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;  /* should always be Screen 0 */
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	int x, y, off_x, off_y, i;
+	BoxRec lims;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+        if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+            sprite.hot.x = lims.x1;
+        else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+            sprite.hot.x = lims.x2 - 1;
+        if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+            sprite.hot.y = lims.y1;
+        else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+            sprite.hot.y = lims.y2 - 1;
+
+	if (REGION_NUM_RECTS(&sprite.Reg2) > 1) 
+	    ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	/* Motion events entering DIX get translated to Screen 0
+	   coordinates.  Replayed events have already been 
+	   translated since they've entered DIX before */
+	XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			  panoramiXdataPtr[0].x;
+	XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			  panoramiXdataPtr[0].y;
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+
+	if (sprite.hotShape) 
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    XineramaSetCursorPosition(
+			sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+    if (syncEvents.playingEvents)
+    {
+	XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	int x, y, off_x, off_y, i;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+	if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+	   sprite.hotShape = &sprite.Reg1;
+	else
+	   sprite.hotShape = NullRegion;
+	
+	sprite.confined = FALSE;
+	sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+	XineramaCheckPhysLimits(sprite.current, generateEvents);
+    }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    XineramaCheckPhysLimits(cursor, FALSE);
+    	(*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+	FreeCursor(sprite.current, (Cursor)0);
+	sprite.current = cursor;
+	sprite.current->refcnt++;
+    }
+}
+
+
+#endif  /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+    if ((event < LASTEvent) || (event >= 128))
+	FatalError("SetMaskForEvent: bogus event number");
+    filters[event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+    if (event >= 128)
+	FatalError("SetCriticalEvent: bogus event number");
+    criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+    xEvent xE;
+
+#ifdef PANORAMIX
+    /* Translate back to the sprite screen since processInputProc
+       will translate from sprite screen to screen 0 upon reentry
+       to the DIX layer */
+    if(!noPanoramiXExtension) {
+	x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+	y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+    }
+#endif
+    xE.u.keyButtonPointer.rootX = x;
+    xE.u.keyButtonPointer.rootY = y;
+    if (syncEvents.playingEvents)
+	xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+    else
+	xE.u.keyButtonPointer.time = currentTime.milliseconds;
+    xE.u.u.type = MotionNotify;
+    (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+    BoxRec box;
+    int x = *px, y = *py;
+    int incx = 1, incy = 1;
+
+    if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+	return;
+    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+    /* this is rather crude */
+    do {
+	x += incx;
+	if (x >= box.x2)
+	{
+	    incx = -1;
+	    x = *px - 1;
+	}
+	else if (x < box.x1)
+	{
+	    incx = 1;
+	    x = *px;
+	    y += incy;
+	    if (y >= box.y2)
+	    {
+		incy = -1;
+		y = *py - 1;
+	    }
+	    else if (y < box.y1)
+		return; /* should never get here! */
+	}
+    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+    *px = x;
+    *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents,
+    Bool confineToScreen,
+    ScreenPtr pScreen)
+{
+    HotSpot new;
+
+    if (!cursor)
+	return;
+    new = sprite.hotPhys;
+    if (pScreen)
+	new.pScreen = pScreen;
+    else
+	pScreen = new.pScreen;
+    (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+			      &sprite.physLimits);
+    sprite.confined = confineToScreen;
+    (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &new.x, &new.y); 
+#endif
+    if ((pScreen != sprite.hotPhys.pScreen) ||
+	(new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	if (pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys = new;
+	(*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+}
+
+static void
+CheckVirtualMotion(
+    register QdEventPtr qe,
+    register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaCheckVirtualMotion(qe, pWin);
+	return;
+    }
+#endif
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	BoxRec lims;
+
+	if (sprite.hot.pScreen != pWin->drawable.pScreen)
+	{
+	    sprite.hot.pScreen = pWin->drawable.pScreen;
+#ifdef XEVIE
+	    xeviehot.x = xeviehot.y = 0;
+#endif
+	    sprite.hot.x = sprite.hot.y = 0;
+	}
+	lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+	if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = lims.x1;
+	else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = lims.x2 - 1;
+	if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = lims.y1;
+	else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+	if (wBoundingShape(pWin))
+	    ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaConfineCursorToWindow(pWin, generateEvents);
+	return;
+    }	
+#endif
+
+    if (syncEvents.playingEvents)
+    {
+	CheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+	sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+					       : NullRegion;
+#endif
+	CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+			pScreen);
+    }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+    return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaChangeToCursor(cursor);
+	return;
+    }
+#endif
+
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    CheckPhysLimits(cursor, FALSE, sprite.confined,
+			    (ScreenPtr)NULL);
+	(*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+						  cursor);
+	FreeCursor(sprite.current, (Cursor)0);
+	sprite.current = cursor;
+	sprite.current->refcnt++;
+    }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+    for (b = b->parent; b; b = b->parent)
+	if (b == a) return TRUE;
+    return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+    register    WindowPtr win;
+    register    GrabPtr grab = inputInfo.pointer->grab;
+
+    if (syncEvents.playingEvents)
+	return;
+    if (grab)
+    {
+	if (grab->cursor)
+	{
+	    ChangeToCursor(grab->cursor);
+	    return;
+	}
+	if (IsParent(grab->window, sprite.win))
+	    win = sprite.win;
+	else
+	    win = grab->window;
+    }
+    else
+	win = sprite.win;
+    for (; win; win = win->parent)
+	if (win->optional && win->optional->cursor != NullCursor)
+	{
+	    ChangeToCursor(win->optional->cursor);
+	    return;
+	}
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+    return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+    return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+    return sprite.current;
+}
+
+void
+GetSpritePosition(int *px, int *py)
+{
+    *px = sprite.hotPhys.x;
+    *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+    if(!noPanoramiXExtension) {
+	return sprite.screen->myNum;
+    } else {
+	return 0;
+    }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+    /* If the ddx/OS is careless about not processing timestamped events from
+     * different sources in sorted order, then it's possible for time to go
+     * backwards when it should not.  Here we ensure a decent time.
+     */
+    if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+	currentTime.months++;
+    else
+	XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+    if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+	MonthChangedOrBadTime(xE); \
+    currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+    lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE);
+}
+
+/**************************************************************************
+ *            The following procedures deal with synchronous events       *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+    register QdEventPtr tail = *syncEvents.pendtail;
+    register QdEventPtr qe;
+    xEvent		*qxE;
+
+    NoticeTime(xE);
+
+#ifdef XKB
+    /* Fix for key repeating bug. */
+    if (device->key != NULL && device->key->xkbInfo != NULL && 
+	xE->u.u.type == KeyRelease)
+	AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+    if (DeviceEventCallback)
+    {
+	DeviceEventInfoRec eventinfo;
+	/*  The RECORD spec says that the root window field of motion events
+	 *  must be valid.  At this point, it hasn't been filled in yet, so
+	 *  we do it here.  The long expression below is necessary to get
+	 *  the current root window; the apparently reasonable alternative
+	 *  GetCurrentRootWindow()->drawable.id doesn't give you the right
+	 *  answer on the first motion event after a screen change because
+	 *  the data that GetCurrentRootWindow relies on hasn't been
+	 *  updated yet.
+	 */
+	if (xE->u.u.type == MotionNotify)
+	    XE_KBPTR.root =
+		WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	eventinfo.events = xE;
+	eventinfo.count = count;
+	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+    }
+    if (xE->u.u.type == MotionNotify)
+    {
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension) {
+	    XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			      panoramiXdataPtr[0].x;
+	    XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			      panoramiXdataPtr[0].y;
+	}
+#endif
+	sprite.hotPhys.x = XE_KBPTR.rootX;
+	sprite.hotPhys.y = XE_KBPTR.rootY;
+	/* do motion compression */
+	if (tail &&
+	    (tail->event->u.u.type == MotionNotify) &&
+	    (tail->pScreen == sprite.hotPhys.pScreen))
+	{
+	    tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+	    tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+	    tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+	    tail->months = currentTime.months;
+	    return;
+	}
+    }
+    qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+    if (!qe)
+	return;
+    qe->next = (QdEventPtr)NULL;
+    qe->device = device;
+    qe->pScreen = sprite.hotPhys.pScreen;
+    qe->months = currentTime.months;
+    qe->event = (xEvent *)(qe + 1);
+    qe->evcount = count;
+    for (qxE = qe->event; --count >= 0; qxE++, xE++)
+	*qxE = *xE;
+    if (tail)
+	syncEvents.pendtail = &tail->next;
+    *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+    register QdEventPtr *prev, qe;
+    register DeviceIntPtr dev;
+
+    prev = &syncEvents.pending;
+    while ( (qe = *prev) )
+    {
+	if (!qe->device->sync.frozen)
+	{
+	    *prev = qe->next;
+	    if (*syncEvents.pendtail == *prev)
+		syncEvents.pendtail = prev;
+	    if (qe->event->u.u.type == MotionNotify)
+		CheckVirtualMotion(qe, NullWindow);
+	    syncEvents.time.months = qe->months;
+	    syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+	   /* Translate back to the sprite screen since processInputProc
+	      will translate from sprite screen to screen 0 upon reentry
+	      to the DIX layer */
+	    if(!noPanoramiXExtension) {
+		qe->event->u.keyButtonPointer.rootX += 
+			panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x;
+		qe->event->u.keyButtonPointer.rootY += 
+			panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y;
+	    }
+#endif
+	    (*qe->device->public.processInputProc)(qe->event, qe->device,
+						   qe->evcount);
+	    xfree(qe);
+	    for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+		;
+	    if (!dev)
+		break;
+	    /* Playing the event may have unfrozen another device. */
+	    /* So to play it safe, restart at the head of the queue */
+	    prev = &syncEvents.pending;
+	}
+	else
+	    prev = &qe->next;
+    } 
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+    dev->sync.frozen = frozen;
+    if (frozen)
+	dev->public.processInputProc = dev->public.enqueueInputProc;
+    else
+	dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+    register DeviceIntPtr replayDev = syncEvents.replayDev;
+    register int i;
+    WindowPtr w;
+    register xEvent *xE;
+    int count;
+    GrabPtr grab;
+    register DeviceIntPtr dev;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+	FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+    if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+	return;
+    syncEvents.playingEvents = TRUE;
+    if (replayDev)
+    {
+	xE = replayDev->sync.event;
+	count = replayDev->sync.evcount;
+	syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+	for (i = 0; i < spriteTraceGood; i++)
+	{
+	    if (syncEvents.replayWin == spriteTrace[i])
+	    {
+		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+		    if (replayDev->focus)
+			DeliverFocusedEvent(replayDev, xE, w, count);
+		    else
+			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+					        replayDev, count);
+		}
+		goto playmore;
+	    }
+	}
+	/* must not still be in the same stack */
+	if (replayDev->focus)
+	    DeliverFocusedEvent(replayDev, xE, w, count);
+	else
+	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+    }
+playmore:
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (!dev->sync.frozen)
+	{
+	    PlayReleasedEvents();
+	    break;
+	}
+    }
+    syncEvents.playingEvents = FALSE;
+    /* the following may have been skipped during replay, so do it now */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+    PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+    GrabPtr grab;
+
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+    register GrabPtr grab = thisDev->grab;
+    register DeviceIntPtr dev;
+
+    if (thisMode == GrabModeSync)
+	thisDev->sync.state = FROZEN_NO_EVENT;
+    else
+    {	/* free both if same client owns both */
+	thisDev->sync.state = THAWED;
+	if (thisDev->sync.other &&
+	    (CLIENT_BITS(thisDev->sync.other->resource) ==
+	     CLIENT_BITS(grab->resource)))
+	    thisDev->sync.other = NullGrab;
+    }
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev != thisDev)
+	{
+	    if (otherMode == GrabModeSync)
+		dev->sync.other = grab;
+	    else
+	    {	/* free both if same client owns both */
+		if (dev->sync.other &&
+		    (CLIENT_BITS(dev->sync.other->resource) ==
+		     CLIENT_BITS(grab->resource)))
+		    dev->sync.other = NullGrab;
+	    }
+	}
+    }
+    ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, 
+                    TimeStamp time, Bool autoGrab)
+{
+    WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+				     : sprite.win;
+
+    if (grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+    }
+    DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+    mouse->valuator->motionHintWindow = NullWindow;
+    if (syncEvents.playingEvents)
+	mouse->grabTime = syncEvents.time;
+    else
+	mouse->grabTime = time;
+    if (grab->cursor)
+	grab->cursor->refcnt++;
+    mouse->activeGrab = *grab;
+    mouse->grab = &mouse->activeGrab;
+    mouse->fromPassiveGrab = autoGrab;
+    PostNewCursor();
+    CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * If grab is synchronous, events are delivered to clients only if they send
+     * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the 
+     * delivered event is saved in a queue and replayed later, when grab is released.
+     * We should  export sync grab to X as async in order to avoid events to be 
+     * queued twice, in the agent and in the X server. This solution have a drawback:
+     * replayed events are not delivered to that application that are not clients of
+     * the agent.
+     * A different solution could be to make the grab asynchronous in the agent and 
+     * to export it as synchronous. But this seems to be less safe.
+     *
+     * To make internal grab asynchronous, change previous line as follows.
+     *
+     * if (nxagentOption(Rootless))
+     * {
+     *   CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
+     * }
+     * else
+     * {
+     *   CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+     * }
+     */
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      /*
+       * FIXME: We should use the correct value
+       * for the cursor. Temporarily we set it
+       * to None.
+       */
+
+       int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+                                                 nxagentCollectGrabPointerPredicate);
+
+       NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
+                                1, grab -> eventMask & PointerGrabMask,
+                                    GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
+                                        nxagentWindow(grab -> confineTo) : None,
+                                            None, CurrentTime);
+    }
+
+    #endif
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+    register GrabPtr grab = mouse->grab;
+    register DeviceIntPtr dev;
+
+    mouse->valuator->motionHintWindow = NullWindow;
+    mouse->grab = NullGrab;
+    mouse->sync.state = NOT_GRABBED;
+    mouse->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+    if (grab->confineTo)
+	ConfineCursorToWindow(ROOT, FALSE, FALSE);
+    PostNewCursor();
+    if (grab->cursor)
+	FreeCursor(grab->cursor, (Cursor)0);
+    ComputeFreezes();
+
+    #ifdef NXAGENT_SERVER
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      XUngrabPointer(nxagentDisplay, CurrentTime);
+
+      if (sprite.win == ROOT)
+      {
+        mouse -> button -> state &=
+            ~(Button1Mask | Button2Mask | Button3Mask |
+                  Button4Mask | Button5Mask);
+      }
+    }
+
+    #endif
+}
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+    WindowPtr oldWin;
+
+    if (keybd->grab)
+	oldWin = keybd->grab->window;
+    else if (keybd->focus)
+	oldWin = keybd->focus->win;
+    else
+	oldWin = sprite.win;
+    if (oldWin == FollowKeyboardWin)
+	oldWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+    if (syncEvents.playingEvents)
+	keybd->grabTime = syncEvents.time;
+    else
+	keybd->grabTime = time;
+    keybd->activeGrab = *grab;
+    keybd->grab = &keybd->activeGrab;
+    keybd->fromPassiveGrab = passive;
+    CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+    register GrabPtr grab = keybd->grab;
+    register DeviceIntPtr dev;
+    register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+					       : sprite.win;
+
+    if (focusWin == FollowKeyboardWin)
+	focusWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    keybd->grab = NullGrab;
+    keybd->sync.state = NOT_GRABBED;
+    keybd->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+    ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+    Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+    TimeStamp grabTime;
+    register DeviceIntPtr dev;
+
+    thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+    thisSynced = FALSE;
+    otherGrabbed = FALSE;
+    othersFrozen = TRUE;
+    grabTime = thisDev->grabTime;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev == thisDev)
+	    continue;
+	if (dev->grab && SameClient(dev->grab, client))
+	{
+	    if (!(thisGrabbed || otherGrabbed) ||
+		(CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+		grabTime = dev->grabTime;
+	    otherGrabbed = TRUE;
+	    if (thisDev->sync.other == dev->grab)
+		thisSynced = TRUE;
+	    if (dev->sync.state < FROZEN)
+		othersFrozen = FALSE;
+	}
+	else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+	    othersFrozen = FALSE;
+    }
+    if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+	return;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, grabTime) == EARLIER))
+	return;
+    switch (newState)
+    {
+	case THAWED:	 	       /* Async */
+	    if (thisGrabbed)
+		thisDev->sync.state = THAWED;
+	    if (thisSynced)
+		thisDev->sync.other = NullGrab;
+	    ComputeFreezes();
+	    break;
+	case FREEZE_NEXT_EVENT:		/* Sync */
+	    if (thisGrabbed)
+	    {
+		thisDev->sync.state = FREEZE_NEXT_EVENT;
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		ComputeFreezes();
+	    }
+	    break;
+	case THAWED_BOTH:		/* AsyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case FREEZE_BOTH_NEXT_EVENT:	/* SyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case NOT_GRABBED:		/* Replay */
+	    if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+	    {
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		syncEvents.replayDev = thisDev;
+		syncEvents.replayWin = thisDev->grab->window;
+		(*thisDev->DeactivateGrab)(thisDev);
+		syncEvents.replayDev = (DeviceIntPtr)NULL;
+	    }
+	    break;
+	case THAW_OTHERS:		/* AsyncOthers */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev == thisDev)
+			continue;
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+    }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+    TimeStamp		time;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    REQUEST(xAllowEventsReq);
+
+    REQUEST_SIZE_MATCH(xAllowEventsReq);
+    time = ClientTimeToServerTime(stuff->time);
+    switch (stuff->mode)
+    {
+	case ReplayPointer:
+	    AllowSome(client, time, mouse, NOT_GRABBED);
+	    break;
+	case SyncPointer: 
+	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncPointer: 
+	    AllowSome(client, time, mouse, THAWED);
+	    break;
+	case ReplayKeyboard: 
+	    AllowSome(client, time, keybd, NOT_GRABBED);
+	    break;
+	case SyncKeyboard: 
+	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncKeyboard: 
+	    AllowSome(client, time, keybd, THAWED);
+	    break;
+	case SyncBoth:
+	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+	    break;
+	case AsyncBoth:
+	    AllowSome(client, time, keybd, THAWED_BOTH);
+	    break;
+	default: 
+	    client->errorValue = stuff->mode;
+	    return BadValue;
+    }
+
+    /*
+     * This is not necessary if we export grab to X as asynchronous.
+     *
+     * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
+     *         stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
+     * {
+     *   XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
+     * }
+     */
+
+    return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+    register DeviceIntPtr dev;
+    Bool    done;
+
+    /* XXX CloseDownClient should remove passive grabs before
+     * releasing active grabs.
+     */
+    do {
+    	done = TRUE;
+    	for (dev = inputInfo.devices; dev; dev = dev->next)
+    	{
+	    if (dev->grab && SameClient(dev->grab, client))
+	    {
+	    	(*dev->DeactivateGrab)(dev);
+	    	done = FALSE;
+	    }
+    	}
+    } while (!done);
+}
+
+/**************************************************************************
+ *            The following procedures deal with delivering events        *
+ **************************************************************************/
+
+int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask, 
+                 Mask filter, GrabPtr grab)
+{
+    int i;
+    int type;
+
+#ifdef DEBUG
+    if (debug_events) ErrorF(
+	"Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+	((filter == CantBeFiltered) || (mask & filter)))
+    {
+	if (grab && !SameClient(grab, client))
+	    return -1; /* don't send, but notify caller */
+	type = pEvents->u.u.type;
+	if (type == MotionNotify)
+	{
+	    if (mask & PointerMotionHintMask)
+	    {
+		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+		    pEvents->u.keyButtonPointer.event)
+		{
+#ifdef DEBUG
+		    if (debug_events) ErrorF("\n");
+	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+		    return 1; /* don't send, but pretend we did */
+		}
+		pEvents->u.u.detail = NotifyHint;
+	    }
+	    else
+	    {
+		pEvents->u.u.detail = NotifyNormal;
+	    }
+	}
+#ifdef XINPUT
+	else
+	{
+	    if ((type == DeviceMotionNotify) &&
+		MaybeSendDeviceMotionNotifyHint
+			((deviceKeyButtonPointer*)pEvents, mask) != 0)
+		return 1;
+	}
+#endif
+	type &= 0177;
+	if (type != KeymapNotify)
+	{
+	    /* all extension events must have a sequence number */
+	    for (i = 0; i < count; i++)
+		pEvents[i].u.u.sequenceNumber = client->sequence;
+	}
+
+	if (BitIsOn(criticalEvents, type))
+	{
+#ifdef SMART_SCHEDULE
+	    if (client->smart_priority < SMART_MAX_PRIORITY)
+		client->smart_priority++;
+#endif
+	    SetCriticalOutputPending();
+	}
+
+	WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+	if (debug_events) ErrorF(  " delivered\n");
+#endif
+	return 1;
+    }
+    else
+    {
+#ifdef DEBUG
+	if (debug_events) ErrorF("\n");
+#endif
+	return 0;
+    }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count, 
+                      Mask filter, GrabPtr grab, int mskidx)
+{
+    int deliveries = 0, nondeliveries = 0;
+    int attempt;
+    register InputClients *other;
+    ClientPtr client = NullClient;
+    Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+		              this mask is the mask of the grab. */
+    int type = pEvents->u.u.type;
+
+    /* CantBeFiltered means only window owner gets the event */
+    if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+    {
+	/* if nobody ever wants to see this event, skip some work */
+	if (filter != CantBeFiltered &&
+	    !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+	    return 0;
+	if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+				      pWin->eventMask, filter, grab)) )
+	{
+	    if (attempt > 0)
+	    {
+		deliveries++;
+		client = wClient(pWin);
+		deliveryMask = pWin->eventMask;
+	    } else
+		nondeliveries--;
+	}
+    }
+    if (filter != CantBeFiltered)
+    {
+	if (type & EXTENSION_EVENT_BASE)
+	{
+	    OtherInputMasks *inputMasks;
+
+	    inputMasks = wOtherInputMasks(pWin);
+	    if (!inputMasks ||
+		!(inputMasks->inputEvents[mskidx] & filter))
+		return 0;
+	    other = inputMasks->inputClients;
+	}
+	else
+	    other = (InputClients *)wOtherClients(pWin);
+	for (; other; other = other->next)
+	{
+	    if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+					  other->mask[mskidx], filter, grab)) )
+	    {
+		if (attempt > 0)
+		{
+		    deliveries++;
+		    client = rClient(other);
+		    deliveryMask = other->mask[mskidx];
+		} else
+		    nondeliveries--;
+	    }
+	}
+    }
+    if ((type == ButtonPress) && deliveries && (!grab))
+    {
+	GrabRec tempGrab;
+
+	tempGrab.device = inputInfo.pointer;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.window = pWin;
+	tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+	tempGrab.eventMask = deliveryMask;
+	tempGrab.keyboardMode = GrabModeAsync;
+	tempGrab.pointerMode = GrabModeAsync;
+	tempGrab.confineTo = NullWindow;
+	tempGrab.cursor = NullCursor;
+	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+					   currentTime, TRUE);
+    }
+    else if ((type == MotionNotify) && deliveries)
+	inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+    else
+    {
+	if (((type == DeviceMotionNotify)
+#ifdef XKB
+	     || (type == DeviceButtonPress)
+#endif
+	    ) && deliveries)
+	    CheckDeviceGrabAndHintWindow (pWin, type,
+					  (deviceKeyButtonPointer*) pEvents,
+					  grab, client, deliveryMask);
+    }
+#endif
+    if (deliveries)
+	return deliveries;
+    return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0.  if
+   send works,  return 1 or if send didn't work, return 2.
+   Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int 
+XineramaTryClientEventsResult(
+    ClientPtr client,
+    GrabPtr grab,
+    Mask mask, 
+    Mask filter
+){
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+        ((filter == CantBeFiltered) || (mask & filter)))
+    {
+        if (grab && !SameClient(grab, client)) return -1;
+	else return 1;
+    }
+    return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents, 
+                           int count, Mask filter, ClientPtr dontClient)
+{
+    register OtherClients *other;
+
+
+    if (pWin->eventMask & filter)
+    {
+        if (wClient(pWin) == dontClient)
+	    return 0;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	    return XineramaTryClientEventsResult(
+			wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+	return TryClientEvents(wClient(pWin), pEvents, count,
+			       pWin->eventMask, filter, NullGrab);
+    }
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->mask & filter)
+	{
+            if (SameClient(other, dontClient))
+		return 0;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	      return XineramaTryClientEventsResult(
+			rClient(other), NullGrab, other->mask, filter);
+#endif
+	    return TryClientEvents(rClient(other), pEvents, count,
+				   other->mask, filter, NullGrab);
+	}
+    }
+    return 2;
+}
+
+static void
+FixUpEventFromWindow(
+    xEvent *xE,
+    WindowPtr pWin,
+    Window child,
+    Bool calcChild)
+{
+    if (calcChild)
+    {
+        WindowPtr w=spriteTrace[spriteTraceGood-1];
+	/* If the search ends up past the root should the child field be 
+	 	set to none or should the value in the argument be passed 
+		through. It probably doesn't matter since everyone calls 
+		this function with child == None anyway. */
+
+        while (w) 
+        {
+            /* If the source window is same as event window, child should be
+		none.  Don't bother going all all the way back to the root. */
+
+ 	    if (w == pWin)
+	    { 
+   		child = None;
+ 		break;
+	    }
+	    
+	    if (w->parent == pWin)
+	    {
+		child = w->drawable.id;
+		break;
+            }
+ 	    w = w->parent;
+        } 	    
+    }
+    XE_KBPTR.root = ROOT->drawable.id;
+    XE_KBPTR.event = pWin->drawable.id;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	XE_KBPTR.sameScreen = xTrue;
+	XE_KBPTR.child = child;
+	XE_KBPTR.eventX =
+	XE_KBPTR.rootX - pWin->drawable.x;
+	XE_KBPTR.eventY =
+	XE_KBPTR.rootY - pWin->drawable.y;
+    }
+    else
+    {
+	XE_KBPTR.sameScreen = xFalse;
+	XE_KBPTR.child = None;
+	XE_KBPTR.eventX = 0;
+	XE_KBPTR.eventY = 0;
+    }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab, 
+                    register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+    Window child = None;
+    int type = xE->u.u.type;
+    Mask filter = filters[type];
+    int deliveries = 0;
+
+    if (type & EXTENSION_EVENT_BASE)
+    {
+	register OtherInputMasks *inputMasks;
+	int mskidx = dev->id;
+
+	inputMasks = wOtherInputMasks(pWin);
+	if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+	    return 0;
+	while (pWin)
+	{
+	    if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, mskidx);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(inputMasks &&
+		 (filter & inputMasks->dontPropagateMask[mskidx])))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	    if (pWin)
+		inputMasks = wOtherInputMasks(pWin);
+	}
+    }
+    else
+    {
+	if (!(filter & pWin->deliverableEvents))
+	    return 0;
+	while (pWin)
+	{
+	    if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, 0);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(filter & wDontPropagateMask(pWin)))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	}
+    }
+    return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count, 
+              register WindowPtr otherParent)
+{
+    Mask filter;
+    int     deliveries;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+	return count;
+#endif
+
+    if (!count)
+	return 0;
+    filter = filters[xE->u.u.type];
+    if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+	xE->u.destroyNotify.event = pWin->drawable.id;
+    if (filter != StructureAndSubMask)
+	return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+    deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+				       NullGrab, 0);
+    if (pWin->parent)
+    {
+	xE->u.destroyNotify.event = pWin->parent->drawable.id;
+	deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+					    SubstructureNotifyMask, NullGrab,
+					    0);
+	if (xE->u.u.type == ReparentNotify)
+	{
+	    xE->u.destroyNotify.event = otherParent->drawable.id;
+	    deliveries += DeliverEventsToWindow(otherParent, xE, count,
+						SubstructureNotifyMask,
+						NullGrab, 0);
+	}
+    }
+    return deliveries;
+}
+
+
+static Bool 
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+	return TRUE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	   if(POINT_IN_REGION(sprite.screen, 
+			&sprite.windows[i]->borderSize, 
+			x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, 
+			y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, 
+			&box))
+		return TRUE;
+	}
+    }
+#endif
+    return FALSE;
+}
+
+static WindowPtr 
+XYToWindow(int x, int y)
+{
+    register WindowPtr  pWin;
+    BoxRec		box;
+
+    spriteTraceGood = 1;	/* root window still there */
+
+    if (nxagentOption(Rootless))
+    {
+      if (nxagentLastEnteredWindow == NULL)
+      {
+        return ROOT;
+      }
+
+      pWin = ROOT->lastChild;
+
+      while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
+      {
+        pWin = pWin->prevSib;
+      }
+    }
+    else
+    {
+      pWin = ROOT->firstChild;
+    }
+
+    while (pWin)
+    {
+	if ((pWin->mapped) &&
+	    (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+	    (x < pWin->drawable.x + (int)pWin->drawable.width +
+	     wBorderWidth(pWin)) &&
+	    (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+	    (y < pWin->drawable.y + (int)pWin->drawable.height +
+	     wBorderWidth (pWin))
+#ifdef SHAPE
+	    /* When a window is shaped, a further check
+	     * is made to see if the point is inside
+	     * borderSize
+	     */
+	    && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+	    && (!wInputShape(pWin) ||
+		POINT_IN_REGION(pWin->drawable.pScreen,
+				wInputShape(pWin),
+				x - pWin->drawable.x,
+				y - pWin->drawable.y, &box))
+#endif
+	    )
+	{
+	    if (spriteTraceGood >= spriteTraceSize)
+	    {
+		spriteTraceSize += 10;
+		Must_have_memory = TRUE; /* XXX */
+		spriteTrace = (WindowPtr *)xrealloc(
+		    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    spriteTrace[spriteTraceGood++] = pWin;
+	    pWin = pWin->firstChild;
+	}
+	else
+	    pWin = pWin->nextSib;
+    }
+    return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaCheckMotion(xE);
+#endif
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+	{
+	    sprite.hot.pScreen = sprite.hotPhys.pScreen;
+	    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+	}
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+	sprite.hotPhys = sprite.hot;
+
+        /*
+         * This code force cursor position to be inside the
+         * root window of the agent. We can't view a reason
+         * to do this and it interacts in an undesirable way
+         * with toggling fullscreen.
+         *
+         * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+         *          (sprite.hotPhys.y != XE_KBPTR.rootY))
+         * {
+         *   (*sprite.hotPhys.pScreen->SetCursorPosition)(
+         *       sprite.hotPhys.pScreen,
+         *           sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+         * }
+         */
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+    if (!(sprite.win->deliverableEvents &
+	  Motion_Filter(inputInfo.pointer->button))
+	!syncEvents.playingEvents)
+    {
+	/* XXX Do PointerNonInterestBox here */
+    }
+#endif
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+    (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx.  The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+    ScreenPtr pScreen = win->drawable.pScreen;
+    GrabPtr   grab;
+
+    if (noPanoramiXExtension) return;
+    
+    sprite.hot.x        -= xoff;
+    sprite.hot.y        -= yoff;
+
+    sprite.hotPhys.x    -= xoff;
+    sprite.hotPhys.y    -= yoff;
+
+    sprite.hotLimits.x1 -= xoff; 
+    sprite.hotLimits.y1 -= yoff;
+    sprite.hotLimits.x2 -= xoff;
+    sprite.hotLimits.y2 -= yoff;
+
+    if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
+        REGION_TRANSLATE(sprite.screen, &sprite.Reg1,    xoff, yoff);
+    if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
+        REGION_TRANSLATE(sprite.screen, &sprite.Reg2,    xoff, yoff);
+
+    /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    } else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+    register ScreenPtr pScreen = win->drawable.pScreen;
+    #ifdef VIEWPORT_FRAME
+    extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+    #endif
+    extern int  nxagentShadowInit(ScreenPtr, WindowPtr);
+
+    sprite.hotPhys.pScreen = pScreen;
+    sprite.hotPhys.x = pScreen->width / 2;
+    sprite.hotPhys.y = pScreen->height / 2;
+    sprite.hot = sprite.hotPhys;
+    sprite.hotLimits.x2 = pScreen->width;
+    sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = win;
+    sprite.current = wCursor (win);
+    sprite.current->refcnt++;
+    spriteTraceGood = 1;
+    ROOT = win;
+    (*pScreen->CursorLimits) (
+	pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+    sprite.confined = FALSE;
+    (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+    (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+    (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+	sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+	sprite.hotLimits.x2 = PanoramiXPixWidth  - panoramiXdataPtr[0].x;
+	sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+	sprite.physLimits = sprite.hotLimits;
+	sprite.confineWin = NullWindow;
+#ifdef SHAPE
+        sprite.hotShape = NullRegion;
+#endif
+	sprite.screen = pScreen;
+	/* gotta UNINIT these someplace */
+	REGION_NULL(pScreen, &sprite.Reg1);
+	REGION_NULL(pScreen, &sprite.Reg2);
+    }
+#endif
+
+    #ifdef VIEWPORT_FRAME
+    nxagentInitViewportFrame(pScreen, win);
+    #endif
+
+    if (nxagentOption(Shadow))
+    {
+      if (nxagentShadowInit(pScreen, win) == -1)
+      {
+        FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName);
+      }
+    }
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+    PostNewCursor();
+}
+
+void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+    sprite.hotPhys.x = x;
+    sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - 
+			    panoramiXdataPtr[0].x;
+	sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - 
+			    panoramiXdataPtr[0].y;
+	if (newScreen != sprite.screen) {
+	    sprite.screen = newScreen;
+	    /* Make sure we tell the DDX to update its copy of the screen */
+	    if(sprite.confineWin)
+		XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+	    else
+		XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+	    /* if the pointer wasn't confined, the DDX won't get 
+	       told of the pointer warp so we reposition it here */
+	    if(!syncEvents.playingEvents)
+		(*sprite.screen->SetCursorPosition)(sprite.screen,
+		    sprite.hotPhys.x + panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x,
+		    sprite.hotPhys.y + panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+	}
+    } else 
+#endif
+    if (newScreen != sprite.hotPhys.pScreen)
+	ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+    WindowPtr pWin,
+    int x,
+    int y
+)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    BoxRec box;
+    int i, xoff, yoff;
+
+    if (!pWin->realized) return FALSE;
+
+    if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+        return TRUE;
+    
+    if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+    xoff = x + panoramiXdataPtr[0].x;  
+    yoff = y + panoramiXdataPtr[0].y;  
+
+    for(i = 1; i < PanoramiXNumScreens; i++) {
+	pWin = sprite.windows[i];
+	pScreen = pWin->drawable.pScreen;
+	x = xoff - panoramiXdataPtr[i].x;
+	y = yoff - panoramiXdataPtr[i].y;
+
+	if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+	   && (!wInputShape(pWin) ||
+	       POINT_IN_REGION(pWin->drawable.pScreen,
+			       wInputShape(pWin),
+			       x - pWin->drawable.x, 
+			       y - pWin->drawable.y, &box)))
+            return TRUE;
+
+    }
+
+    return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+
+    REQUEST(xWarpPointerReq);
+
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if(source == WindowTable[0]) {
+	    winX -= panoramiXdataPtr[0].x;
+	    winY -= panoramiXdataPtr[0].y;
+	}
+	if (x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !XineramaPointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	if(dest == WindowTable[0]) {
+	    x -= panoramiXdataPtr[0].x;
+	    y -= panoramiXdataPtr[0].y;
+	}
+    } 
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < sprite.physLimits.x1)
+	x = sprite.physLimits.x1;
+    else if (x >= sprite.physLimits.x2)
+	x = sprite.physLimits.x2 - 1;
+    if (y < sprite.physLimits.y1)
+	y = sprite.physLimits.y1;
+    else if (y >= sprite.physLimits.y2)
+	y = sprite.physLimits.y2 - 1;
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &x, &y);
+
+    XineramaSetCursorPosition(x, y, TRUE);
+
+    return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+    ScreenPtr	newScreen;
+
+    REQUEST(xWarpPointerReq);
+
+    REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaWarpPointer(client);
+#endif
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+	    x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !PointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) 
+    {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	newScreen = dest->drawable.pScreen;
+    } else 
+	newScreen = sprite.hotPhys.pScreen;
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < 0)
+	x = 0;
+    else if (x >= newScreen->width)
+	x = newScreen->width - 1;
+    if (y < 0)
+	y = 0;
+    else if (y >= newScreen->height)
+	y = newScreen->height - 1;
+
+    if (newScreen == sprite.hotPhys.pScreen)
+    {
+	if (x < sprite.physLimits.x1)
+	    x = sprite.physLimits.x1;
+	else if (x >= sprite.physLimits.x2)
+	    x = sprite.physLimits.x2 - 1;
+	if (y < sprite.physLimits.y1)
+	    y = sprite.physLimits.y1;
+	else if (y >= sprite.physLimits.y2)
+	    y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+	(*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+    }
+    else if (!PointerConfinedToScreen())
+    {
+	NewCurrentScreen(newScreen, x, y);
+    }
+    return Success;
+}
+
+static Bool 
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+     if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+	return TRUE;
+
+#ifdef PANORAMIX
+     if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	    if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+		return TRUE;
+	}
+     }
+#endif
+     return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+	passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+    WindowPtr pWin,
+    register DeviceIntPtr device,
+    register xEvent *xE,
+    int count)
+{
+    register GrabPtr grab = wPassiveGrabs(pWin);
+    GrabRec tempGrab;
+    register xEvent *dxE;
+
+    if (!grab)
+	return FALSE;
+    tempGrab.window = pWin;
+    tempGrab.device = device;
+    tempGrab.type = xE->u.u.type;
+    tempGrab.detail.exact = xE->u.u.detail;
+    tempGrab.detail.pMask = NULL;
+    tempGrab.modifiersDetail.pMask = NULL;
+    for (; grab; grab = grab->next)
+    {
+#ifdef XKB
+	DeviceIntPtr	gdev;
+	XkbSrvInfoPtr	xkbi;
+
+	gdev= grab->modifierDevice;
+	xkbi= gdev->key->xkbInfo;
+#endif
+	tempGrab.modifierDevice = grab->modifierDevice;
+	if ((device == grab->modifierDevice) &&
+	    ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+	     || (xE->u.u.type == DeviceKeyPress)
+#endif
+	     ))
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->prev_state;
+#endif
+	else
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->state;
+#endif
+	if (GrabMatchesSecond(&tempGrab, grab) &&
+	    (!grab->confineTo ||
+	     (grab->confineTo->realized && 
+				BorderSizeNotEmpty(grab->confineTo))))
+	{
+#ifdef XCSECURITY
+	    if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+		return FALSE;
+#endif
+#ifdef XKB
+	    if (!noXkbExtension) {
+		XE_KBPTR.state &= 0x1f00;
+		XE_KBPTR.state |=
+				tempGrab.modifiersDetail.exact&(~0x1f00);
+	    }
+#endif
+	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+ 
+	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+	    (void) TryClientEvents(rClient(grab), xE, count,
+				   filters[xE->u.u.type],
+				   filters[xE->u.u.type],  grab);
+
+	    if (device->sync.state == FROZEN_NO_EVENT)
+	    {
+		if (device->sync.evcount < count)
+		{
+		    Must_have_memory = TRUE; /* XXX */
+		    device->sync.event = (xEvent *)xrealloc(device->sync.event,
+							    count*
+							    sizeof(xEvent));
+		    Must_have_memory = FALSE; /* XXX */
+		}
+		device->sync.evcount = count;
+		for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+		    *dxE = *xE;
+	    	device->sync.state = FROZEN_WITH_EVENT;
+            }	
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated.  If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated.  If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated.  If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE, 
+                 int checkFirst, int count)
+{
+    register int i;
+    register WindowPtr pWin = NULL;
+    register FocusClassPtr focus = device->focus;
+
+    if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+	 || (xE->u.u.type == DeviceButtonPress)
+#endif
+	 ) && (device->button->buttonsDown != 1))
+	return FALSE;
+
+    i = checkFirst;
+
+    if (focus)
+    {
+	for (; i < focus->traceGood; i++)
+	{
+	    pWin = focus->trace[i];
+	    if (pWin->optional &&
+		CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+		return TRUE;
+	}
+  
+	if ((focus->win == NoneWin) ||
+	    (i >= spriteTraceGood) ||
+	    ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+	    return FALSE;
+    }
+
+    for (; i < spriteTraceGood; i++)
+    {
+	pWin = spriteTrace[i];
+	if (pWin->optional &&
+	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+    WindowPtr focus = keybd->focus->win;
+    int mskidx = 0;
+
+    if (focus == FollowKeyboardWin)
+	focus = inputInfo.keyboard->focus->win;
+    if (!focus)
+	return;
+    if (focus == PointerRootWin)
+    {
+	DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+	return;
+    }
+    if ((focus == window) || IsParent(focus, window))
+    {
+	if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+	    return;
+    }
+    /* just deliver it to the focus window */
+    FixUpEventFromWindow(xE, focus, None, FALSE);
+    if (xE->u.u.type & EXTENSION_EVENT_BASE)
+	mskidx = keybd->id;
+    (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+				NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev, 
+                    Bool deactivateGrab, int count)
+{
+    register GrabPtr grab = thisDev->grab;
+    int deliveries = 0;
+    register DeviceIntPtr dev;
+    register xEvent *dxE;
+
+    if (grab->ownerEvents)
+    {
+	WindowPtr focus;
+
+	if (thisDev->focus)
+	{
+	    focus = thisDev->focus->win;
+	    if (focus == FollowKeyboardWin)
+		focus = inputInfo.keyboard->focus->win;
+	}
+	else
+	    focus = PointerRootWin;
+	if (focus == PointerRootWin)
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+					     thisDev, count);
+	else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+					     thisDev, count);
+	else if (focus)
+	    deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+					     thisDev, count);
+    }
+    if (!deliveries)
+    {
+	FixUpEventFromWindow(xE, grab->window, None, TRUE);
+	deliveries = TryClientEvents(rClient(grab), xE, count,
+				     (Mask)grab->eventMask,
+				     filters[xE->u.u.type], grab);
+	if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+			   || xE->u.u.type == DeviceMotionNotify
+#endif
+			   ))
+	    thisDev->valuator->motionHintWindow = grab->window;
+    }
+    if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+					  && xE->u.u.type != DeviceMotionNotify
+#endif
+					  ))
+	switch (thisDev->sync.state)
+	{
+	case FREEZE_BOTH_NEXT_EVENT:
+	    for (dev = inputInfo.devices; dev; dev = dev->next)
+	    {
+		if (dev == thisDev)
+		    continue;
+		FreezeThaw(dev, TRUE);
+		if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+		    (CLIENT_BITS(dev->grab->resource) ==
+		     CLIENT_BITS(thisDev->grab->resource)))
+		    dev->sync.state = FROZEN_NO_EVENT;
+		else
+		    dev->sync.other = thisDev->grab;
+	    }
+	    /* fall through */
+	case FREEZE_NEXT_EVENT:
+	    thisDev->sync.state = FROZEN_WITH_EVENT;
+	    FreezeThaw(thisDev, TRUE);
+	    if (thisDev->sync.evcount < count)
+	    {
+		Must_have_memory = TRUE; /* XXX */
+		thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+							 count*sizeof(xEvent));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    thisDev->sync.evcount = count;
+	    for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+		*dxE = *xE;
+	    break;
+	}
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register int    i;
+    register CARD8  modifiers;
+    register CARD16 mask;
+    GrabPtr         grab = keybd->grab;
+    Bool            deactivateGrab = FALSE;
+    register KeyClassPtr keyc = keybd->key;
+#ifdef XEVIE
+    static Window           rootWin = 0;
+
+    if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+          (xevieMask & xevieFilters[xE->u.u.type])) {
+      key = xE->u.u.detail;
+      kptr = &keyc->down[key >> 3];
+      bit = 1 << (key & 7);
+      if((xE->u.u.type == KeyPress &&  (*kptr & bit)) ||
+         (xE->u.u.type == KeyRelease && !(*kptr & bit)))
+      {} else {
+#ifdef XKB
+        if(!noXkbExtension)
+	    xevieKBEventSent = 1;
+#endif
+        if(!xevieKBEventSent)
+        {
+          xeviekb = keybd;
+          if(!rootWin) {
+	      rootWin = GetCurrentRootWindow()->drawable.id;
+          }
+          xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+          xE->u.keyButtonPointer.root = rootWin;
+          xE->u.keyButtonPointer.child = (xeviewin->firstChild) ? xeviewin->firstChild->
+drawable.id:0;
+          xE->u.keyButtonPointer.rootX = xeviehot.x;
+          xE->u.keyButtonPointer.rootY = xeviehot.y;
+          xE->u.keyButtonPointer.state = keyc->state;
+          WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+#ifdef XKB
+          if(noXkbExtension)
+#endif
+            return;
+        } else {
+	    xevieKBEventSent = 0;
+        }
+      }
+    }
+#endif
+
+    if (!syncEvents.playingEvents)
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+#ifdef XEVIE
+    /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+    if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+	 (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+	  && !noXkbExtension
+#endif
+    )))
+#endif
+    XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+    XE_KBPTR.rootX = sprite.hot.x;
+    XE_KBPTR.rootY = sprite.hot.y;
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+    modifiers = keyc->modifierMap[key];
+#if defined(XKB) && defined(XEVIE)
+    if(!noXkbExtension && !xeviegrabState &&
+       xevieFlag && clients[xevieClientIndex] &&
+       (xevieMask & xevieFilters[xE->u.u.type])) {
+	switch(xE->u.u.type) {
+	  case KeyPress: *kptr &= ~bit; break;
+	  case KeyRelease: *kptr |= bit; break;
+	}
+    }
+#endif
+
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    if (*kptr & bit) /* allow ddx to generate multiple downs */
+	    {   
+		if (!modifiers)
+		{
+		    xE->u.u.type = KeyRelease;
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		    xE->u.u.type = KeyPress;
+		    /* release can have side effects, don't fall through */
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		}
+		return;
+	    }
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr |= bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers)
+		{
+		    /* This key affects modifier "i" */
+		    keyc->modifierKeyCount[i]++;
+		    keyc->state |= mask;
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+	    {
+		keybd->activatingKey = key;
+		return;
+	    }
+	    break;
+	case KeyRelease: 
+	    if (!(*kptr & bit)) /* guard against duplicates */
+		return;
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr &= ~bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers) {
+		    /* This key affects modifier "i" */
+		    if (--keyc->modifierKeyCount[i] <= 0) {
+			keyc->state &= ~mask;
+			keyc->modifierKeyCount[i] = 0;
+		    }
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+    if (grab)
+	DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+    else
+	DeliverFocusedEvent(keybd, xE, sprite.win, count);
+    if (deactivateGrab)
+        (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+   this is only used when the pressing of keys does not cause 
+   CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register KeyClassPtr keyc = keybd->key;
+
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("FixKeyState: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    *kptr |= bit;
+	    break;
+	case KeyRelease: 
+	    *kptr &= ~bit;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+    register GrabPtr	grab = mouse->grab;
+    Bool                deactivateGrab = FALSE;
+    register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+    XkbSrvInfoPtr xkbi;
+
+    xkbi = inputInfo.keyboard->key->xkbInfo;
+#endif
+#ifdef XEVIE
+    if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+       (xevieMask & xevieFilters[xE->u.u.type])) {
+      if(xevieEventSent)
+        xevieEventSent = 0;
+      else {
+        xeviemouse = mouse;
+        WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+        return;
+      }
+    }
+#endif
+
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE)
+    XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+			(noXkbExtension ?
+				inputInfo.keyboard->key->state :
+				xkbi->state.grab_mods)
+#else
+			inputInfo.keyboard->key->state
+#endif
+				    ));
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    /* see comment in EnqueueEvents regarding the next three lines */
+	    if (xE->u.u.type == MotionNotify)
+		XE_KBPTR.root =
+		    WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    if (xE->u.u.type != MotionNotify)
+    {
+	register int  key;
+	register BYTE *kptr;
+	int           bit;
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+
+	key = xE->u.u.detail;
+	kptr = &butc->down[key >> 3];
+	bit = 1 << (key & 7);
+	switch (xE->u.u.type)
+	{
+	case ButtonPress: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (!(*kptr & bit))
+		butc->buttonsDown++;
+	    butc->motionMask = ButtonMotionMask;
+	    *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!grab)
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		    return;
+	    break;
+	case ButtonRelease: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (*kptr & bit)
+		--butc->buttonsDown;
+	    if (!butc->buttonsDown)
+		butc->motionMask = 0;
+	    *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!butc->state && mouse->fromPassiveGrab)
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("bogus pointer event from ddx");
+	}
+    }
+    else if (!CheckMotion(xE))
+	return;
+    if (grab)
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    else
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    if (deactivateGrab)
+        (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+	(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+    register WindowPtr pWin;
+{
+    register OtherClients *others;
+    register WindowPtr pChild;
+
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->optional)
+	{
+	    pChild->optional->otherEventMasks = 0;
+	    for (others = wOtherClients(pChild); others; others = others->next)
+	    {
+		pChild->optional->otherEventMasks |= others->mask;
+	    }
+	}
+	pChild->deliverableEvents = pChild->eventMask|
+				    wOtherEventMasks(pChild);
+	if (pChild->parent)
+	    pChild->deliverableEvents |=
+		(pChild->parent->deliverableEvents &
+		 ~wDontPropagateMask(pChild) & PropagateMask);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+/**
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+    register OtherClientsPtr other, prev;
+    register WindowPtr pWin = (WindowPtr)value;
+
+    prev = 0;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->resource == id)
+	{
+	    if (prev)
+		prev->next = other->next;
+	    else
+	    {
+		if (!(pWin->optional->otherClients = other->next))
+		    CheckWindowOptionalNeed (pWin);
+	    }
+	    xfree(other);
+	    RecalculateDeliverableEvents(pWin);
+	    return(Success);
+	}
+	prev = other;
+    }
+    FatalError("client not on event list");
+    /*NOTREACHED*/
+    return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+    Mask check;
+    OtherClients * others;
+
+    if (mask & ~AllEventMasks)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    check = (mask & AtMostOneClient);
+    if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+    {				       /* It is illegal for two different
+				          clients to select on any of the
+				          events for AtMostOneClient. However,
+				          it is OK, for some client to
+				          continue selecting on one of those
+				          events.  */
+	if ((wClient(pWin) != client) && (check & pWin->eventMask))
+	    return BadAccess;
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (!SameClient(others, client) && (check & others->mask))
+		return BadAccess;
+	}
+    }
+    if (wClient (pWin) == client)
+    {
+	check = pWin->eventMask;
+#ifdef SGIMISC
+	pWin->eventMask =
+	    (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+	pWin->eventMask = mask;
+#endif
+    }
+    else
+    {
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (SameClient(others, client))
+	    {
+		check = others->mask;
+#ifdef SGIMISC
+		mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+		if (mask == 0)
+		{
+		    FreeResource(others->resource, RT_NONE);
+		    return Success;
+		}
+		else
+		    others->mask = mask;
+		goto maskSet;
+	    }
+	}
+	check = 0;
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return BadAlloc;
+	others = (OtherClients *) xalloc(sizeof(OtherClients));
+	if (!others)
+	    return BadAlloc;
+	others->mask = mask;
+	others->resource = FakeClientID(client->index);
+	others->next = pWin->optional->otherClients;
+	pWin->optional->otherClients = others;
+	if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+	    return BadAlloc;
+    }
+maskSet: 
+    if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+	(mask & PointerMotionHintMask) &&
+	!(check & PointerMotionHintMask) &&
+	!inputInfo.pointer->grab)
+	inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client, 
+                       Mask mask, Bool *checkOptional)
+{
+    register int i, free;
+
+    if ((mask & ~PropagateMask) && !permitOldBugs)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    if (pWin->dontPropagate)
+	DontPropagateRefCnts[pWin->dontPropagate]--;
+    if (!mask)
+	i = 0;
+    else
+    {
+	for (i = DNPMCOUNT, free = 0; --i > 0; )
+	{
+	    if (!DontPropagateRefCnts[i])
+		free = i;
+	    else if (mask == DontPropagateMasks[i])
+		break;
+	}
+	if (!i && free)
+	{
+	    i = free;
+	    DontPropagateMasks[i] = mask;
+	}
+    }
+    if (i || !mask)
+    {
+	pWin->dontPropagate = i;
+	if (i)
+	    DontPropagateRefCnts[i]++;
+	if (pWin->optional)
+	{
+	    pWin->optional->dontPropagateMask = mask;
+	    *checkOptional = TRUE;
+	}
+    }
+    else
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	{
+	    if (pWin->dontPropagate)
+		DontPropagateRefCnts[pWin->dontPropagate]++;
+	    return BadAlloc;
+	}
+	pWin->dontPropagate = 0;
+        pWin->optional->dontPropagateMask = mask;
+    }
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+static WindowPtr 
+CommonAncestor(
+    register WindowPtr a,
+    register WindowPtr b)
+{
+    for (b = b->parent; b; b = b->parent)
+	if (IsParent(b, a)) return b;
+    return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+    int type,
+    int mode,
+    int detail,
+    register WindowPtr pWin,
+    Window child)
+{
+    xEvent		event;
+    register DeviceIntPtr keybd = inputInfo.keyboard;
+    WindowPtr		focus;
+    register DeviceIntPtr mouse = inputInfo.pointer;
+    register GrabPtr	grab = mouse->grab;
+    Mask		mask;
+
+    if ((pWin == mouse->valuator->motionHintWindow) &&
+	(detail != NotifyInferior))
+	mouse->valuator->motionHintWindow = NullWindow;
+    if (grab)
+    {
+	mask = (pWin == grab->window) ? grab->eventMask : 0;
+	if (grab->ownerEvents)
+	    mask |= EventMaskForClient(pWin, rClient(grab));
+    }
+    else
+    {
+	mask = pWin->eventMask | wOtherEventMasks(pWin);
+    }
+    if (mask & filters[type])
+    {
+	event.u.u.type = type;
+	event.u.u.detail = detail;
+	event.u.enterLeave.time = currentTime.milliseconds;
+	event.u.enterLeave.rootX = sprite.hot.x;
+	event.u.enterLeave.rootY = sprite.hot.y;
+	/* Counts on the same initial structure of crossing & button events! */
+	FixUpEventFromWindow(&event, pWin, None, FALSE);
+	/* Enter/Leave events always set child */
+	event.u.enterLeave.child = child;
+	event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+					    ELFlagSameScreen : 0;
+#ifdef XKB
+	if (!noXkbExtension) {
+	    event.u.enterLeave.state = mouse->button->state & 0x1f00;
+	    event.u.enterLeave.state |= 
+			XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+	} else
+#endif
+	event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+	event.u.enterLeave.mode = mode;
+	focus = keybd->focus->win;
+	if ((focus != NoneWin) &&
+	    ((pWin == focus) || (focus == PointerRootWin) ||
+	     IsParent(focus, pWin)))
+	    event.u.enterLeave.flags |= ELFlagFocus;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), &event, 1, mask,
+				  filters[type], grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+					NullGrab, 0);
+    }
+    if ((type == EnterNotify) && (mask & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+
+#ifdef XCSECURITY
+	ClientPtr client = grab ? rClient(grab)
+				: clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+	ke.type = KeymapNotify;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+				  KeymapStateMask, grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+					KeymapStateMask, NullGrab, 0);
+    }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+    WindowPtr	parent = child->parent;
+
+    if (ancestor == parent)
+	return;
+    EnterNotifies(ancestor, parent, mode, detail);
+    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+    register WindowPtr  pWin;
+
+    if (ancestor == child)
+	return;
+    for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+    {
+	EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+	child = pWin;
+    }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+    if (fromWin == toWin)
+	return;
+    if (IsParent(fromWin, toWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+	EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+    }
+    else if (IsParent(toWin, fromWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+	LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+    }
+    else
+    { /* neither fromWin nor toWin is descendent of the other */
+	WindowPtr common = CommonAncestor(toWin, fromWin);
+	/* common == NullWindow ==> different screens */
+	EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+	LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+	EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+    }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+    xEvent event;
+
+#ifdef XINPUT
+    if (dev != inputInfo.keyboard)
+    {
+	DeviceFocusEvent(dev, type, mode, detail, pWin);
+	return;
+    }
+#endif
+    event.u.focus.mode = mode;
+    event.u.u.type = type;
+    event.u.u.detail = detail;
+    event.u.focus.window = pWin->drawable.id;
+    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+				0);
+    if ((type == FocusIn) &&
+	((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+#ifdef XCSECURITY
+	ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+	ke.type = KeymapNotify;
+	(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+				    KeymapStateMask, NullGrab, 0);
+    }
+}
+
+ /*
+  * recursive because it is easier
+  * no-op if child not descended from ancestor
+  */
+static Bool
+FocusInEvents(
+    DeviceIntPtr dev,
+    WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+    int mode, int detail,
+    Bool doAncestor)
+{
+    if (child == NullWindow)
+	return ancestor == NullWindow;
+    if (ancestor == child)
+    {
+	if (doAncestor)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+		      doAncestor))
+    {
+	if (child != skipChild)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+    DeviceIntPtr dev,
+    WindowPtr child, WindowPtr ancestor,
+    int mode, int detail,
+    Bool doAncestor)
+{
+    register WindowPtr  pWin;
+
+    for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+	FocusEvent(dev, FocusOut, mode, detail, pWin);
+    if (doAncestor)
+	FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+    int     out, in;		       /* for holding details for to/from
+				          PointerRoot/None */
+    int     i;
+
+    if (fromWin == toWin)
+	return;
+    out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+    in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+    if ((toWin == NullWindow) || (toWin == PointerRootWin))
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+   	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+	    /* Notify all the roots */
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	}
+	else
+	{
+	    if (IsParent(fromWin, sprite.win))
+	      FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+			     FALSE);
+	    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+	    /* next call catches the root too, if the screen changed */
+	    FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+			   NotifyNonlinearVirtual, FALSE);
+	}
+	/* Notify all the roots */
+#ifdef PANORAMIX
+	if ( !noPanoramiXExtension )
+	    FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+	else 
+#endif
+	    for (i=0; i<screenInfo.numScreens; i++)
+	        FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+	if (toWin == PointerRootWin)
+	    (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+				NotifyPointer, TRUE);
+    }
+    else
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	    if (toWin->parent != NullWindow)
+	      (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+				  NotifyNonlinearVirtual, TRUE);
+	    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+	    if (IsParent(toWin, sprite.win))
+    	       (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+				   NotifyPointer, FALSE);
+	}
+	else
+	{
+	    if (IsParent(toWin, fromWin))
+	    {
+		FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+		FocusOutEvents(dev, fromWin->parent, toWin, mode,
+			       NotifyVirtual, FALSE);
+		FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+		if ((IsParent(toWin, sprite.win)) &&
+			(sprite.win != fromWin) &&
+			(!IsParent(fromWin, sprite.win)) &&
+			(!IsParent(sprite.win, fromWin)))
+		    (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					mode, NotifyPointer, FALSE);
+	    }
+	    else
+		if (IsParent(fromWin, toWin))
+		{
+		    if ((IsParent(fromWin, sprite.win)) &&
+			    (sprite.win != fromWin) &&
+			    (!IsParent(toWin, sprite.win)) &&
+			    (!IsParent(sprite.win, toWin)))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+		    (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+					NotifyVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+		}
+		else
+		{
+		/* neither fromWin or toWin is child of other */
+		    WindowPtr common = CommonAncestor(toWin, fromWin);
+		/* common == NullWindow ==> different screens */
+		    if (IsParent(fromWin, sprite.win))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+		    if (fromWin->parent != NullWindow)
+		      FocusOutEvents(dev, fromWin->parent, common, mode,
+				     NotifyNonlinearVirtual, FALSE);
+		    if (toWin->parent != NullWindow)
+		      (void)FocusInEvents(dev, common, toWin, toWin, mode,
+					  NotifyNonlinearVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+		    if (IsParent(toWin, sprite.win))
+			(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					    mode, NotifyPointer, FALSE);
+		}
+	}
+    }
+}
+
+int
+SetInputFocus(
+    ClientPtr client,
+    DeviceIntPtr dev,
+    Window focusID,
+    CARD8 revertTo,
+    Time ctime,
+    Bool followOK)
+{
+    register FocusClassPtr focus;
+    register WindowPtr focusWin;
+    int mode;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((revertTo != RevertToParent) &&
+	(revertTo != RevertToPointerRoot) &&
+	(revertTo != RevertToNone) &&
+	((revertTo != RevertToFollowKeyboard) || !followOK))
+    {
+	client->errorValue = revertTo;
+	return BadValue;
+    }
+    time = ClientTimeToServerTime(ctime);
+    if ((focusID == None) || (focusID == PointerRoot))
+	focusWin = (WindowPtr)(long)focusID;
+    else if ((focusID == FollowKeyboard) && followOK)
+	focusWin = inputInfo.keyboard->focus->win;
+    else if (!(focusWin = SecurityLookupWindow(focusID, client,
+					       SecurityReadAccess)))
+	return BadWindow;
+    else
+    {
+ 	/* It is a match error to try to set the input focus to an 
+	unviewable window. */
+
+	if(!focusWin->realized)
+	    return(BadMatch);
+    }
+    focus = dev->focus;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, focus->time) == EARLIER))
+	return Success;
+    mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+    if (focus->win == FollowKeyboardWin)
+	DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+    else
+	DoFocusEvents(dev, focus->win, focusWin, mode);
+    focus->time = time;
+    focus->revert = revertTo;
+    if (focusID == FollowKeyboard)
+	focus->win = FollowKeyboardWin;
+    else
+	focus->win = focusWin;
+    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+	focus->traceGood = 0;
+    else
+    {
+        int depth = 0;
+	register WindowPtr pWin;
+
+        for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+        if (depth > focus->traceSize)
+        {
+	    focus->traceSize = depth+1;
+	    Must_have_memory = TRUE; /* XXX */
+	    focus->trace = (WindowPtr *)xrealloc(focus->trace,
+						 focus->traceSize *
+						 sizeof(WindowPtr));
+	    Must_have_memory = FALSE; /* XXX */
+	}
+	focus->traceGood = depth;
+        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
+	    focus->trace[depth] = pWin;
+    }
+    return Success;
+}
+
+int
+ProcSetInputFocus(client)
+    ClientPtr client;
+{
+    REQUEST(xSetInputFocusReq);
+
+    REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+	return Success;
+#endif
+    return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+			 stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+    xGetInputFocusReply rep;
+    /* REQUEST(xReq); */
+    FocusClassPtr focus = inputInfo.keyboard->focus;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (focus->win == NoneWin)
+	rep.focus = None;
+    else if (focus->win == PointerRootWin)
+	rep.focus = PointerRoot;
+    else rep.focus = focus->win->drawable.id;
+    rep.revertTo = focus->revert;
+    WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+    return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+    xGrabPointerReply rep;
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    WindowPtr pWin, confineTo;
+    CursorPtr cursor, oldCursor;
+    REQUEST(xGrabPointerReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xGrabPointerReq);
+    UpdateCurrentTime();
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+        return BadValue;
+    }
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+	confineTo = NullWindow;
+    else 
+    {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+	/* at this point, some sort of reply is guaranteed. */
+    time = ClientTimeToServerTime(stuff->time);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    grab = device->grab;
+    if ((grab) && !SameClient(grab, client))
+	rep.status = AlreadyGrabbed;
+    else if ((!pWin->realized) ||
+             (confineTo &&
+                !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+	rep.status = GrabNotViewable;
+    else if (device->sync.frozen &&
+	     device->sync.other && !SameClient(device->sync.other, client))
+	rep.status = GrabFrozen;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	rep.status = GrabInvalidTime;
+    else
+    {
+	GrabRec tempGrab;
+
+	oldCursor = NullCursor;
+	if (grab)
+ 	{
+	    if (grab->confineTo && !confineTo)
+		ConfineCursorToWindow(ROOT, FALSE, FALSE);
+	    oldCursor = grab->cursor;
+	}
+	tempGrab.cursor = cursor;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = stuff->ownerEvents;
+	tempGrab.eventMask = stuff->eventMask;
+	tempGrab.confineTo = confineTo;
+	tempGrab.window = pWin;
+	tempGrab.keyboardMode = stuff->keyboardMode;
+	tempGrab.pointerMode = stuff->pointerMode;
+	tempGrab.device = device;
+	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+	if (oldCursor)
+	    FreeCursor (oldCursor, (Cursor)0);
+	rep.status = GrabSuccess;
+    }
+    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+    return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    register GrabPtr grab = device->grab;
+    CursorPtr newCursor, oldCursor;
+    REQUEST(xChangeActivePointerGrabReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    if (stuff->cursor == None)
+	newCursor = NullCursor;
+    else
+    {
+	newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!newCursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+    if (!grab)
+	return Success;
+    if (!SameClient(grab, client))
+	return Success;
+    time = ClientTimeToServerTime(stuff->time);
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	return Success;
+    oldCursor = grab->cursor;
+    grab->cursor = newCursor;
+    if (newCursor)
+	newCursor->refcnt++;
+    PostNewCursor();
+    if (oldCursor)
+	FreeCursor(oldCursor, (Cursor)0);
+    grab->eventMask = stuff->eventMask;
+    return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	    (grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev, 
+           unsigned this_mode, unsigned other_mode, Window grabWindow, 
+           unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+    register WindowPtr pWin;
+    register GrabPtr grab;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+    {
+	client->errorValue = this_mode;
+        return BadValue;
+    }
+    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+    {
+	client->errorValue = other_mode;
+        return BadValue;
+    }
+    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+    {
+	client->errorValue = ownerEvents;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    time = ClientTimeToServerTime(ctime);
+    grab = dev->grab;
+    if (grab && !SameClient(grab, client))
+	*status = AlreadyGrabbed;
+    else if (!pWin->realized)
+	*status = GrabNotViewable;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+	*status = GrabInvalidTime;
+    else if (dev->sync.frozen &&
+	     dev->sync.other && !SameClient(dev->sync.other, client))
+	*status = GrabFrozen;
+    else
+    {
+	GrabRec tempGrab;
+
+	tempGrab.window = pWin;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = ownerEvents;
+	tempGrab.keyboardMode = this_mode;
+	tempGrab.pointerMode = other_mode;
+	tempGrab.eventMask = mask;
+	tempGrab.device = dev;
+	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+	*status = GrabSuccess;
+    }
+    return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+    xGrabKeyboardReply rep;
+    REQUEST(xGrabKeyboardReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+    {
+	result = Success;
+	rep.status = AlreadyGrabbed;
+    }
+    else
+#endif
+    result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+			stuff->pointerMode, stuff->grabWindow,
+			stuff->ownerEvents, stuff->time,
+			KeyPressMask | KeyReleaseMask, &rep.status);
+    if (result != Success)
+	return result;
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+    return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.keyboard;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	(grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+    xQueryPointerReply rep;
+    WindowPtr pWin, t;
+    REQUEST(xResourceReq);
+    DeviceIntPtr mouse = inputInfo.pointer;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (mouse->valuator->motionHintWindow)
+	MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+    rep.length = 0;
+    rep.root = (ROOT)->drawable.id;
+    rep.rootX = sprite.hot.x;
+    rep.rootY = sprite.hot.y;
+    rep.child = None;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	rep.sameScreen = xTrue;
+	rep.winX = sprite.hot.x - pWin->drawable.x;
+	rep.winY = sprite.hot.y - pWin->drawable.y;
+	for (t = sprite.win; t; t = t->parent)
+	    if (t->parent == pWin)
+	    {
+		rep.child = t->drawable.id;
+		break;
+	    }
+    }
+    else
+    {
+	rep.sameScreen = xFalse;
+	rep.winX = 0;
+	rep.winY = 0;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	rep.rootX += panoramiXdataPtr[0].x;
+	rep.rootY += panoramiXdataPtr[0].y;
+	if(stuff->id == rep.root) {
+	    rep.winX += panoramiXdataPtr[0].x;
+	    rep.winY += panoramiXdataPtr[0].y;
+	}
+    }
+#endif
+
+    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+    return(Success);    
+}
+
+void
+InitEvents()
+{
+    int i;
+
+    sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+    inputInfo.numDevices = 0;
+    inputInfo.devices = (DeviceIntPtr)NULL;
+    inputInfo.off_devices = (DeviceIntPtr)NULL;
+    inputInfo.keyboard = (DeviceIntPtr)NULL;
+    inputInfo.pointer = (DeviceIntPtr)NULL;
+    if (spriteTraceSize == 0)
+    {
+	spriteTraceSize = 32;
+	spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+	if (!spriteTrace)
+	    FatalError("failed to allocate spriteTrace");
+    }
+    spriteTraceGood = 0;
+    lastEventMask = OwnerGrabButtonMask;
+    filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = NullWindow;
+    sprite.current = NullCursor;
+    sprite.hotLimits.x1 = 0;
+    sprite.hotLimits.y1 = 0;
+    sprite.hotLimits.x2 = 0;
+    sprite.hotLimits.y2 = 0;
+    sprite.confined = FALSE;
+    syncEvents.replayDev = (DeviceIntPtr)NULL;
+    syncEvents.replayWin = NullWindow;
+    while (syncEvents.pending)
+    {
+	QdEventPtr next = syncEvents.pending->next;
+	xfree(syncEvents.pending);
+	syncEvents.pending = next;
+    }
+    syncEvents.pendtail = &syncEvents.pending;
+    syncEvents.playingEvents = FALSE;
+    syncEvents.time.months = 0;
+    syncEvents.time.milliseconds = 0;	/* hardly matters */
+    currentTime.months = 0;
+    currentTime.milliseconds = GetTimeInMillis();
+    lastDeviceEventTime = currentTime;
+    for (i = 0; i < DNPMCOUNT; i++)
+    {
+	DontPropagateMasks[i] = 0;
+	DontPropagateRefCnts[i] = 0;
+    }
+}
+
+void
+CloseDownEvents(void)
+{
+  xfree(spriteTrace);
+  spriteTrace = NULL;
+  spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+    WindowPtr pWin;
+    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+    REQUEST(xSendEventReq);
+
+    REQUEST_SIZE_MATCH(xSendEventReq);
+
+    /* The client's event type must be a core event type or one defined by an
+	extension. */
+
+
+#ifdef NXAGENT_CLIPBOARD
+
+    if (stuff -> event.u.u.type == SelectionNotify)
+    {
+    	extern int nxagentSendNotify(xEvent*);
+	if (nxagentSendNotify(&stuff->event) == 1)
+	  return Success;
+    }
+#endif
+
+    if ( ! ((stuff->event.u.u.type > X_Reply &&
+	     stuff->event.u.u.type < LASTEvent) || 
+	    (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+	     stuff->event.u.u.type < (unsigned)lastEvent)))
+    {
+	client->errorValue = stuff->event.u.u.type;
+	return BadValue;
+    }
+    if (stuff->event.u.u.type == ClientMessage &&
+	stuff->event.u.u.detail != 8 &&
+	stuff->event.u.u.detail != 16 &&
+	stuff->event.u.u.detail != 32 &&
+	!permitOldBugs)
+    {
+	client->errorValue = stuff->event.u.u.detail;
+	return BadValue;
+    }
+    if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+	return BadValue;
+    }
+
+    if (stuff->destination == PointerWindow)
+	pWin = sprite.win;
+    else if (stuff->destination == InputFocus)
+    {
+	WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+	if (inputFocus == NoneWin)
+	    return Success;
+
+	/* If the input focus is PointerRootWin, send the event to where
+	the pointer is if possible, then perhaps propogate up to root. */
+   	if (inputFocus == PointerRootWin)
+	    inputFocus = ROOT;
+
+	if (IsParent(inputFocus, sprite.win))
+	{
+	    effectiveFocus = inputFocus;
+	    pWin = sprite.win;
+	}
+	else
+	    effectiveFocus = pWin = inputFocus;
+    }
+    else
+	pWin = SecurityLookupWindow(stuff->destination, client,
+				    SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+    {
+	client->errorValue = stuff->propagate;
+	return BadValue;
+    }
+    stuff->event.u.u.type |= 0x80;
+    if (stuff->propagate)
+    {
+	for (;pWin; pWin = pWin->parent)
+	{
+	    if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				      NullGrab, 0))
+		return Success;
+	    if (pWin == effectiveFocus)
+		return Success;
+	    stuff->eventMask &= ~wDontPropagateMask(pWin);
+	    if (!stuff->eventMask)
+		break;
+	}
+    }
+    else
+	(void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				    NullGrab, 0);
+    return Success;
+}
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+    REQUEST(xUngrabKeyReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xUngrabKeyReq);
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = keybd;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = KeyPress;
+    tempGrab.detail.exact = stuff->key;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+    WindowPtr pWin;
+    REQUEST(xGrabKeyReq);
+    GrabPtr grab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xGrabKeyReq);
+    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return(BadValue);
+    }
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    grab = CreateGrab(client->index, keybd, pWin, 
+	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+	keybd, stuff->modifiers, KeyPress, stuff->key, 
+	NullWindow, NullCursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+    WindowPtr pWin, confineTo;
+    REQUEST(xGrabButtonReq);
+    CursorPtr cursor;
+    GrabPtr grab;
+
+    REQUEST_SIZE_MATCH(xGrabButtonReq);
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return BadValue;
+    }
+    if (stuff->eventMask & ~PointerGrabMask)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+       confineTo = NullWindow;
+    else {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+
+
+    grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
+    permitOldBugs ? (Mask)(stuff->eventMask |
+			       ButtonPressMask | ButtonReleaseMask) :
+			(Mask)stuff->eventMask,
+	(Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+	(Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+	ButtonPress, stuff->button, confineTo, cursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+    REQUEST(xUngrabButtonReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+
+    REQUEST_SIZE_MATCH(xUngrabButtonReq);
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = inputInfo.pointer;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = ButtonPress;
+    tempGrab.detail.exact = stuff->button;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+    WindowPtr		parent;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    FocusClassPtr	focus = keybd->focus;
+    OtherClientsPtr	oc;
+    GrabPtr		passive;
+
+
+    /* Deactivate any grabs performed on this window, before making any
+	input focus changes. */
+
+    if (mouse->grab &&
+	((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+	(*mouse->DeactivateGrab)(mouse);
+
+    /* Deactivating a keyboard grab should cause focus events. */
+
+    if (keybd->grab && (keybd->grab->window == pWin))
+	(*keybd->DeactivateGrab)(keybd);
+
+    /* If the focus window is a root window (ie. has no parent) then don't 
+	delete the focus from it. */
+    
+    if ((pWin == focus->win) && (pWin->parent != NullWindow))
+    {
+	int focusEventMode = NotifyNormal;
+
+ 	/* If a grab is in progress, then alter the mode of focus events. */
+
+	if (keybd->grab)
+	    focusEventMode = NotifyWhileGrabbed;
+
+	switch (focus->revert)
+	{
+	case RevertToNone:
+	    DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+	    focus->win = NoneWin;
+	    focus->traceGood = 0;
+	    break;
+	case RevertToParent:
+	    parent = pWin;
+	    do
+	    {
+		parent = parent->parent;
+		focus->traceGood--;
+	    } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+   during SaveSet processing would cause the focus to revert to the
+   nearest enclosing window which will survive the death of the exiting
+   client, instead of ending up reverting to a dying window and thence
+   to None
+ */
+#ifdef NOTDEF
+ 	      || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+		);
+	    DoFocusEvents(keybd, pWin, parent, focusEventMode);
+	    focus->win = parent;
+	    focus->revert = RevertToNone;
+	    break;
+	case RevertToPointerRoot:
+	    DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+	    focus->win = PointerRootWin;
+	    focus->traceGood = 0;
+	    break;
+	}
+    }
+
+    if (mouse->valuator->motionHintWindow == pWin)
+	mouse->valuator->motionHintWindow = NullWindow;
+
+    if (freeResources)
+    {
+	if (pWin->dontPropagate)
+	    DontPropagateRefCnts[pWin->dontPropagate]--;
+	while ( (oc = wOtherClients(pWin)) )
+	    FreeResource(oc->resource, RT_NONE);
+	while ( (passive = wPassiveGrabs(pWin)) )
+	    FreeResource(passive->resource, RT_NONE);
+     }
+#ifdef XINPUT
+    DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry 
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+    GrabPtr grab = inputInfo.pointer->grab;
+    WindowPtr confineTo;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+    if (grab && (confineTo = grab->confineTo))
+    {
+	if (!BorderSizeNotEmpty(confineTo))
+	    (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+	else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+	    ConfineCursorToWindow(confineTo, TRUE, TRUE);
+    }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+    register OtherClientsPtr	other;
+
+    if (wClient (pWin) == client)
+	return pWin->eventMask;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (SameClient(other, client))
+	    return other->mask;
+    }
+    return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+    CursorPtr pCursor;
+    int		nscr;
+    ScreenPtr	pscr;
+    Bool 	displayed;
+    REQUEST(xRecolorCursorReq);
+
+    REQUEST_SIZE_MATCH(xRecolorCursorReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+					RT_CURSOR, SecurityWriteAccess);
+    if ( !pCursor) 
+    {
+	client->errorValue = stuff->cursor;
+	return (BadCursor);
+    }
+
+    pCursor->foreRed = stuff->foreRed;
+    pCursor->foreGreen = stuff->foreGreen;
+    pCursor->foreBlue = stuff->foreBlue;
+
+    pCursor->backRed = stuff->backRed;
+    pCursor->backGreen = stuff->backGreen;
+    pCursor->backBlue = stuff->backBlue;
+
+    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+    {
+	pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension)
+	    displayed = (pscr == sprite.screen);
+	else
+#endif
+	    displayed = (pscr == sprite.hotPhys.pScreen);
+	( *pscr->RecolorCursor)(pscr, pCursor,
+				(pCursor == sprite.current) && displayed);
+    }
+    return (Success);
+}
+
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+    xEvent    eventCopy;
+#endif
+    xEvent    eventTo, *eventFrom;
+    int       i;
+
+#ifdef XKB
+    if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+	return;
+#endif
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && 
+       (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 
+    {
+	switch(events->u.u.type) {
+	case MotionNotify:
+	case ButtonPress:
+	case ButtonRelease:
+	case KeyPress:
+	case KeyRelease:
+	case EnterNotify:
+	case LeaveNotify:
+	/* 
+	   When multiple clients want the same event DeliverEventsToWindow
+	   passes the same event structure multiple times so we can't 
+	   modify the one passed to us 
+        */
+	    count = 1;  /* should always be 1 */
+	    memcpy(&eventCopy, events, sizeof(xEvent));
+	    eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+	    eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+	    if(eventCopy.u.keyButtonPointer.event == 
+	       eventCopy.u.keyButtonPointer.root) 
+	    {
+		eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+		eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+	    }
+	    events = &eventCopy;
+	    break;
+	default: break;
+	}
+    }
+#endif
+
+    if (EventCallback)
+    {
+	EventInfoRec eventinfo;
+	eventinfo.client = pClient;
+	eventinfo.events = events;
+	eventinfo.count = count;
+	CallCallbacks(&EventCallback, (pointer)&eventinfo);
+    }
+    if(pClient->swapped)
+    {
+	for(i = 0; i < count; i++)
+	{
+	    eventFrom = &events[i];
+	    /* Remember to strip off the leading bit of type in case
+	       this event was sent with "SendEvent." */
+	    (*EventSwapVector[eventFrom->u.u.type & 0177])
+		(eventFrom, &eventTo);
+	    (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+	}
+    }
+    else
+    {
+	(void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
new file mode 100644
index 000000000..91e290996
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -0,0 +1,4827 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.17 2005/08/25 22:11:04 anholt Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "Xlib.h"
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#ifdef XEVIE
+extern WindowPtr *WindowTable;
+extern int       xevieFlag;
+extern int       xevieClientIndex;
+extern DeviceIntPtr     xeviemouse;
+extern DeviceIntPtr     xeviekb;
+extern Mask      xevieMask;
+extern Mask      xevieFilters[128];
+extern int       xevieEventSent;
+extern int       xevieKBEventSent;
+int    xeviegrabState = 0;
+xEvent *xeviexE;
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "../../dix/dispatch.h"
+
+#include "NXlib.h"
+
+#include "Events.h"
+#include "Windows.h"
+#include "Args.h"
+
+extern Display *nxagentDisplay;
+
+extern WindowPtr nxagentLastEnteredWindow;
+
+#define EXTENSION_EVENT_BASE  64
+
+#define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+	Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+	PointerMotionMask | Button1MotionMask | \
+	Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+	Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+	KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+	MotionMask )
+#define PointerGrabMask ( \
+	ButtonPressMask | ButtonReleaseMask | \
+	EnterWindowMask | LeaveWindowMask | \
+	PointerMotionHintMask | KeymapStateMask | \
+	MotionMask )
+#define AllModifiersMask ( \
+	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+	Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+			      (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+    QdEventPtr		pending, *pendtail;
+    DeviceIntPtr	replayDev;	/* kludgy rock to put flag for */
+    WindowPtr		replayWin;	/*   ComputeFreezes            */
+    Bool		playingEvents;
+    TimeStamp		time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static  struct {
+    CursorPtr	current;
+    BoxRec	hotLimits;	/* logical constraints of hot spot */
+    Bool	confined;	/* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+    RegionPtr	hotShape;	/* additional logical shape constraint */
+#endif
+    BoxRec	physLimits;	/* physical constraints of hot spot */
+    WindowPtr	win;		/* window of logical position */
+    HotSpot	hot;		/* logical pointer position */
+    HotSpot	hotPhys;	/* physical pointer position */
+#ifdef PANORAMIX
+    ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
+    RegionRec   Reg1;	        /* Region 1 for confining motion */
+    RegionRec   Reg2;		/* Region 2 for confining virtual motion */
+    WindowPtr   windows[MAXSCREENS];
+    WindowPtr	confineWin;	/* confine window */ 
+#endif
+} sprite;			/* info about the cursor sprite */
+
+#ifdef XEVIE
+WindowPtr xeviewin;
+HotSpot xeviehot;
+#endif
+
+static void DoEnterLeaveEvents(
+    WindowPtr fromWin,
+    WindowPtr toWin,
+    int mode
+);
+
+static WindowPtr XYToWindow(
+    int x,
+    int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+	NoSuchEvent,		       /* 0 */
+	NoSuchEvent,		       /* 1 */
+	KeyPressMask,		       /* KeyPress */
+	KeyReleaseMask,		       /* KeyRelease */
+	ButtonPressMask,	       /* ButtonPress */
+	ButtonReleaseMask,	       /* ButtonRelease */
+	PointerMotionMask,	       /* MotionNotify (initial state) */
+	EnterWindowMask,	       /* EnterNotify */
+	LeaveWindowMask,	       /* LeaveNotify */
+	FocusChangeMask,	       /* FocusIn */
+	FocusChangeMask,	       /* FocusOut */
+	KeymapStateMask,	       /* KeymapNotify */
+	ExposureMask,		       /* Expose */
+	CantBeFiltered,		       /* GraphicsExpose */
+	CantBeFiltered,		       /* NoExpose */
+	VisibilityChangeMask,	       /* VisibilityNotify */
+	SubstructureNotifyMask,	       /* CreateNotify */
+	StructureAndSubMask,	       /* DestroyNotify */
+	StructureAndSubMask,	       /* UnmapNotify */
+	StructureAndSubMask,	       /* MapNotify */
+	SubstructureRedirectMask,      /* MapRequest */
+	StructureAndSubMask,	       /* ReparentNotify */
+	StructureAndSubMask,	       /* ConfigureNotify */
+	SubstructureRedirectMask,      /* ConfigureRequest */
+	StructureAndSubMask,	       /* GravityNotify */
+	ResizeRedirectMask,	       /* ResizeRequest */
+	StructureAndSubMask,	       /* CirculateNotify */
+	SubstructureRedirectMask,      /* CirculateRequest */
+	PropertyChangeMask,	       /* PropertyNotify */
+	CantBeFiltered,		       /* SelectionClear */
+	CantBeFiltered,		       /* SelectionRequest */
+	CantBeFiltered,		       /* SelectionNotify */
+	ColormapChangeMask,	       /* ColormapNotify */
+	CantBeFiltered,		       /* ClientMessage */
+	CantBeFiltered		       /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+    0x7c				/* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+    int x, 
+    int y, 
+    Bool generateEvent
+){
+    ScreenPtr pScreen;
+    BoxRec box;
+    int i;
+
+    /* x,y are in Screen 0 coordinates.  We need to decide what Screen
+       to send the message too and what the coordinates relative to 
+       that screen are. */
+
+    pScreen = sprite.screen;
+    x += panoramiXdataPtr[0].x;
+    y += panoramiXdataPtr[0].y;
+
+    if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+								x, y, &box)) 
+    {
+	FOR_NSCREENS(i) 
+	{
+	    if(i == pScreen->myNum) 
+		continue;
+	    if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+	    {
+		pScreen = screenInfo.screens[i];
+		break;
+	    }
+	}
+    }
+
+    sprite.screen = pScreen;
+    sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+    sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+    x -= panoramiXdataPtr[pScreen->myNum].x;
+    y -= panoramiXdataPtr[pScreen->myNum].y;
+
+    return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+    ScreenPtr pScreen = sprite.screen;
+    BoxRec newBox = sprite.physLimits;
+
+    /* Translate the constraining box to the screen
+       the sprite is actually on */
+    newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+    newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+    (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents
+){
+    HotSpot new;
+
+    if (!cursor)
+	return;
+ 
+    new = sprite.hotPhys;
+
+    /* I don't care what the DDX has to say about it */
+    sprite.physLimits = sprite.hotLimits;
+
+    /* constrain the pointer to those limits */
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+
+    if (sprite.hotShape)  /* more work if the shape is a mess */
+	ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+    if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	XineramaSetCursorPosition (new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+
+    /* Tell DDX what the limits are */
+    XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+    if(pWin == WindowTable[0]) {
+	    memcpy(sprite.windows, WindowTable, 
+				PanoramiXNumScreens*sizeof(WindowPtr));
+    } else {
+	PanoramiXRes *win;
+	int i;
+
+	win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+	if(!win)
+	    return FALSE;
+
+	for(i = 0; i < PanoramiXNumScreens; i++) {
+	   sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+	   if(!sprite.windows[i])  /* window is being unmapped */
+		return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+   QdEventPtr qe,
+   WindowPtr pWin
+){
+
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;  /* should always be Screen 0 */
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	int x, y, off_x, off_y, i;
+	BoxRec lims;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+        if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+            sprite.hot.x = lims.x1;
+        else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+            sprite.hot.x = lims.x2 - 1;
+        if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+            sprite.hot.y = lims.y1;
+        else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+            sprite.hot.y = lims.y2 - 1;
+
+	if (REGION_NUM_RECTS(&sprite.Reg2) > 1) 
+	    ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	/* Motion events entering DIX get translated to Screen 0
+	   coordinates.  Replayed events have already been 
+	   translated since they've entered DIX before */
+	XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			  panoramiXdataPtr[0].x;
+	XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			  panoramiXdataPtr[0].y;
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+
+	if (sprite.hotShape) 
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    XineramaSetCursorPosition(
+			sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+    if (syncEvents.playingEvents)
+    {
+	XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	int x, y, off_x, off_y, i;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+	if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+	   sprite.hotShape = &sprite.Reg1;
+	else
+	   sprite.hotShape = NullRegion;
+	
+	sprite.confined = FALSE;
+	sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+	XineramaCheckPhysLimits(sprite.current, generateEvents);
+    }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    XineramaCheckPhysLimits(cursor, FALSE);
+    	(*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+	FreeCursor(sprite.current, (Cursor)0);
+	sprite.current = cursor;
+	sprite.current->refcnt++;
+    }
+}
+
+
+#endif  /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+    if ((event < LASTEvent) || (event >= 128))
+	FatalError("SetMaskForEvent: bogus event number");
+    filters[event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+    if (event >= 128)
+	FatalError("SetCriticalEvent: bogus event number");
+    criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+    xEvent xE;
+
+#ifdef PANORAMIX
+    /* Translate back to the sprite screen since processInputProc
+       will translate from sprite screen to screen 0 upon reentry
+       to the DIX layer */
+    if(!noPanoramiXExtension) {
+	x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+	y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+    }
+#endif
+    xE.u.keyButtonPointer.rootX = x;
+    xE.u.keyButtonPointer.rootY = y;
+    if (syncEvents.playingEvents)
+	xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+    else
+	xE.u.keyButtonPointer.time = currentTime.milliseconds;
+    xE.u.u.type = MotionNotify;
+    (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+    BoxRec box;
+    int x = *px, y = *py;
+    int incx = 1, incy = 1;
+
+    if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+	return;
+    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+    /* this is rather crude */
+    do {
+	x += incx;
+	if (x >= box.x2)
+	{
+	    incx = -1;
+	    x = *px - 1;
+	}
+	else if (x < box.x1)
+	{
+	    incx = 1;
+	    x = *px;
+	    y += incy;
+	    if (y >= box.y2)
+	    {
+		incy = -1;
+		y = *py - 1;
+	    }
+	    else if (y < box.y1)
+		return; /* should never get here! */
+	}
+    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+    *px = x;
+    *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents,
+    Bool confineToScreen,
+    ScreenPtr pScreen)
+{
+    HotSpot new;
+
+    if (!cursor)
+	return;
+    new = sprite.hotPhys;
+    if (pScreen)
+	new.pScreen = pScreen;
+    else
+	pScreen = new.pScreen;
+    (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+			      &sprite.physLimits);
+    sprite.confined = confineToScreen;
+    (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &new.x, &new.y); 
+#endif
+    if ((pScreen != sprite.hotPhys.pScreen) ||
+	(new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	if (pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys = new;
+	(*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+}
+
+static void
+CheckVirtualMotion(
+    register QdEventPtr qe,
+    register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaCheckVirtualMotion(qe, pWin);
+	return;
+    }
+#endif
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	BoxRec lims;
+
+	if (sprite.hot.pScreen != pWin->drawable.pScreen)
+	{
+	    sprite.hot.pScreen = pWin->drawable.pScreen;
+#ifdef XEVIE
+	    xeviehot.x = xeviehot.y = 0;
+#endif
+	    sprite.hot.x = sprite.hot.y = 0;
+	}
+	lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+	if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = lims.x1;
+	else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = lims.x2 - 1;
+	if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = lims.y1;
+	else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+	if (wBoundingShape(pWin))
+	    ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaConfineCursorToWindow(pWin, generateEvents);
+	return;
+    }	
+#endif
+
+    if (syncEvents.playingEvents)
+    {
+	CheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+	sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+					       : NullRegion;
+#endif
+	CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+			pScreen);
+    }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+    return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaChangeToCursor(cursor);
+	return;
+    }
+#endif
+
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    CheckPhysLimits(cursor, FALSE, sprite.confined,
+			    (ScreenPtr)NULL);
+	(*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+						  cursor);
+	FreeCursor(sprite.current, (Cursor)0);
+	sprite.current = cursor;
+	sprite.current->refcnt++;
+    }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+    for (b = b->parent; b; b = b->parent)
+	if (b == a) return TRUE;
+    return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+    register    WindowPtr win;
+    register    GrabPtr grab = inputInfo.pointer->grab;
+
+    if (syncEvents.playingEvents)
+	return;
+    if (grab)
+    {
+	if (grab->cursor)
+	{
+	    ChangeToCursor(grab->cursor);
+	    return;
+	}
+	if (IsParent(grab->window, sprite.win))
+	    win = sprite.win;
+	else
+	    win = grab->window;
+    }
+    else
+	win = sprite.win;
+    for (; win; win = win->parent)
+	if (win->optional && win->optional->cursor != NullCursor)
+	{
+	    ChangeToCursor(win->optional->cursor);
+	    return;
+	}
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+    return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+    return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+    return sprite.current;
+}
+
+void
+GetSpritePosition(int *px, int *py)
+{
+    *px = sprite.hotPhys.x;
+    *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+    if(!noPanoramiXExtension) {
+	return sprite.screen->myNum;
+    } else {
+	return 0;
+    }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+    /* If the ddx/OS is careless about not processing timestamped events from
+     * different sources in sorted order, then it's possible for time to go
+     * backwards when it should not.  Here we ensure a decent time.
+     */
+    if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+	currentTime.months++;
+    else
+	XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+    if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+	MonthChangedOrBadTime(xE); \
+    currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+    lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE);
+}
+
+/**************************************************************************
+ *            The following procedures deal with synchronous events       *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+    register QdEventPtr tail = *syncEvents.pendtail;
+    register QdEventPtr qe;
+    xEvent		*qxE;
+
+    NoticeTime(xE);
+
+#ifdef XKB
+    /* Fix for key repeating bug. */
+    if (device->key != NULL && device->key->xkbInfo != NULL && 
+	xE->u.u.type == KeyRelease)
+	AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+    if (DeviceEventCallback)
+    {
+	DeviceEventInfoRec eventinfo;
+	/*  The RECORD spec says that the root window field of motion events
+	 *  must be valid.  At this point, it hasn't been filled in yet, so
+	 *  we do it here.  The long expression below is necessary to get
+	 *  the current root window; the apparently reasonable alternative
+	 *  GetCurrentRootWindow()->drawable.id doesn't give you the right
+	 *  answer on the first motion event after a screen change because
+	 *  the data that GetCurrentRootWindow relies on hasn't been
+	 *  updated yet.
+	 */
+	if (xE->u.u.type == MotionNotify)
+	    XE_KBPTR.root =
+		WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	eventinfo.events = xE;
+	eventinfo.count = count;
+	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+    }
+    if (xE->u.u.type == MotionNotify)
+    {
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension) {
+	    XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			      panoramiXdataPtr[0].x;
+	    XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			      panoramiXdataPtr[0].y;
+	}
+#endif
+	sprite.hotPhys.x = XE_KBPTR.rootX;
+	sprite.hotPhys.y = XE_KBPTR.rootY;
+	/* do motion compression */
+	if (tail &&
+	    (tail->event->u.u.type == MotionNotify) &&
+	    (tail->pScreen == sprite.hotPhys.pScreen))
+	{
+	    tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+	    tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+	    tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+	    tail->months = currentTime.months;
+	    return;
+	}
+    }
+    qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+    if (!qe)
+	return;
+    qe->next = (QdEventPtr)NULL;
+    qe->device = device;
+    qe->pScreen = sprite.hotPhys.pScreen;
+    qe->months = currentTime.months;
+    qe->event = (xEvent *)(qe + 1);
+    qe->evcount = count;
+    for (qxE = qe->event; --count >= 0; qxE++, xE++)
+	*qxE = *xE;
+    if (tail)
+	syncEvents.pendtail = &tail->next;
+    *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+    register QdEventPtr *prev, qe;
+    register DeviceIntPtr dev;
+
+    prev = &syncEvents.pending;
+    while ( (qe = *prev) )
+    {
+	if (!qe->device->sync.frozen)
+	{
+	    *prev = qe->next;
+	    if (*syncEvents.pendtail == *prev)
+		syncEvents.pendtail = prev;
+	    if (qe->event->u.u.type == MotionNotify)
+		CheckVirtualMotion(qe, NullWindow);
+	    syncEvents.time.months = qe->months;
+	    syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+	   /* Translate back to the sprite screen since processInputProc
+	      will translate from sprite screen to screen 0 upon reentry
+	      to the DIX layer */
+	    if(!noPanoramiXExtension) {
+		qe->event->u.keyButtonPointer.rootX += 
+			panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x;
+		qe->event->u.keyButtonPointer.rootY += 
+			panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y;
+	    }
+#endif
+	    (*qe->device->public.processInputProc)(qe->event, qe->device,
+						   qe->evcount);
+	    xfree(qe);
+	    for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+		;
+	    if (!dev)
+		break;
+	    /* Playing the event may have unfrozen another device. */
+	    /* So to play it safe, restart at the head of the queue */
+	    prev = &syncEvents.pending;
+	}
+	else
+	    prev = &qe->next;
+    } 
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+    dev->sync.frozen = frozen;
+    if (frozen)
+	dev->public.processInputProc = dev->public.enqueueInputProc;
+    else
+	dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+    register DeviceIntPtr replayDev = syncEvents.replayDev;
+    register int i;
+    WindowPtr w;
+    register xEvent *xE;
+    int count;
+    GrabPtr grab;
+    register DeviceIntPtr dev;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+	FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+    if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+	return;
+    syncEvents.playingEvents = TRUE;
+    if (replayDev)
+    {
+	xE = replayDev->sync.event;
+	count = replayDev->sync.evcount;
+	syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+	for (i = 0; i < spriteTraceGood; i++)
+	{
+	    if (syncEvents.replayWin == spriteTrace[i])
+	    {
+		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+		    if (replayDev->focus)
+			DeliverFocusedEvent(replayDev, xE, w, count);
+		    else
+			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+					        replayDev, count);
+		}
+		goto playmore;
+	    }
+	}
+	/* must not still be in the same stack */
+	if (replayDev->focus)
+	    DeliverFocusedEvent(replayDev, xE, w, count);
+	else
+	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+    }
+playmore:
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (!dev->sync.frozen)
+	{
+	    PlayReleasedEvents();
+	    break;
+	}
+    }
+    syncEvents.playingEvents = FALSE;
+    /* the following may have been skipped during replay, so do it now */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+    PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+    GrabPtr grab;
+
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+    register GrabPtr grab = thisDev->grab;
+    register DeviceIntPtr dev;
+
+    if (thisMode == GrabModeSync)
+	thisDev->sync.state = FROZEN_NO_EVENT;
+    else
+    {	/* free both if same client owns both */
+	thisDev->sync.state = THAWED;
+	if (thisDev->sync.other &&
+	    (CLIENT_BITS(thisDev->sync.other->resource) ==
+	     CLIENT_BITS(grab->resource)))
+	    thisDev->sync.other = NullGrab;
+    }
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev != thisDev)
+	{
+	    if (otherMode == GrabModeSync)
+		dev->sync.other = grab;
+	    else
+	    {	/* free both if same client owns both */
+		if (dev->sync.other &&
+		    (CLIENT_BITS(dev->sync.other->resource) ==
+		     CLIENT_BITS(grab->resource)))
+		    dev->sync.other = NullGrab;
+	    }
+	}
+    }
+    ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, 
+                    TimeStamp time, Bool autoGrab)
+{
+    WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+				     : sprite.win;
+
+    if (grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+    }
+    DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+    mouse->valuator->motionHintWindow = NullWindow;
+    if (syncEvents.playingEvents)
+	mouse->grabTime = syncEvents.time;
+    else
+	mouse->grabTime = time;
+    if (grab->cursor)
+	grab->cursor->refcnt++;
+    mouse->activeGrab = *grab;
+    mouse->grab = &mouse->activeGrab;
+    mouse->fromPassiveGrab = autoGrab;
+    PostNewCursor();
+    CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * If grab is synchronous, events are delivered to clients only if they send
+     * an AllowEvent request. If mode field in AllowEvent request is SyncPointer, the 
+     * delivered event is saved in a queue and replayed later, when grab is released.
+     * We should  export sync grab to X as async in order to avoid events to be 
+     * queued twice, in the agent and in the X server. This solution have a drawback:
+     * replayed events are not delivered to that application that are not clients of
+     * the agent.
+     * A different solution could be to make the grab asynchronous in the agent and 
+     * to export it as synchronous. But this seems to be less safe.
+     *
+     * To make internal grab asynchronous, change previous line as follows.
+     *
+     * if (nxagentOption(Rootless))
+     * {
+     *   CheckGrabForSyncs(mouse, GrabModeAsync, (Bool)grab->keyboardMode);
+     * }
+     * else
+     * {
+     *   CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+     * }
+     */
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      /*
+       * FIXME: We should use the correct value
+       * for the cursor. Temporarily we set it
+       * to None.
+       */
+
+       int resource = nxagentWaitForResource(NXGetCollectGrabPointerResource,
+                                                 nxagentCollectGrabPointerPredicate);
+
+       NXCollectGrabPointer(nxagentDisplay, resource, nxagentWindow(grab -> window),
+                                1, grab -> eventMask & PointerGrabMask,
+                                    GrabModeAsync, GrabModeAsync, (grab -> confineTo) ?
+                                        nxagentWindow(grab -> confineTo) : None,
+                                            None, CurrentTime);
+    }
+
+    #endif
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+    register GrabPtr grab = mouse->grab;
+    register DeviceIntPtr dev;
+
+    mouse->valuator->motionHintWindow = NullWindow;
+    mouse->grab = NullGrab;
+    mouse->sync.state = NOT_GRABBED;
+    mouse->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+    if (grab->confineTo)
+	ConfineCursorToWindow(ROOT, FALSE, FALSE);
+    PostNewCursor();
+    if (grab->cursor)
+	FreeCursor(grab->cursor, (Cursor)0);
+    ComputeFreezes();
+
+    #ifdef NXAGENT_SERVER
+
+    if (nxagentOption(Rootless) == 1)
+    {
+      XUngrabPointer(nxagentDisplay, CurrentTime);
+
+      if (sprite.win == ROOT)
+      {
+        mouse -> button -> state &=
+            ~(Button1Mask | Button2Mask | Button3Mask |
+                  Button4Mask | Button5Mask);
+      }
+    }
+
+    #endif
+}
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+    WindowPtr oldWin;
+
+    if (keybd->grab)
+	oldWin = keybd->grab->window;
+    else if (keybd->focus)
+	oldWin = keybd->focus->win;
+    else
+	oldWin = sprite.win;
+    if (oldWin == FollowKeyboardWin)
+	oldWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+    if (syncEvents.playingEvents)
+	keybd->grabTime = syncEvents.time;
+    else
+	keybd->grabTime = time;
+    keybd->activeGrab = *grab;
+    keybd->grab = &keybd->activeGrab;
+    keybd->fromPassiveGrab = passive;
+    CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+    register GrabPtr grab = keybd->grab;
+    register DeviceIntPtr dev;
+    register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+					       : sprite.win;
+
+    if (focusWin == FollowKeyboardWin)
+	focusWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    keybd->grab = NullGrab;
+    keybd->sync.state = NOT_GRABBED;
+    keybd->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+    ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+    Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+    TimeStamp grabTime;
+    register DeviceIntPtr dev;
+
+    thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+    thisSynced = FALSE;
+    otherGrabbed = FALSE;
+    othersFrozen = TRUE;
+    grabTime = thisDev->grabTime;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev == thisDev)
+	    continue;
+	if (dev->grab && SameClient(dev->grab, client))
+	{
+	    if (!(thisGrabbed || otherGrabbed) ||
+		(CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+		grabTime = dev->grabTime;
+	    otherGrabbed = TRUE;
+	    if (thisDev->sync.other == dev->grab)
+		thisSynced = TRUE;
+	    if (dev->sync.state < FROZEN)
+		othersFrozen = FALSE;
+	}
+	else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+	    othersFrozen = FALSE;
+    }
+    if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+	return;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, grabTime) == EARLIER))
+	return;
+    switch (newState)
+    {
+	case THAWED:	 	       /* Async */
+	    if (thisGrabbed)
+		thisDev->sync.state = THAWED;
+	    if (thisSynced)
+		thisDev->sync.other = NullGrab;
+	    ComputeFreezes();
+	    break;
+	case FREEZE_NEXT_EVENT:		/* Sync */
+	    if (thisGrabbed)
+	    {
+		thisDev->sync.state = FREEZE_NEXT_EVENT;
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		ComputeFreezes();
+	    }
+	    break;
+	case THAWED_BOTH:		/* AsyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case FREEZE_BOTH_NEXT_EVENT:	/* SyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case NOT_GRABBED:		/* Replay */
+	    if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+	    {
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		syncEvents.replayDev = thisDev;
+		syncEvents.replayWin = thisDev->grab->window;
+		(*thisDev->DeactivateGrab)(thisDev);
+		syncEvents.replayDev = (DeviceIntPtr)NULL;
+	    }
+	    break;
+	case THAW_OTHERS:		/* AsyncOthers */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev == thisDev)
+			continue;
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+    }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+    TimeStamp		time;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    REQUEST(xAllowEventsReq);
+
+    REQUEST_SIZE_MATCH(xAllowEventsReq);
+    time = ClientTimeToServerTime(stuff->time);
+    switch (stuff->mode)
+    {
+	case ReplayPointer:
+	    AllowSome(client, time, mouse, NOT_GRABBED);
+	    break;
+	case SyncPointer: 
+	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncPointer: 
+	    AllowSome(client, time, mouse, THAWED);
+	    break;
+	case ReplayKeyboard: 
+	    AllowSome(client, time, keybd, NOT_GRABBED);
+	    break;
+	case SyncKeyboard: 
+	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncKeyboard: 
+	    AllowSome(client, time, keybd, THAWED);
+	    break;
+	case SyncBoth:
+	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+	    break;
+	case AsyncBoth:
+	    AllowSome(client, time, keybd, THAWED_BOTH);
+	    break;
+	default: 
+	    client->errorValue = stuff->mode;
+	    return BadValue;
+    }
+
+    /*
+     * This is not necessary if we export grab to X as asynchronous.
+     *
+     * if (nxagentOption(Rootless) && stuff -> mode != ReplayKeyboard &&
+     *         stuff -> mode != SyncKeyboard && stuff -> mode != AsyncKeyboard)
+     * {
+     *   XAllowEvents(nxagentDisplay, stuff -> mode, CurrentTime);
+     * }
+     */
+
+    return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+    register DeviceIntPtr dev;
+    Bool    done;
+
+    /* XXX CloseDownClient should remove passive grabs before
+     * releasing active grabs.
+     */
+    do {
+    	done = TRUE;
+    	for (dev = inputInfo.devices; dev; dev = dev->next)
+    	{
+	    if (dev->grab && SameClient(dev->grab, client))
+	    {
+	    	(*dev->DeactivateGrab)(dev);
+	    	done = FALSE;
+	    }
+    	}
+    } while (!done);
+}
+
+/**************************************************************************
+ *            The following procedures deal with delivering events        *
+ **************************************************************************/
+
+int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask, 
+                 Mask filter, GrabPtr grab)
+{
+    int i;
+    int type;
+
+#ifdef DEBUG
+    if (debug_events) ErrorF(
+	"Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+	((filter == CantBeFiltered) || (mask & filter)))
+    {
+	if (grab && !SameClient(grab, client))
+	    return -1; /* don't send, but notify caller */
+	type = pEvents->u.u.type;
+	if (type == MotionNotify)
+	{
+	    if (mask & PointerMotionHintMask)
+	    {
+		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+		    pEvents->u.keyButtonPointer.event)
+		{
+#ifdef DEBUG
+		    if (debug_events) ErrorF("\n");
+	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+		    return 1; /* don't send, but pretend we did */
+		}
+		pEvents->u.u.detail = NotifyHint;
+	    }
+	    else
+	    {
+		pEvents->u.u.detail = NotifyNormal;
+	    }
+	}
+#ifdef XINPUT
+	else
+	{
+	    if ((type == DeviceMotionNotify) &&
+		MaybeSendDeviceMotionNotifyHint
+			((deviceKeyButtonPointer*)pEvents, mask) != 0)
+		return 1;
+	}
+#endif
+	type &= 0177;
+	if (type != KeymapNotify)
+	{
+	    /* all extension events must have a sequence number */
+	    for (i = 0; i < count; i++)
+		pEvents[i].u.u.sequenceNumber = client->sequence;
+	}
+
+	if (BitIsOn(criticalEvents, type))
+	{
+#ifdef SMART_SCHEDULE
+	    if (client->smart_priority < SMART_MAX_PRIORITY)
+		client->smart_priority++;
+#endif
+	    SetCriticalOutputPending();
+	}
+
+	WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+	if (debug_events) ErrorF(  " delivered\n");
+#endif
+	return 1;
+    }
+    else
+    {
+#ifdef DEBUG
+	if (debug_events) ErrorF("\n");
+#endif
+	return 0;
+    }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count, 
+                      Mask filter, GrabPtr grab, int mskidx)
+{
+    int deliveries = 0, nondeliveries = 0;
+    int attempt;
+    register InputClients *other;
+    ClientPtr client = NullClient;
+    Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+		              this mask is the mask of the grab. */
+    int type = pEvents->u.u.type;
+
+    /* CantBeFiltered means only window owner gets the event */
+    if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+    {
+	/* if nobody ever wants to see this event, skip some work */
+	if (filter != CantBeFiltered &&
+	    !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+	    return 0;
+	if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+				      pWin->eventMask, filter, grab)) )
+	{
+	    if (attempt > 0)
+	    {
+		deliveries++;
+		client = wClient(pWin);
+		deliveryMask = pWin->eventMask;
+	    } else
+		nondeliveries--;
+	}
+    }
+    if (filter != CantBeFiltered)
+    {
+	if (type & EXTENSION_EVENT_BASE)
+	{
+	    OtherInputMasks *inputMasks;
+
+	    inputMasks = wOtherInputMasks(pWin);
+	    if (!inputMasks ||
+		!(inputMasks->inputEvents[mskidx] & filter))
+		return 0;
+	    other = inputMasks->inputClients;
+	}
+	else
+	    other = (InputClients *)wOtherClients(pWin);
+	for (; other; other = other->next)
+	{
+	    if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+					  other->mask[mskidx], filter, grab)) )
+	    {
+		if (attempt > 0)
+		{
+		    deliveries++;
+		    client = rClient(other);
+		    deliveryMask = other->mask[mskidx];
+		} else
+		    nondeliveries--;
+	    }
+	}
+    }
+    if ((type == ButtonPress) && deliveries && (!grab))
+    {
+	GrabRec tempGrab;
+
+	tempGrab.device = inputInfo.pointer;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.window = pWin;
+	tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+	tempGrab.eventMask = deliveryMask;
+	tempGrab.keyboardMode = GrabModeAsync;
+	tempGrab.pointerMode = GrabModeAsync;
+	tempGrab.confineTo = NullWindow;
+	tempGrab.cursor = NullCursor;
+	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+					   currentTime, TRUE);
+    }
+    else if ((type == MotionNotify) && deliveries)
+	inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+    else
+    {
+	if (((type == DeviceMotionNotify)
+#ifdef XKB
+	     || (type == DeviceButtonPress)
+#endif
+	    ) && deliveries)
+	    CheckDeviceGrabAndHintWindow (pWin, type,
+					  (deviceKeyButtonPointer*) pEvents,
+					  grab, client, deliveryMask);
+    }
+#endif
+    if (deliveries)
+	return deliveries;
+    return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0.  if
+   send works,  return 1 or if send didn't work, return 2.
+   Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int 
+XineramaTryClientEventsResult(
+    ClientPtr client,
+    GrabPtr grab,
+    Mask mask, 
+    Mask filter
+){
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+        ((filter == CantBeFiltered) || (mask & filter)))
+    {
+        if (grab && !SameClient(grab, client)) return -1;
+	else return 1;
+    }
+    return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents, 
+                           int count, Mask filter, ClientPtr dontClient)
+{
+    register OtherClients *other;
+
+
+    if (pWin->eventMask & filter)
+    {
+        if (wClient(pWin) == dontClient)
+	    return 0;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	    return XineramaTryClientEventsResult(
+			wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+	return TryClientEvents(wClient(pWin), pEvents, count,
+			       pWin->eventMask, filter, NullGrab);
+    }
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->mask & filter)
+	{
+            if (SameClient(other, dontClient))
+		return 0;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	      return XineramaTryClientEventsResult(
+			rClient(other), NullGrab, other->mask, filter);
+#endif
+	    return TryClientEvents(rClient(other), pEvents, count,
+				   other->mask, filter, NullGrab);
+	}
+    }
+    return 2;
+}
+
+static void
+FixUpEventFromWindow(
+    xEvent *xE,
+    WindowPtr pWin,
+    Window child,
+    Bool calcChild)
+{
+    if (calcChild)
+    {
+        WindowPtr w=spriteTrace[spriteTraceGood-1];
+	/* If the search ends up past the root should the child field be 
+	 	set to none or should the value in the argument be passed 
+		through. It probably doesn't matter since everyone calls 
+		this function with child == None anyway. */
+
+        while (w) 
+        {
+            /* If the source window is same as event window, child should be
+		none.  Don't bother going all all the way back to the root. */
+
+ 	    if (w == pWin)
+	    { 
+   		child = None;
+ 		break;
+	    }
+	    
+	    if (w->parent == pWin)
+	    {
+		child = w->drawable.id;
+		break;
+            }
+ 	    w = w->parent;
+        } 	    
+    }
+    XE_KBPTR.root = ROOT->drawable.id;
+    XE_KBPTR.event = pWin->drawable.id;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	XE_KBPTR.sameScreen = xTrue;
+	XE_KBPTR.child = child;
+	XE_KBPTR.eventX =
+	XE_KBPTR.rootX - pWin->drawable.x;
+	XE_KBPTR.eventY =
+	XE_KBPTR.rootY - pWin->drawable.y;
+    }
+    else
+    {
+	XE_KBPTR.sameScreen = xFalse;
+	XE_KBPTR.child = None;
+	XE_KBPTR.eventX = 0;
+	XE_KBPTR.eventY = 0;
+    }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab, 
+                    register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+    Window child = None;
+    int type = xE->u.u.type;
+    Mask filter = filters[type];
+    int deliveries = 0;
+
+    if (type & EXTENSION_EVENT_BASE)
+    {
+	register OtherInputMasks *inputMasks;
+	int mskidx = dev->id;
+
+	inputMasks = wOtherInputMasks(pWin);
+	if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+	    return 0;
+	while (pWin)
+	{
+	    if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, mskidx);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(inputMasks &&
+		 (filter & inputMasks->dontPropagateMask[mskidx])))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	    if (pWin)
+		inputMasks = wOtherInputMasks(pWin);
+	}
+    }
+    else
+    {
+	if (!(filter & pWin->deliverableEvents))
+	    return 0;
+	while (pWin)
+	{
+	    if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, 0);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(filter & wDontPropagateMask(pWin)))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	}
+    }
+    return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count, 
+              register WindowPtr otherParent)
+{
+    Mask filter;
+    int     deliveries;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+	return count;
+#endif
+
+    if (!count)
+	return 0;
+    filter = filters[xE->u.u.type];
+    if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+	xE->u.destroyNotify.event = pWin->drawable.id;
+    if (filter != StructureAndSubMask)
+	return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+    deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+				       NullGrab, 0);
+    if (pWin->parent)
+    {
+	xE->u.destroyNotify.event = pWin->parent->drawable.id;
+	deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+					    SubstructureNotifyMask, NullGrab,
+					    0);
+	if (xE->u.u.type == ReparentNotify)
+	{
+	    xE->u.destroyNotify.event = otherParent->drawable.id;
+	    deliveries += DeliverEventsToWindow(otherParent, xE, count,
+						SubstructureNotifyMask,
+						NullGrab, 0);
+	}
+    }
+    return deliveries;
+}
+
+
+static Bool 
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+	return TRUE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	   if(POINT_IN_REGION(sprite.screen, 
+			&sprite.windows[i]->borderSize, 
+			x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, 
+			y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, 
+			&box))
+		return TRUE;
+	}
+    }
+#endif
+    return FALSE;
+}
+
+static WindowPtr 
+XYToWindow(int x, int y)
+{
+    register WindowPtr  pWin;
+    BoxRec		box;
+
+    spriteTraceGood = 1;	/* root window still there */
+
+    if (nxagentOption(Rootless))
+    {
+      if (nxagentLastEnteredWindow == NULL)
+      {
+        return ROOT;
+      }
+
+      pWin = ROOT->lastChild;
+
+      while (pWin && pWin != ROOT->firstChild && pWin != nxagentLastEnteredWindow)
+      {
+        pWin = pWin->prevSib;
+      }
+    }
+    else
+    {
+      pWin = ROOT->firstChild;
+    }
+
+    while (pWin)
+    {
+	if ((pWin->mapped) &&
+	    (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+	    (x < pWin->drawable.x + (int)pWin->drawable.width +
+	     wBorderWidth(pWin)) &&
+	    (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+	    (y < pWin->drawable.y + (int)pWin->drawable.height +
+	     wBorderWidth (pWin))
+#ifdef SHAPE
+	    /* When a window is shaped, a further check
+	     * is made to see if the point is inside
+	     * borderSize
+	     */
+	    && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+	    && (!wInputShape(pWin) ||
+		POINT_IN_REGION(pWin->drawable.pScreen,
+				wInputShape(pWin),
+				x - pWin->drawable.x,
+				y - pWin->drawable.y, &box))
+#endif
+	    )
+	{
+	    if (spriteTraceGood >= spriteTraceSize)
+	    {
+		spriteTraceSize += 10;
+		Must_have_memory = TRUE; /* XXX */
+		spriteTrace = (WindowPtr *)xrealloc(
+		    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    spriteTrace[spriteTraceGood++] = pWin;
+	    pWin = pWin->firstChild;
+	}
+	else
+	    pWin = pWin->nextSib;
+    }
+    return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaCheckMotion(xE);
+#endif
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+	{
+	    sprite.hot.pScreen = sprite.hotPhys.pScreen;
+	    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+	}
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+	sprite.hotPhys = sprite.hot;
+
+        /*
+         * This code force cursor position to be inside the
+         * root window of the agent. We can't view a reason
+         * to do this and it interacts in an undesirable way
+         * with toggling fullscreen.
+         *
+         * if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+         *          (sprite.hotPhys.y != XE_KBPTR.rootY))
+         * {
+         *   (*sprite.hotPhys.pScreen->SetCursorPosition)(
+         *       sprite.hotPhys.pScreen,
+         *           sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+         * }
+         */
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+    if (!(sprite.win->deliverableEvents &
+	  Motion_Filter(inputInfo.pointer->button))
+	!syncEvents.playingEvents)
+    {
+	/* XXX Do PointerNonInterestBox here */
+    }
+#endif
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+    (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx.  The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+    ScreenPtr pScreen = win->drawable.pScreen;
+    GrabPtr   grab;
+
+    if (noPanoramiXExtension) return;
+    
+    sprite.hot.x        -= xoff;
+    sprite.hot.y        -= yoff;
+
+    sprite.hotPhys.x    -= xoff;
+    sprite.hotPhys.y    -= yoff;
+
+    sprite.hotLimits.x1 -= xoff; 
+    sprite.hotLimits.y1 -= yoff;
+    sprite.hotLimits.x2 -= xoff;
+    sprite.hotLimits.y2 -= yoff;
+
+    if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
+        REGION_TRANSLATE(sprite.screen, &sprite.Reg1,    xoff, yoff);
+    if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
+        REGION_TRANSLATE(sprite.screen, &sprite.Reg2,    xoff, yoff);
+
+    /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    } else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+    register ScreenPtr pScreen = win->drawable.pScreen;
+    #ifdef VIEWPORT_FRAME
+    extern void nxagentInitViewportFrame(ScreenPtr, WindowPtr);
+    #endif
+    extern int  nxagentShadowInit(ScreenPtr, WindowPtr);
+
+    sprite.hotPhys.pScreen = pScreen;
+    sprite.hotPhys.x = pScreen->width / 2;
+    sprite.hotPhys.y = pScreen->height / 2;
+    sprite.hot = sprite.hotPhys;
+    sprite.hotLimits.x2 = pScreen->width;
+    sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = win;
+    sprite.current = wCursor (win);
+    sprite.current->refcnt++;
+    spriteTraceGood = 1;
+    ROOT = win;
+    (*pScreen->CursorLimits) (
+	pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+    sprite.confined = FALSE;
+    (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+    (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+    (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+	sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+	sprite.hotLimits.x2 = PanoramiXPixWidth  - panoramiXdataPtr[0].x;
+	sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+	sprite.physLimits = sprite.hotLimits;
+	sprite.confineWin = NullWindow;
+#ifdef SHAPE
+        sprite.hotShape = NullRegion;
+#endif
+	sprite.screen = pScreen;
+	/* gotta UNINIT these someplace */
+	REGION_NULL(pScreen, &sprite.Reg1);
+	REGION_NULL(pScreen, &sprite.Reg2);
+    }
+#endif
+
+    #ifdef VIEWPORT_FRAME
+    nxagentInitViewportFrame(pScreen, win);
+    #endif
+
+    if (nxagentOption(Shadow))
+    {
+      if (nxagentShadowInit(pScreen, win) == -1)
+      {
+        FatalError("Failed to connect to display '%s'", nxagentShadowDisplayName);
+      }
+    }
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+    PostNewCursor();
+}
+
+void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+    sprite.hotPhys.x = x;
+    sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - 
+			    panoramiXdataPtr[0].x;
+	sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - 
+			    panoramiXdataPtr[0].y;
+	if (newScreen != sprite.screen) {
+	    sprite.screen = newScreen;
+	    /* Make sure we tell the DDX to update its copy of the screen */
+	    if(sprite.confineWin)
+		XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+	    else
+		XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+	    /* if the pointer wasn't confined, the DDX won't get 
+	       told of the pointer warp so we reposition it here */
+	    if(!syncEvents.playingEvents)
+		(*sprite.screen->SetCursorPosition)(sprite.screen,
+		    sprite.hotPhys.x + panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x,
+		    sprite.hotPhys.y + panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+	}
+    } else 
+#endif
+    if (newScreen != sprite.hotPhys.pScreen)
+	ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+    WindowPtr pWin,
+    int x,
+    int y
+)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    BoxRec box;
+    int i, xoff, yoff;
+
+    if (!pWin->realized) return FALSE;
+
+    if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+        return TRUE;
+    
+    if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+    xoff = x + panoramiXdataPtr[0].x;  
+    yoff = y + panoramiXdataPtr[0].y;  
+
+    for(i = 1; i < PanoramiXNumScreens; i++) {
+	pWin = sprite.windows[i];
+	pScreen = pWin->drawable.pScreen;
+	x = xoff - panoramiXdataPtr[i].x;
+	y = yoff - panoramiXdataPtr[i].y;
+
+	if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+	   && (!wInputShape(pWin) ||
+	       POINT_IN_REGION(pWin->drawable.pScreen,
+			       wInputShape(pWin),
+			       x - pWin->drawable.x, 
+			       y - pWin->drawable.y, &box)))
+            return TRUE;
+
+    }
+
+    return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+
+    REQUEST(xWarpPointerReq);
+
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if(source == WindowTable[0]) {
+	    winX -= panoramiXdataPtr[0].x;
+	    winY -= panoramiXdataPtr[0].y;
+	}
+	if (x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !XineramaPointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	if(dest == WindowTable[0]) {
+	    x -= panoramiXdataPtr[0].x;
+	    y -= panoramiXdataPtr[0].y;
+	}
+    } 
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < sprite.physLimits.x1)
+	x = sprite.physLimits.x1;
+    else if (x >= sprite.physLimits.x2)
+	x = sprite.physLimits.x2 - 1;
+    if (y < sprite.physLimits.y1)
+	y = sprite.physLimits.y1;
+    else if (y >= sprite.physLimits.y2)
+	y = sprite.physLimits.y2 - 1;
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &x, &y);
+
+    XineramaSetCursorPosition(x, y, TRUE);
+
+    return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+    ScreenPtr	newScreen;
+
+    REQUEST(xWarpPointerReq);
+
+    REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaWarpPointer(client);
+#endif
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+	    x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !PointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) 
+    {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	newScreen = dest->drawable.pScreen;
+    } else 
+	newScreen = sprite.hotPhys.pScreen;
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < 0)
+	x = 0;
+    else if (x >= newScreen->width)
+	x = newScreen->width - 1;
+    if (y < 0)
+	y = 0;
+    else if (y >= newScreen->height)
+	y = newScreen->height - 1;
+
+    if (newScreen == sprite.hotPhys.pScreen)
+    {
+	if (x < sprite.physLimits.x1)
+	    x = sprite.physLimits.x1;
+	else if (x >= sprite.physLimits.x2)
+	    x = sprite.physLimits.x2 - 1;
+	if (y < sprite.physLimits.y1)
+	    y = sprite.physLimits.y1;
+	else if (y >= sprite.physLimits.y2)
+	    y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+	(*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+    }
+    else if (!PointerConfinedToScreen())
+    {
+	NewCurrentScreen(newScreen, x, y);
+    }
+    return Success;
+}
+
+static Bool 
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+     if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+	return TRUE;
+
+#ifdef PANORAMIX
+     if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	    if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+		return TRUE;
+	}
+     }
+#endif
+     return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+	passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+    WindowPtr pWin,
+    register DeviceIntPtr device,
+    register xEvent *xE,
+    int count)
+{
+    register GrabPtr grab = wPassiveGrabs(pWin);
+    GrabRec tempGrab;
+    register xEvent *dxE;
+
+    if (!grab)
+	return FALSE;
+    tempGrab.window = pWin;
+    tempGrab.device = device;
+    tempGrab.type = xE->u.u.type;
+    tempGrab.detail.exact = xE->u.u.detail;
+    tempGrab.detail.pMask = NULL;
+    tempGrab.modifiersDetail.pMask = NULL;
+    for (; grab; grab = grab->next)
+    {
+#ifdef XKB
+	DeviceIntPtr	gdev;
+	XkbSrvInfoPtr	xkbi;
+
+	gdev= grab->modifierDevice;
+	xkbi= gdev->key->xkbInfo;
+#endif
+	tempGrab.modifierDevice = grab->modifierDevice;
+	if ((device == grab->modifierDevice) &&
+	    ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+	     || (xE->u.u.type == DeviceKeyPress)
+#endif
+	     ))
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->prev_state;
+#endif
+	else
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->state;
+#endif
+	if (GrabMatchesSecond(&tempGrab, grab) &&
+	    (!grab->confineTo ||
+	     (grab->confineTo->realized && 
+				BorderSizeNotEmpty(grab->confineTo))))
+	{
+#ifdef XCSECURITY
+	    if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+		return FALSE;
+#endif
+#ifdef XKB
+	    if (!noXkbExtension) {
+		XE_KBPTR.state &= 0x1f00;
+		XE_KBPTR.state |=
+				tempGrab.modifiersDetail.exact&(~0x1f00);
+	    }
+#endif
+	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+ 
+	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+	    (void) TryClientEvents(rClient(grab), xE, count,
+				   filters[xE->u.u.type],
+				   filters[xE->u.u.type],  grab);
+
+	    if (device->sync.state == FROZEN_NO_EVENT)
+	    {
+		if (device->sync.evcount < count)
+		{
+		    Must_have_memory = TRUE; /* XXX */
+		    device->sync.event = (xEvent *)xrealloc(device->sync.event,
+							    count*
+							    sizeof(xEvent));
+		    Must_have_memory = FALSE; /* XXX */
+		}
+		device->sync.evcount = count;
+		for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+		    *dxE = *xE;
+	    	device->sync.state = FROZEN_WITH_EVENT;
+            }	
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated.  If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated.  If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated.  If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE, 
+                 int checkFirst, int count)
+{
+    register int i;
+    register WindowPtr pWin = NULL;
+    register FocusClassPtr focus = device->focus;
+
+    if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+	 || (xE->u.u.type == DeviceButtonPress)
+#endif
+	 ) && (device->button->buttonsDown != 1))
+	return FALSE;
+
+    i = checkFirst;
+
+    if (focus)
+    {
+	for (; i < focus->traceGood; i++)
+	{
+	    pWin = focus->trace[i];
+	    if (pWin->optional &&
+		CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+		return TRUE;
+	}
+  
+	if ((focus->win == NoneWin) ||
+	    (i >= spriteTraceGood) ||
+	    ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+	    return FALSE;
+    }
+
+    for (; i < spriteTraceGood; i++)
+    {
+	pWin = spriteTrace[i];
+	if (pWin->optional &&
+	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+    WindowPtr focus = keybd->focus->win;
+    int mskidx = 0;
+
+    if (focus == FollowKeyboardWin)
+	focus = inputInfo.keyboard->focus->win;
+    if (!focus)
+	return;
+    if (focus == PointerRootWin)
+    {
+	DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+	return;
+    }
+    if ((focus == window) || IsParent(focus, window))
+    {
+	if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+	    return;
+    }
+    /* just deliver it to the focus window */
+    FixUpEventFromWindow(xE, focus, None, FALSE);
+    if (xE->u.u.type & EXTENSION_EVENT_BASE)
+	mskidx = keybd->id;
+    (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+				NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev, 
+                    Bool deactivateGrab, int count)
+{
+    register GrabPtr grab = thisDev->grab;
+    int deliveries = 0;
+    register DeviceIntPtr dev;
+    register xEvent *dxE;
+
+    if (grab->ownerEvents)
+    {
+	WindowPtr focus;
+
+	if (thisDev->focus)
+	{
+	    focus = thisDev->focus->win;
+	    if (focus == FollowKeyboardWin)
+		focus = inputInfo.keyboard->focus->win;
+	}
+	else
+	    focus = PointerRootWin;
+	if (focus == PointerRootWin)
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+					     thisDev, count);
+	else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+					     thisDev, count);
+	else if (focus)
+	    deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+					     thisDev, count);
+    }
+    if (!deliveries)
+    {
+	FixUpEventFromWindow(xE, grab->window, None, TRUE);
+	deliveries = TryClientEvents(rClient(grab), xE, count,
+				     (Mask)grab->eventMask,
+				     filters[xE->u.u.type], grab);
+	if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+			   || xE->u.u.type == DeviceMotionNotify
+#endif
+			   ))
+	    thisDev->valuator->motionHintWindow = grab->window;
+    }
+    if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+					  && xE->u.u.type != DeviceMotionNotify
+#endif
+					  ))
+	switch (thisDev->sync.state)
+	{
+	case FREEZE_BOTH_NEXT_EVENT:
+	    for (dev = inputInfo.devices; dev; dev = dev->next)
+	    {
+		if (dev == thisDev)
+		    continue;
+		FreezeThaw(dev, TRUE);
+		if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+		    (CLIENT_BITS(dev->grab->resource) ==
+		     CLIENT_BITS(thisDev->grab->resource)))
+		    dev->sync.state = FROZEN_NO_EVENT;
+		else
+		    dev->sync.other = thisDev->grab;
+	    }
+	    /* fall through */
+	case FREEZE_NEXT_EVENT:
+	    thisDev->sync.state = FROZEN_WITH_EVENT;
+	    FreezeThaw(thisDev, TRUE);
+	    if (thisDev->sync.evcount < count)
+	    {
+		Must_have_memory = TRUE; /* XXX */
+		thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+							 count*sizeof(xEvent));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    thisDev->sync.evcount = count;
+	    for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+		*dxE = *xE;
+	    break;
+	}
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register int    i;
+    register CARD8  modifiers;
+    register CARD16 mask;
+    GrabPtr         grab = keybd->grab;
+    Bool            deactivateGrab = FALSE;
+    register KeyClassPtr keyc = keybd->key;
+#ifdef XEVIE
+    static Window           rootWin = 0;
+
+    if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+          (xevieMask & xevieFilters[xE->u.u.type])) {
+      key = xE->u.u.detail;
+      kptr = &keyc->down[key >> 3];
+      bit = 1 << (key & 7);
+      if((xE->u.u.type == KeyPress &&  (*kptr & bit)) ||
+         (xE->u.u.type == KeyRelease && !(*kptr & bit)))
+      {} else {
+#ifdef XKB
+        if(!noXkbExtension)
+	    xevieKBEventSent = 1;
+#endif
+        if(!xevieKBEventSent)
+        {
+          xeviekb = keybd;
+          if(!rootWin) {
+	      rootWin = GetCurrentRootWindow()->drawable.id;
+          }
+          xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+          xE->u.keyButtonPointer.root = rootWin;
+          xE->u.keyButtonPointer.child = (xeviewin->firstChild) ? xeviewin->firstChild->
+drawable.id:0;
+          xE->u.keyButtonPointer.rootX = xeviehot.x;
+          xE->u.keyButtonPointer.rootY = xeviehot.y;
+          xE->u.keyButtonPointer.state = keyc->state;
+          WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+#ifdef XKB
+          if(noXkbExtension)
+#endif
+            return;
+        } else {
+	    xevieKBEventSent = 0;
+        }
+      }
+    }
+#endif
+
+    if (!syncEvents.playingEvents)
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+#ifdef XEVIE
+    /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+    if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+	 (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+	  && !noXkbExtension
+#endif
+    )))
+#endif
+    XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+    XE_KBPTR.rootX = sprite.hot.x;
+    XE_KBPTR.rootY = sprite.hot.y;
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+    modifiers = keyc->modifierMap[key];
+#if defined(XKB) && defined(XEVIE)
+    if(!noXkbExtension && !xeviegrabState &&
+       xevieFlag && clients[xevieClientIndex] &&
+       (xevieMask & xevieFilters[xE->u.u.type])) {
+	switch(xE->u.u.type) {
+	  case KeyPress: *kptr &= ~bit; break;
+	  case KeyRelease: *kptr |= bit; break;
+	}
+    }
+#endif
+
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    if (*kptr & bit) /* allow ddx to generate multiple downs */
+	    {   
+		if (!modifiers)
+		{
+		    xE->u.u.type = KeyRelease;
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		    xE->u.u.type = KeyPress;
+		    /* release can have side effects, don't fall through */
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		}
+		return;
+	    }
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr |= bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers)
+		{
+		    /* This key affects modifier "i" */
+		    keyc->modifierKeyCount[i]++;
+		    keyc->state |= mask;
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+	    {
+		keybd->activatingKey = key;
+		return;
+	    }
+	    break;
+	case KeyRelease: 
+	    if (!(*kptr & bit)) /* guard against duplicates */
+		return;
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr &= ~bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers) {
+		    /* This key affects modifier "i" */
+		    if (--keyc->modifierKeyCount[i] <= 0) {
+			keyc->state &= ~mask;
+			keyc->modifierKeyCount[i] = 0;
+		    }
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+    if (grab)
+	DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+    else
+	DeliverFocusedEvent(keybd, xE, sprite.win, count);
+    if (deactivateGrab)
+        (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+   this is only used when the pressing of keys does not cause 
+   CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register KeyClassPtr keyc = keybd->key;
+
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("FixKeyState: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    *kptr |= bit;
+	    break;
+	case KeyRelease: 
+	    *kptr &= ~bit;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+    register GrabPtr	grab = mouse->grab;
+    Bool                deactivateGrab = FALSE;
+    register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+    XkbSrvInfoPtr xkbi;
+
+    xkbi = inputInfo.keyboard->key->xkbInfo;
+#endif
+#ifdef XEVIE
+    if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+       (xevieMask & xevieFilters[xE->u.u.type])) {
+      if(xevieEventSent)
+        xevieEventSent = 0;
+      else {
+        xeviemouse = mouse;
+        WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+        return;
+      }
+    }
+#endif
+
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE)
+    XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+			(noXkbExtension ?
+				inputInfo.keyboard->key->state :
+				xkbi->state.grab_mods)
+#else
+			inputInfo.keyboard->key->state
+#endif
+				    ));
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    /* see comment in EnqueueEvents regarding the next three lines */
+	    if (xE->u.u.type == MotionNotify)
+		XE_KBPTR.root =
+		    WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    if (xE->u.u.type != MotionNotify)
+    {
+	register int  key;
+	register BYTE *kptr;
+	int           bit;
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+
+	key = xE->u.u.detail;
+	kptr = &butc->down[key >> 3];
+	bit = 1 << (key & 7);
+	switch (xE->u.u.type)
+	{
+	case ButtonPress: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (!(*kptr & bit))
+		butc->buttonsDown++;
+	    butc->motionMask = ButtonMotionMask;
+	    *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!grab)
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		    return;
+	    break;
+	case ButtonRelease: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (*kptr & bit)
+		--butc->buttonsDown;
+	    if (!butc->buttonsDown)
+		butc->motionMask = 0;
+	    *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!butc->state && mouse->fromPassiveGrab)
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("bogus pointer event from ddx");
+	}
+    }
+    else if (!CheckMotion(xE))
+	return;
+    if (grab)
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    else
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    if (deactivateGrab)
+        (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+	(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+    register WindowPtr pWin;
+{
+    register OtherClients *others;
+    register WindowPtr pChild;
+
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->optional)
+	{
+	    pChild->optional->otherEventMasks = 0;
+	    for (others = wOtherClients(pChild); others; others = others->next)
+	    {
+		pChild->optional->otherEventMasks |= others->mask;
+	    }
+	}
+	pChild->deliverableEvents = pChild->eventMask|
+				    wOtherEventMasks(pChild);
+	if (pChild->parent)
+	    pChild->deliverableEvents |=
+		(pChild->parent->deliverableEvents &
+		 ~wDontPropagateMask(pChild) & PropagateMask);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+/**
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+    register OtherClientsPtr other, prev;
+    register WindowPtr pWin = (WindowPtr)value;
+
+    prev = 0;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->resource == id)
+	{
+	    if (prev)
+		prev->next = other->next;
+	    else
+	    {
+		if (!(pWin->optional->otherClients = other->next))
+		    CheckWindowOptionalNeed (pWin);
+	    }
+	    xfree(other);
+	    RecalculateDeliverableEvents(pWin);
+	    return(Success);
+	}
+	prev = other;
+    }
+    FatalError("client not on event list");
+    /*NOTREACHED*/
+    return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+    Mask check;
+    OtherClients * others;
+
+    if (mask & ~AllEventMasks)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    check = (mask & AtMostOneClient);
+    if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+    {				       /* It is illegal for two different
+				          clients to select on any of the
+				          events for AtMostOneClient. However,
+				          it is OK, for some client to
+				          continue selecting on one of those
+				          events.  */
+	if ((wClient(pWin) != client) && (check & pWin->eventMask))
+	    return BadAccess;
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (!SameClient(others, client) && (check & others->mask))
+		return BadAccess;
+	}
+    }
+    if (wClient (pWin) == client)
+    {
+	check = pWin->eventMask;
+#ifdef SGIMISC
+	pWin->eventMask =
+	    (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+	pWin->eventMask = mask;
+#endif
+    }
+    else
+    {
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (SameClient(others, client))
+	    {
+		check = others->mask;
+#ifdef SGIMISC
+		mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+		if (mask == 0)
+		{
+		    FreeResource(others->resource, RT_NONE);
+		    return Success;
+		}
+		else
+		    others->mask = mask;
+		goto maskSet;
+	    }
+	}
+	check = 0;
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return BadAlloc;
+	others = (OtherClients *) xalloc(sizeof(OtherClients));
+	if (!others)
+	    return BadAlloc;
+	others->mask = mask;
+	others->resource = FakeClientID(client->index);
+	others->next = pWin->optional->otherClients;
+	pWin->optional->otherClients = others;
+	if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+	    return BadAlloc;
+    }
+maskSet: 
+    if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+	(mask & PointerMotionHintMask) &&
+	!(check & PointerMotionHintMask) &&
+	!inputInfo.pointer->grab)
+	inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client, 
+                       Mask mask, Bool *checkOptional)
+{
+    register int i, free;
+
+    if ((mask & ~PropagateMask) && !permitOldBugs)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    if (pWin->dontPropagate)
+	DontPropagateRefCnts[pWin->dontPropagate]--;
+    if (!mask)
+	i = 0;
+    else
+    {
+	for (i = DNPMCOUNT, free = 0; --i > 0; )
+	{
+	    if (!DontPropagateRefCnts[i])
+		free = i;
+	    else if (mask == DontPropagateMasks[i])
+		break;
+	}
+	if (!i && free)
+	{
+	    i = free;
+	    DontPropagateMasks[i] = mask;
+	}
+    }
+    if (i || !mask)
+    {
+	pWin->dontPropagate = i;
+	if (i)
+	    DontPropagateRefCnts[i]++;
+	if (pWin->optional)
+	{
+	    pWin->optional->dontPropagateMask = mask;
+	    *checkOptional = TRUE;
+	}
+    }
+    else
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	{
+	    if (pWin->dontPropagate)
+		DontPropagateRefCnts[pWin->dontPropagate]++;
+	    return BadAlloc;
+	}
+	pWin->dontPropagate = 0;
+        pWin->optional->dontPropagateMask = mask;
+    }
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+static WindowPtr 
+CommonAncestor(
+    register WindowPtr a,
+    register WindowPtr b)
+{
+    for (b = b->parent; b; b = b->parent)
+	if (IsParent(b, a)) return b;
+    return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+    int type,
+    int mode,
+    int detail,
+    register WindowPtr pWin,
+    Window child)
+{
+    xEvent		event;
+    register DeviceIntPtr keybd = inputInfo.keyboard;
+    WindowPtr		focus;
+    register DeviceIntPtr mouse = inputInfo.pointer;
+    register GrabPtr	grab = mouse->grab;
+    Mask		mask;
+
+    if ((pWin == mouse->valuator->motionHintWindow) &&
+	(detail != NotifyInferior))
+	mouse->valuator->motionHintWindow = NullWindow;
+    if (grab)
+    {
+	mask = (pWin == grab->window) ? grab->eventMask : 0;
+	if (grab->ownerEvents)
+	    mask |= EventMaskForClient(pWin, rClient(grab));
+    }
+    else
+    {
+	mask = pWin->eventMask | wOtherEventMasks(pWin);
+    }
+    if (mask & filters[type])
+    {
+	event.u.u.type = type;
+	event.u.u.detail = detail;
+	event.u.enterLeave.time = currentTime.milliseconds;
+	event.u.enterLeave.rootX = sprite.hot.x;
+	event.u.enterLeave.rootY = sprite.hot.y;
+	/* Counts on the same initial structure of crossing & button events! */
+	FixUpEventFromWindow(&event, pWin, None, FALSE);
+	/* Enter/Leave events always set child */
+	event.u.enterLeave.child = child;
+	event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+					    ELFlagSameScreen : 0;
+#ifdef XKB
+	if (!noXkbExtension) {
+	    event.u.enterLeave.state = mouse->button->state & 0x1f00;
+	    event.u.enterLeave.state |= 
+			XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+	} else
+#endif
+	event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+	event.u.enterLeave.mode = mode;
+	focus = keybd->focus->win;
+	if ((focus != NoneWin) &&
+	    ((pWin == focus) || (focus == PointerRootWin) ||
+	     IsParent(focus, pWin)))
+	    event.u.enterLeave.flags |= ELFlagFocus;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), &event, 1, mask,
+				  filters[type], grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+					NullGrab, 0);
+    }
+    if ((type == EnterNotify) && (mask & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+
+#ifdef XCSECURITY
+	ClientPtr client = grab ? rClient(grab)
+				: clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+	ke.type = KeymapNotify;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+				  KeymapStateMask, grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+					KeymapStateMask, NullGrab, 0);
+    }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+    WindowPtr	parent = child->parent;
+
+    if (ancestor == parent)
+	return;
+    EnterNotifies(ancestor, parent, mode, detail);
+    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+    register WindowPtr  pWin;
+
+    if (ancestor == child)
+	return;
+    for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+    {
+	EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+	child = pWin;
+    }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+    if (fromWin == toWin)
+	return;
+    if (IsParent(fromWin, toWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+	EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+    }
+    else if (IsParent(toWin, fromWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+	LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+    }
+    else
+    { /* neither fromWin nor toWin is descendent of the other */
+	WindowPtr common = CommonAncestor(toWin, fromWin);
+	/* common == NullWindow ==> different screens */
+	EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+	LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+	EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+    }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+    xEvent event;
+
+#ifdef XINPUT
+    if (dev != inputInfo.keyboard)
+    {
+	DeviceFocusEvent(dev, type, mode, detail, pWin);
+	return;
+    }
+#endif
+    event.u.focus.mode = mode;
+    event.u.u.type = type;
+    event.u.u.detail = detail;
+    event.u.focus.window = pWin->drawable.id;
+    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+				0);
+    if ((type == FocusIn) &&
+	((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+#ifdef XCSECURITY
+	ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+	ke.type = KeymapNotify;
+	(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+				    KeymapStateMask, NullGrab, 0);
+    }
+}
+
+ /*
+  * recursive because it is easier
+  * no-op if child not descended from ancestor
+  */
+static Bool
+FocusInEvents(
+    DeviceIntPtr dev,
+    WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+    int mode, int detail,
+    Bool doAncestor)
+{
+    if (child == NullWindow)
+	return ancestor == NullWindow;
+    if (ancestor == child)
+    {
+	if (doAncestor)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+		      doAncestor))
+    {
+	if (child != skipChild)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+    DeviceIntPtr dev,
+    WindowPtr child, WindowPtr ancestor,
+    int mode, int detail,
+    Bool doAncestor)
+{
+    register WindowPtr  pWin;
+
+    for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+	FocusEvent(dev, FocusOut, mode, detail, pWin);
+    if (doAncestor)
+	FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+    int     out, in;		       /* for holding details for to/from
+				          PointerRoot/None */
+    int     i;
+
+    if (fromWin == toWin)
+	return;
+    out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+    in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+    if ((toWin == NullWindow) || (toWin == PointerRootWin))
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+   	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+	    /* Notify all the roots */
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	}
+	else
+	{
+	    if (IsParent(fromWin, sprite.win))
+	      FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+			     FALSE);
+	    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+	    /* next call catches the root too, if the screen changed */
+	    FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+			   NotifyNonlinearVirtual, FALSE);
+	}
+	/* Notify all the roots */
+#ifdef PANORAMIX
+	if ( !noPanoramiXExtension )
+	    FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+	else 
+#endif
+	    for (i=0; i<screenInfo.numScreens; i++)
+	        FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+	if (toWin == PointerRootWin)
+	    (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+				NotifyPointer, TRUE);
+    }
+    else
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	    if (toWin->parent != NullWindow)
+	      (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+				  NotifyNonlinearVirtual, TRUE);
+	    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+	    if (IsParent(toWin, sprite.win))
+    	       (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+				   NotifyPointer, FALSE);
+	}
+	else
+	{
+	    if (IsParent(toWin, fromWin))
+	    {
+		FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+		FocusOutEvents(dev, fromWin->parent, toWin, mode,
+			       NotifyVirtual, FALSE);
+		FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+		if ((IsParent(toWin, sprite.win)) &&
+			(sprite.win != fromWin) &&
+			(!IsParent(fromWin, sprite.win)) &&
+			(!IsParent(sprite.win, fromWin)))
+		    (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					mode, NotifyPointer, FALSE);
+	    }
+	    else
+		if (IsParent(fromWin, toWin))
+		{
+		    if ((IsParent(fromWin, sprite.win)) &&
+			    (sprite.win != fromWin) &&
+			    (!IsParent(toWin, sprite.win)) &&
+			    (!IsParent(sprite.win, toWin)))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+		    (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+					NotifyVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+		}
+		else
+		{
+		/* neither fromWin or toWin is child of other */
+		    WindowPtr common = CommonAncestor(toWin, fromWin);
+		/* common == NullWindow ==> different screens */
+		    if (IsParent(fromWin, sprite.win))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+		    if (fromWin->parent != NullWindow)
+		      FocusOutEvents(dev, fromWin->parent, common, mode,
+				     NotifyNonlinearVirtual, FALSE);
+		    if (toWin->parent != NullWindow)
+		      (void)FocusInEvents(dev, common, toWin, toWin, mode,
+					  NotifyNonlinearVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+		    if (IsParent(toWin, sprite.win))
+			(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					    mode, NotifyPointer, FALSE);
+		}
+	}
+    }
+}
+
+int
+SetInputFocus(
+    ClientPtr client,
+    DeviceIntPtr dev,
+    Window focusID,
+    CARD8 revertTo,
+    Time ctime,
+    Bool followOK)
+{
+    register FocusClassPtr focus;
+    register WindowPtr focusWin;
+    int mode;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((revertTo != RevertToParent) &&
+	(revertTo != RevertToPointerRoot) &&
+	(revertTo != RevertToNone) &&
+	((revertTo != RevertToFollowKeyboard) || !followOK))
+    {
+	client->errorValue = revertTo;
+	return BadValue;
+    }
+    time = ClientTimeToServerTime(ctime);
+    if ((focusID == None) || (focusID == PointerRoot))
+	focusWin = (WindowPtr)(long)focusID;
+    else if ((focusID == FollowKeyboard) && followOK)
+	focusWin = inputInfo.keyboard->focus->win;
+    else if (!(focusWin = SecurityLookupWindow(focusID, client,
+					       SecurityReadAccess)))
+	return BadWindow;
+    else
+    {
+ 	/* It is a match error to try to set the input focus to an 
+	unviewable window. */
+
+	if(!focusWin->realized)
+	    return(BadMatch);
+    }
+    focus = dev->focus;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, focus->time) == EARLIER))
+	return Success;
+    mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+    if (focus->win == FollowKeyboardWin)
+	DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+    else
+	DoFocusEvents(dev, focus->win, focusWin, mode);
+    focus->time = time;
+    focus->revert = revertTo;
+    if (focusID == FollowKeyboard)
+	focus->win = FollowKeyboardWin;
+    else
+	focus->win = focusWin;
+    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+	focus->traceGood = 0;
+    else
+    {
+        int depth = 0;
+	register WindowPtr pWin;
+
+        for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+        if (depth > focus->traceSize)
+        {
+	    focus->traceSize = depth+1;
+	    Must_have_memory = TRUE; /* XXX */
+	    focus->trace = (WindowPtr *)xrealloc(focus->trace,
+						 focus->traceSize *
+						 sizeof(WindowPtr));
+	    Must_have_memory = FALSE; /* XXX */
+	}
+	focus->traceGood = depth;
+        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
+	    focus->trace[depth] = pWin;
+    }
+    return Success;
+}
+
+int
+ProcSetInputFocus(client)
+    ClientPtr client;
+{
+    REQUEST(xSetInputFocusReq);
+
+    REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+	return Success;
+#endif
+    return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+			 stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+    xGetInputFocusReply rep;
+    /* REQUEST(xReq); */
+    FocusClassPtr focus = inputInfo.keyboard->focus;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (focus->win == NoneWin)
+	rep.focus = None;
+    else if (focus->win == PointerRootWin)
+	rep.focus = PointerRoot;
+    else rep.focus = focus->win->drawable.id;
+    rep.revertTo = focus->revert;
+    WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+    return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+    xGrabPointerReply rep;
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    WindowPtr pWin, confineTo;
+    CursorPtr cursor, oldCursor;
+    REQUEST(xGrabPointerReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xGrabPointerReq);
+    UpdateCurrentTime();
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+        return BadValue;
+    }
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+	confineTo = NullWindow;
+    else 
+    {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+	/* at this point, some sort of reply is guaranteed. */
+    time = ClientTimeToServerTime(stuff->time);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    grab = device->grab;
+    if ((grab) && !SameClient(grab, client))
+	rep.status = AlreadyGrabbed;
+    else if ((!pWin->realized) ||
+             (confineTo &&
+                !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+	rep.status = GrabNotViewable;
+    else if (device->sync.frozen &&
+	     device->sync.other && !SameClient(device->sync.other, client))
+	rep.status = GrabFrozen;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	rep.status = GrabInvalidTime;
+    else
+    {
+	GrabRec tempGrab;
+
+	oldCursor = NullCursor;
+	if (grab)
+ 	{
+	    if (grab->confineTo && !confineTo)
+		ConfineCursorToWindow(ROOT, FALSE, FALSE);
+	    oldCursor = grab->cursor;
+	}
+	tempGrab.cursor = cursor;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = stuff->ownerEvents;
+	tempGrab.eventMask = stuff->eventMask;
+	tempGrab.confineTo = confineTo;
+	tempGrab.window = pWin;
+	tempGrab.keyboardMode = stuff->keyboardMode;
+	tempGrab.pointerMode = stuff->pointerMode;
+	tempGrab.device = device;
+	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+	if (oldCursor)
+	    FreeCursor (oldCursor, (Cursor)0);
+	rep.status = GrabSuccess;
+    }
+    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+    return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    register GrabPtr grab = device->grab;
+    CursorPtr newCursor, oldCursor;
+    REQUEST(xChangeActivePointerGrabReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    if (stuff->cursor == None)
+	newCursor = NullCursor;
+    else
+    {
+	newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!newCursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+    if (!grab)
+	return Success;
+    if (!SameClient(grab, client))
+	return Success;
+    time = ClientTimeToServerTime(stuff->time);
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	return Success;
+    oldCursor = grab->cursor;
+    grab->cursor = newCursor;
+    if (newCursor)
+	newCursor->refcnt++;
+    PostNewCursor();
+    if (oldCursor)
+	FreeCursor(oldCursor, (Cursor)0);
+    grab->eventMask = stuff->eventMask;
+    return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	    (grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev, 
+           unsigned this_mode, unsigned other_mode, Window grabWindow, 
+           unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+    register WindowPtr pWin;
+    register GrabPtr grab;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+    {
+	client->errorValue = this_mode;
+        return BadValue;
+    }
+    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+    {
+	client->errorValue = other_mode;
+        return BadValue;
+    }
+    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+    {
+	client->errorValue = ownerEvents;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    time = ClientTimeToServerTime(ctime);
+    grab = dev->grab;
+    if (grab && !SameClient(grab, client))
+	*status = AlreadyGrabbed;
+    else if (!pWin->realized)
+	*status = GrabNotViewable;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+	*status = GrabInvalidTime;
+    else if (dev->sync.frozen &&
+	     dev->sync.other && !SameClient(dev->sync.other, client))
+	*status = GrabFrozen;
+    else
+    {
+	GrabRec tempGrab;
+
+	tempGrab.window = pWin;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = ownerEvents;
+	tempGrab.keyboardMode = this_mode;
+	tempGrab.pointerMode = other_mode;
+	tempGrab.eventMask = mask;
+	tempGrab.device = dev;
+	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+	*status = GrabSuccess;
+    }
+    return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+    xGrabKeyboardReply rep;
+    REQUEST(xGrabKeyboardReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+    {
+	result = Success;
+	rep.status = AlreadyGrabbed;
+    }
+    else
+#endif
+    result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+			stuff->pointerMode, stuff->grabWindow,
+			stuff->ownerEvents, stuff->time,
+			KeyPressMask | KeyReleaseMask, &rep.status);
+    if (result != Success)
+	return result;
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+    return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.keyboard;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	(grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+    xQueryPointerReply rep;
+    WindowPtr pWin, t;
+    REQUEST(xResourceReq);
+    DeviceIntPtr mouse = inputInfo.pointer;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (mouse->valuator->motionHintWindow)
+	MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+    rep.length = 0;
+    rep.root = (ROOT)->drawable.id;
+    rep.rootX = sprite.hot.x;
+    rep.rootY = sprite.hot.y;
+    rep.child = None;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	rep.sameScreen = xTrue;
+	rep.winX = sprite.hot.x - pWin->drawable.x;
+	rep.winY = sprite.hot.y - pWin->drawable.y;
+	for (t = sprite.win; t; t = t->parent)
+	    if (t->parent == pWin)
+	    {
+		rep.child = t->drawable.id;
+		break;
+	    }
+    }
+    else
+    {
+	rep.sameScreen = xFalse;
+	rep.winX = 0;
+	rep.winY = 0;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	rep.rootX += panoramiXdataPtr[0].x;
+	rep.rootY += panoramiXdataPtr[0].y;
+	if(stuff->id == rep.root) {
+	    rep.winX += panoramiXdataPtr[0].x;
+	    rep.winY += panoramiXdataPtr[0].y;
+	}
+    }
+#endif
+
+    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+    return(Success);    
+}
+
+void
+InitEvents()
+{
+    int i;
+
+    sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+    inputInfo.numDevices = 0;
+    inputInfo.devices = (DeviceIntPtr)NULL;
+    inputInfo.off_devices = (DeviceIntPtr)NULL;
+    inputInfo.keyboard = (DeviceIntPtr)NULL;
+    inputInfo.pointer = (DeviceIntPtr)NULL;
+    if (spriteTraceSize == 0)
+    {
+	spriteTraceSize = 32;
+	spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+	if (!spriteTrace)
+	    FatalError("failed to allocate spriteTrace");
+    }
+    spriteTraceGood = 0;
+    lastEventMask = OwnerGrabButtonMask;
+    filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = NullWindow;
+    sprite.current = NullCursor;
+    sprite.hotLimits.x1 = 0;
+    sprite.hotLimits.y1 = 0;
+    sprite.hotLimits.x2 = 0;
+    sprite.hotLimits.y2 = 0;
+    sprite.confined = FALSE;
+    syncEvents.replayDev = (DeviceIntPtr)NULL;
+    syncEvents.replayWin = NullWindow;
+    while (syncEvents.pending)
+    {
+	QdEventPtr next = syncEvents.pending->next;
+	xfree(syncEvents.pending);
+	syncEvents.pending = next;
+    }
+    syncEvents.pendtail = &syncEvents.pending;
+    syncEvents.playingEvents = FALSE;
+    syncEvents.time.months = 0;
+    syncEvents.time.milliseconds = 0;	/* hardly matters */
+    currentTime.months = 0;
+    currentTime.milliseconds = GetTimeInMillis();
+    lastDeviceEventTime = currentTime;
+    for (i = 0; i < DNPMCOUNT; i++)
+    {
+	DontPropagateMasks[i] = 0;
+	DontPropagateRefCnts[i] = 0;
+    }
+}
+
+void
+CloseDownEvents(void)
+{
+  xfree(spriteTrace);
+  spriteTrace = NULL;
+  spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+    WindowPtr pWin;
+    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+    REQUEST(xSendEventReq);
+
+    REQUEST_SIZE_MATCH(xSendEventReq);
+
+    /* The client's event type must be a core event type or one defined by an
+	extension. */
+
+
+#ifdef NXAGENT_CLIPBOARD
+
+    if (stuff -> event.u.u.type == SelectionNotify)
+    {
+    	extern int nxagentSendNotify(xEvent*);
+	if (nxagentSendNotify(&stuff->event) == 1)
+	  return Success;
+    }
+#endif
+
+    if ( ! ((stuff->event.u.u.type > X_Reply &&
+	     stuff->event.u.u.type < LASTEvent) || 
+	    (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+	     stuff->event.u.u.type < (unsigned)lastEvent)))
+    {
+	client->errorValue = stuff->event.u.u.type;
+	return BadValue;
+    }
+    if (stuff->event.u.u.type == ClientMessage &&
+	stuff->event.u.u.detail != 8 &&
+	stuff->event.u.u.detail != 16 &&
+	stuff->event.u.u.detail != 32 &&
+	!permitOldBugs)
+    {
+	client->errorValue = stuff->event.u.u.detail;
+	return BadValue;
+    }
+    if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+	return BadValue;
+    }
+
+    if (stuff->destination == PointerWindow)
+	pWin = sprite.win;
+    else if (stuff->destination == InputFocus)
+    {
+	WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+	if (inputFocus == NoneWin)
+	    return Success;
+
+	/* If the input focus is PointerRootWin, send the event to where
+	the pointer is if possible, then perhaps propogate up to root. */
+   	if (inputFocus == PointerRootWin)
+	    inputFocus = ROOT;
+
+	if (IsParent(inputFocus, sprite.win))
+	{
+	    effectiveFocus = inputFocus;
+	    pWin = sprite.win;
+	}
+	else
+	    effectiveFocus = pWin = inputFocus;
+    }
+    else
+	pWin = SecurityLookupWindow(stuff->destination, client,
+				    SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+    {
+	client->errorValue = stuff->propagate;
+	return BadValue;
+    }
+    stuff->event.u.u.type |= 0x80;
+    if (stuff->propagate)
+    {
+	for (;pWin; pWin = pWin->parent)
+	{
+	    if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				      NullGrab, 0))
+		return Success;
+	    if (pWin == effectiveFocus)
+		return Success;
+	    stuff->eventMask &= ~wDontPropagateMask(pWin);
+	    if (!stuff->eventMask)
+		break;
+	}
+    }
+    else
+	(void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				    NullGrab, 0);
+    return Success;
+}
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+    REQUEST(xUngrabKeyReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xUngrabKeyReq);
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = keybd;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = KeyPress;
+    tempGrab.detail.exact = stuff->key;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+    WindowPtr pWin;
+    REQUEST(xGrabKeyReq);
+    GrabPtr grab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xGrabKeyReq);
+    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return(BadValue);
+    }
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    grab = CreateGrab(client->index, keybd, pWin, 
+	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+	keybd, stuff->modifiers, KeyPress, stuff->key, 
+	NullWindow, NullCursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+    WindowPtr pWin, confineTo;
+    REQUEST(xGrabButtonReq);
+    CursorPtr cursor;
+    GrabPtr grab;
+
+    REQUEST_SIZE_MATCH(xGrabButtonReq);
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return BadValue;
+    }
+    if (stuff->eventMask & ~PointerGrabMask)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+       confineTo = NullWindow;
+    else {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+
+
+    grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
+    permitOldBugs ? (Mask)(stuff->eventMask |
+			       ButtonPressMask | ButtonReleaseMask) :
+			(Mask)stuff->eventMask,
+	(Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+	(Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+	ButtonPress, stuff->button, confineTo, cursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+    REQUEST(xUngrabButtonReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+
+    REQUEST_SIZE_MATCH(xUngrabButtonReq);
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = inputInfo.pointer;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = ButtonPress;
+    tempGrab.detail.exact = stuff->button;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+    WindowPtr		parent;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    FocusClassPtr	focus = keybd->focus;
+    OtherClientsPtr	oc;
+    GrabPtr		passive;
+
+
+    /* Deactivate any grabs performed on this window, before making any
+	input focus changes. */
+
+    if (mouse->grab &&
+	((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+	(*mouse->DeactivateGrab)(mouse);
+
+    /* Deactivating a keyboard grab should cause focus events. */
+
+    if (keybd->grab && (keybd->grab->window == pWin))
+	(*keybd->DeactivateGrab)(keybd);
+
+    /* If the focus window is a root window (ie. has no parent) then don't 
+	delete the focus from it. */
+    
+    if ((pWin == focus->win) && (pWin->parent != NullWindow))
+    {
+	int focusEventMode = NotifyNormal;
+
+ 	/* If a grab is in progress, then alter the mode of focus events. */
+
+	if (keybd->grab)
+	    focusEventMode = NotifyWhileGrabbed;
+
+	switch (focus->revert)
+	{
+	case RevertToNone:
+	    DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+	    focus->win = NoneWin;
+	    focus->traceGood = 0;
+	    break;
+	case RevertToParent:
+	    parent = pWin;
+	    do
+	    {
+		parent = parent->parent;
+		focus->traceGood--;
+	    } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+   during SaveSet processing would cause the focus to revert to the
+   nearest enclosing window which will survive the death of the exiting
+   client, instead of ending up reverting to a dying window and thence
+   to None
+ */
+#ifdef NOTDEF
+ 	      || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+		);
+	    DoFocusEvents(keybd, pWin, parent, focusEventMode);
+	    focus->win = parent;
+	    focus->revert = RevertToNone;
+	    break;
+	case RevertToPointerRoot:
+	    DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+	    focus->win = PointerRootWin;
+	    focus->traceGood = 0;
+	    break;
+	}
+    }
+
+    if (mouse->valuator->motionHintWindow == pWin)
+	mouse->valuator->motionHintWindow = NullWindow;
+
+    if (freeResources)
+    {
+	if (pWin->dontPropagate)
+	    DontPropagateRefCnts[pWin->dontPropagate]--;
+	while ( (oc = wOtherClients(pWin)) )
+	    FreeResource(oc->resource, RT_NONE);
+	while ( (passive = wPassiveGrabs(pWin)) )
+	    FreeResource(passive->resource, RT_NONE);
+     }
+#ifdef XINPUT
+    DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry 
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+    GrabPtr grab = inputInfo.pointer->grab;
+    WindowPtr confineTo;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+    if (grab && (confineTo = grab->confineTo))
+    {
+	if (!BorderSizeNotEmpty(confineTo))
+	    (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+	else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+	    ConfineCursorToWindow(confineTo, TRUE, TRUE);
+    }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+    register OtherClientsPtr	other;
+
+    if (wClient (pWin) == client)
+	return pWin->eventMask;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (SameClient(other, client))
+	    return other->mask;
+    }
+    return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+    CursorPtr pCursor;
+    int		nscr;
+    ScreenPtr	pscr;
+    Bool 	displayed;
+    REQUEST(xRecolorCursorReq);
+
+    REQUEST_SIZE_MATCH(xRecolorCursorReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+					RT_CURSOR, SecurityWriteAccess);
+    if ( !pCursor) 
+    {
+	client->errorValue = stuff->cursor;
+	return (BadCursor);
+    }
+
+    pCursor->foreRed = stuff->foreRed;
+    pCursor->foreGreen = stuff->foreGreen;
+    pCursor->foreBlue = stuff->foreBlue;
+
+    pCursor->backRed = stuff->backRed;
+    pCursor->backGreen = stuff->backGreen;
+    pCursor->backBlue = stuff->backBlue;
+
+    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+    {
+	pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension)
+	    displayed = (pscr == sprite.screen);
+	else
+#endif
+	    displayed = (pscr == sprite.hotPhys.pScreen);
+	( *pscr->RecolorCursor)(pscr, pCursor,
+				(pCursor == sprite.current) && displayed);
+    }
+    return (Success);
+}
+
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+    xEvent    eventCopy;
+#endif
+    xEvent    eventTo, *eventFrom;
+    int       i;
+
+#ifdef XKB
+    if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+	return;
+#endif
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && 
+       (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 
+    {
+	switch(events->u.u.type) {
+	case MotionNotify:
+	case ButtonPress:
+	case ButtonRelease:
+	case KeyPress:
+	case KeyRelease:
+	case EnterNotify:
+	case LeaveNotify:
+	/* 
+	   When multiple clients want the same event DeliverEventsToWindow
+	   passes the same event structure multiple times so we can't 
+	   modify the one passed to us 
+        */
+	    count = 1;  /* should always be 1 */
+	    memcpy(&eventCopy, events, sizeof(xEvent));
+	    eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+	    eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+	    if(eventCopy.u.keyButtonPointer.event == 
+	       eventCopy.u.keyButtonPointer.root) 
+	    {
+		eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+		eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+	    }
+	    events = &eventCopy;
+	    break;
+	default: break;
+	}
+    }
+#endif
+
+    if (EventCallback)
+    {
+	EventInfoRec eventinfo;
+	eventinfo.client = pClient;
+	eventinfo.events = events;
+	eventinfo.count = count;
+	CallCallbacks(&EventCallback, (pointer)&eventinfo);
+    }
+    if(pClient->swapped)
+    {
+	for(i = 0; i < count; i++)
+	{
+	    eventFrom = &events[i];
+	    /* Remember to strip off the leading bit of type in case
+	       this event was sent with "SendEvent." */
+	    (*EventSwapVector[eventFrom->u.u.type & 0177])
+		(eventFrom, &eventTo);
+	    (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+	}
+    }
+    else
+    {
+	(void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original
new file mode 100644
index 000000000..4373673f9
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.X.original
@@ -0,0 +1,4670 @@
+/* $XdotOrg: xc/programs/Xserver/dix/events.c,v 1.17 2005/08/25 22:11:04 anholt Exp $ */
+/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.51 2004/01/12 17:04:52 tsi Exp $ */
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/*****************************************************************
+
+Copyright 2003-2005 Sun Microsystems, Inc.
+
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+******************************************************************/
+
+/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBsrv.h>
+extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
+#endif
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#ifdef XEVIE
+extern WindowPtr *WindowTable;
+extern int       xevieFlag;
+extern int       xevieClientIndex;
+extern DeviceIntPtr     xeviemouse;
+extern DeviceIntPtr     xeviekb;
+extern Mask      xevieMask;
+extern Mask      xevieFilters[128];
+extern int       xevieEventSent;
+extern int       xevieKBEventSent;
+int    xeviegrabState = 0;
+xEvent *xeviexE;
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "dispatch.h"
+
+#define EXTENSION_EVENT_BASE  64
+
+#define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+	Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+	PointerMotionMask | Button1MotionMask | \
+	Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+	Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+	KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+	MotionMask )
+#define PointerGrabMask ( \
+	ButtonPressMask | ButtonReleaseMask | \
+	EnterWindowMask | LeaveWindowMask | \
+	PointerMotionHintMask | KeymapStateMask | \
+	MotionMask )
+#define AllModifiersMask ( \
+	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+	Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllEventMasks (lastEventMask|(lastEventMask-1))
+/*
+ * The following relies on the fact that the Button<n>MotionMasks are equal
+ * to the corresponding Button<n>Masks from the current modifier/button state.
+ */
+#define Motion_Filter(class) (PointerMotionMask | \
+			      (class)->state | (class)->motionMask)
+
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+#ifdef DEBUG
+static debug_events = 0;
+#endif
+InputInfo inputInfo;
+
+static struct {
+    QdEventPtr		pending, *pendtail;
+    DeviceIntPtr	replayDev;	/* kludgy rock to put flag for */
+    WindowPtr		replayWin;	/*   ComputeFreezes            */
+    Bool		playingEvents;
+    TimeStamp		time;
+} syncEvents;
+
+/*
+ * The window trace information is used to avoid having to compute all the
+ * windows between the root and the current pointer window each time a button
+ * or key goes down. The grabs on each of those windows must be checked.
+ */
+static WindowPtr *spriteTrace = (WindowPtr *)NULL;
+#define ROOT spriteTrace[0]
+static int spriteTraceSize = 0;
+static int spriteTraceGood;
+
+static  struct {
+    CursorPtr	current;
+    BoxRec	hotLimits;	/* logical constraints of hot spot */
+    Bool	confined;	/* confined to screen */
+#if defined(SHAPE) || defined(PANORAMIX)
+    RegionPtr	hotShape;	/* additional logical shape constraint */
+#endif
+    BoxRec	physLimits;	/* physical constraints of hot spot */
+    WindowPtr	win;		/* window of logical position */
+    HotSpot	hot;		/* logical pointer position */
+    HotSpot	hotPhys;	/* physical pointer position */
+#ifdef PANORAMIX
+    ScreenPtr	screen;		/* all others are in Screen 0 coordinates */
+    RegionRec   Reg1;	        /* Region 1 for confining motion */
+    RegionRec   Reg2;		/* Region 2 for confining virtual motion */
+    WindowPtr   windows[MAXSCREENS];
+    WindowPtr	confineWin;	/* confine window */ 
+#endif
+} sprite;			/* info about the cursor sprite */
+
+#ifdef XEVIE
+WindowPtr xeviewin;
+HotSpot xeviehot;
+#endif
+
+static void DoEnterLeaveEvents(
+    WindowPtr fromWin,
+    WindowPtr toWin,
+    int mode
+);
+
+static WindowPtr XYToWindow(
+    int x,
+    int y
+);
+
+extern int lastEvent;
+
+static Mask lastEventMask;
+
+#ifdef XINPUT
+extern int DeviceMotionNotify;
+#endif
+
+#define CantBeFiltered NoEventMask
+static Mask filters[128] =
+{
+	NoSuchEvent,		       /* 0 */
+	NoSuchEvent,		       /* 1 */
+	KeyPressMask,		       /* KeyPress */
+	KeyReleaseMask,		       /* KeyRelease */
+	ButtonPressMask,	       /* ButtonPress */
+	ButtonReleaseMask,	       /* ButtonRelease */
+	PointerMotionMask,	       /* MotionNotify (initial state) */
+	EnterWindowMask,	       /* EnterNotify */
+	LeaveWindowMask,	       /* LeaveNotify */
+	FocusChangeMask,	       /* FocusIn */
+	FocusChangeMask,	       /* FocusOut */
+	KeymapStateMask,	       /* KeymapNotify */
+	ExposureMask,		       /* Expose */
+	CantBeFiltered,		       /* GraphicsExpose */
+	CantBeFiltered,		       /* NoExpose */
+	VisibilityChangeMask,	       /* VisibilityNotify */
+	SubstructureNotifyMask,	       /* CreateNotify */
+	StructureAndSubMask,	       /* DestroyNotify */
+	StructureAndSubMask,	       /* UnmapNotify */
+	StructureAndSubMask,	       /* MapNotify */
+	SubstructureRedirectMask,      /* MapRequest */
+	StructureAndSubMask,	       /* ReparentNotify */
+	StructureAndSubMask,	       /* ConfigureNotify */
+	SubstructureRedirectMask,      /* ConfigureRequest */
+	StructureAndSubMask,	       /* GravityNotify */
+	ResizeRedirectMask,	       /* ResizeRequest */
+	StructureAndSubMask,	       /* CirculateNotify */
+	SubstructureRedirectMask,      /* CirculateRequest */
+	PropertyChangeMask,	       /* PropertyNotify */
+	CantBeFiltered,		       /* SelectionClear */
+	CantBeFiltered,		       /* SelectionRequest */
+	CantBeFiltered,		       /* SelectionNotify */
+	ColormapChangeMask,	       /* ColormapNotify */
+	CantBeFiltered,		       /* ClientMessage */
+	CantBeFiltered		       /* MappingNotify */
+};
+
+static CARD8 criticalEvents[32] =
+{
+    0x7c				/* key and button events */
+};
+
+#ifdef PANORAMIX
+
+static void ConfineToShape(RegionPtr shape, int *px, int *py);
+static void SyntheticMotion(int x, int y);
+static void PostNewCursor(void);
+
+static Bool
+XineramaSetCursorPosition(
+    int x, 
+    int y, 
+    Bool generateEvent
+){
+    ScreenPtr pScreen;
+    BoxRec box;
+    int i;
+
+    /* x,y are in Screen 0 coordinates.  We need to decide what Screen
+       to send the message too and what the coordinates relative to 
+       that screen are. */
+
+    pScreen = sprite.screen;
+    x += panoramiXdataPtr[0].x;
+    y += panoramiXdataPtr[0].y;
+
+    if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+								x, y, &box)) 
+    {
+	FOR_NSCREENS(i) 
+	{
+	    if(i == pScreen->myNum) 
+		continue;
+	    if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+	    {
+		pScreen = screenInfo.screens[i];
+		break;
+	    }
+	}
+    }
+
+    sprite.screen = pScreen;
+    sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
+    sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
+    x -= panoramiXdataPtr[pScreen->myNum].x;
+    y -= panoramiXdataPtr[pScreen->myNum].y;
+
+    return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(void)
+{
+    ScreenPtr pScreen = sprite.screen;
+    BoxRec newBox = sprite.physLimits;
+
+    /* Translate the constraining box to the screen
+       the sprite is actually on */
+    newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+    newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+    newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+    (* pScreen->ConstrainCursor)(pScreen, &newBox);
+}
+
+static void
+XineramaCheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents
+){
+    HotSpot new;
+
+    if (!cursor)
+	return;
+ 
+    new = sprite.hotPhys;
+
+    /* I don't care what the DDX has to say about it */
+    sprite.physLimits = sprite.hotLimits;
+
+    /* constrain the pointer to those limits */
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+
+    if (sprite.hotShape)  /* more work if the shape is a mess */
+	ConfineToShape(sprite.hotShape, &new.x, &new.y);
+
+    if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	XineramaSetCursorPosition (new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+
+    /* Tell DDX what the limits are */
+    XineramaConstrainCursor();
+}
+
+
+static Bool
+XineramaSetWindowPntrs(WindowPtr pWin)
+{
+    if(pWin == WindowTable[0]) {
+	    memcpy(sprite.windows, WindowTable, 
+				PanoramiXNumScreens*sizeof(WindowPtr));
+    } else {
+	PanoramiXRes *win;
+	int i;
+
+	win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
+
+	if(!win)
+	    return FALSE;
+
+	for(i = 0; i < PanoramiXNumScreens; i++) {
+	   sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
+	   if(!sprite.windows[i])  /* window is being unmapped */
+		return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+static void
+XineramaCheckVirtualMotion(
+   QdEventPtr qe,
+   WindowPtr pWin
+){
+
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;  /* should always be Screen 0 */
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	int x, y, off_x, off_y, i;
+	BoxRec lims;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
+
+        if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+            sprite.hot.x = lims.x1;
+        else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+            sprite.hot.x = lims.x2 - 1;
+        if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+            sprite.hot.y = lims.y1;
+        else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+            sprite.hot.y = lims.y2 - 1;
+
+	if (REGION_NUM_RECTS(&sprite.Reg2) > 1) 
+	    ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
+
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+}
+
+
+static Bool
+XineramaCheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	/* Motion events entering DIX get translated to Screen 0
+	   coordinates.  Replayed events have already been 
+	   translated since they've entered DIX before */
+	XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			  panoramiXdataPtr[0].x;
+	XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			  panoramiXdataPtr[0].y;
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+
+	if (sprite.hotShape) 
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    XineramaSetCursorPosition(
+			sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+
+static void
+XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
+{
+
+    if (syncEvents.playingEvents)
+    {
+	XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	int x, y, off_x, off_y, i;
+
+	if(!XineramaSetWindowPntrs(pWin))
+	    return;
+
+	i = PanoramiXNumScreens - 1;
+	
+	REGION_COPY(sprite.screen, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize); 
+	off_x = panoramiXdataPtr[i].x;
+	off_y = panoramiXdataPtr[i].y;
+
+	while(i--) {
+	    x = off_x - panoramiXdataPtr[i].x;
+	    y = off_y - panoramiXdataPtr[i].y;
+
+	    if(x || y)
+		REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
+		
+	    REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, 
+					&sprite.windows[i]->borderSize);
+
+	    off_x = panoramiXdataPtr[i].x;
+	    off_y = panoramiXdataPtr[i].y;
+	}
+
+	sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
+
+	if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
+	   sprite.hotShape = &sprite.Reg1;
+	else
+	   sprite.hotShape = NullRegion;
+	
+	sprite.confined = FALSE;
+	sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+	XineramaCheckPhysLimits(sprite.current, generateEvents);
+    }
+}
+
+
+static void
+XineramaChangeToCursor(CursorPtr cursor)
+{
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    XineramaCheckPhysLimits(cursor, FALSE);
+    	(*sprite.screen->DisplayCursor)(sprite.screen, cursor);
+	FreeCursor(sprite.current, (Cursor)0);
+	sprite.current = cursor;
+	sprite.current->refcnt++;
+    }
+}
+
+
+#endif  /* PANORAMIX */
+
+void
+SetMaskForEvent(Mask mask, int event)
+{
+    if ((event < LASTEvent) || (event >= 128))
+	FatalError("SetMaskForEvent: bogus event number");
+    filters[event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+    if (event >= 128)
+	FatalError("SetCriticalEvent: bogus event number");
+    criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+static void
+SyntheticMotion(int x, int y)
+{
+    xEvent xE;
+
+#ifdef PANORAMIX
+    /* Translate back to the sprite screen since processInputProc
+       will translate from sprite screen to screen 0 upon reentry
+       to the DIX layer */
+    if(!noPanoramiXExtension) {
+	x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
+	y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
+    }
+#endif
+    xE.u.keyButtonPointer.rootX = x;
+    xE.u.keyButtonPointer.rootY = y;
+    if (syncEvents.playingEvents)
+	xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
+    else
+	xE.u.keyButtonPointer.time = currentTime.milliseconds;
+    xE.u.u.type = MotionNotify;
+    (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
+}
+
+#ifdef SHAPE
+static void
+ConfineToShape(RegionPtr shape, int *px, int *py)
+{
+    BoxRec box;
+    int x = *px, y = *py;
+    int incx = 1, incy = 1;
+
+    if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
+	return;
+    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
+    /* this is rather crude */
+    do {
+	x += incx;
+	if (x >= box.x2)
+	{
+	    incx = -1;
+	    x = *px - 1;
+	}
+	else if (x < box.x1)
+	{
+	    incx = 1;
+	    x = *px;
+	    y += incy;
+	    if (y >= box.y2)
+	    {
+		incy = -1;
+		y = *py - 1;
+	    }
+	    else if (y < box.y1)
+		return; /* should never get here! */
+	}
+    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
+    *px = x;
+    *py = y;
+}
+#endif
+
+static void
+CheckPhysLimits(
+    CursorPtr cursor,
+    Bool generateEvents,
+    Bool confineToScreen,
+    ScreenPtr pScreen)
+{
+    HotSpot new;
+
+    if (!cursor)
+	return;
+    new = sprite.hotPhys;
+    if (pScreen)
+	new.pScreen = pScreen;
+    else
+	pScreen = new.pScreen;
+    (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
+			      &sprite.physLimits);
+    sprite.confined = confineToScreen;
+    (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
+    if (new.x < sprite.physLimits.x1)
+	new.x = sprite.physLimits.x1;
+    else
+	if (new.x >= sprite.physLimits.x2)
+	    new.x = sprite.physLimits.x2 - 1;
+    if (new.y < sprite.physLimits.y1)
+	new.y = sprite.physLimits.y1;
+    else
+	if (new.y >= sprite.physLimits.y2)
+	    new.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &new.x, &new.y); 
+#endif
+    if ((pScreen != sprite.hotPhys.pScreen) ||
+	(new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
+    {
+	if (pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys = new;
+	(*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
+	if (!generateEvents)
+	    SyntheticMotion(new.x, new.y);
+    }
+}
+
+static void
+CheckVirtualMotion(
+    register QdEventPtr qe,
+    register WindowPtr pWin)
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaCheckVirtualMotion(qe, pWin);
+	return;
+    }
+#endif
+    if (qe)
+    {
+	sprite.hot.pScreen = qe->pScreen;
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
+	pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
+					 NullWindow;
+    }
+    if (pWin)
+    {
+	BoxRec lims;
+
+	if (sprite.hot.pScreen != pWin->drawable.pScreen)
+	{
+	    sprite.hot.pScreen = pWin->drawable.pScreen;
+#ifdef XEVIE
+	    xeviehot.x = xeviehot.y = 0;
+#endif
+	    sprite.hot.x = sprite.hot.y = 0;
+	}
+	lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+	if (sprite.hot.x < lims.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = lims.x1;
+	else if (sprite.hot.x >= lims.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = lims.x2 - 1;
+	if (sprite.hot.y < lims.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = lims.y1;
+	else if (sprite.hot.y >= lims.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = lims.y2 - 1;
+#ifdef SHAPE
+	if (wBoundingShape(pWin))
+	    ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
+#endif
+	if (qe)
+	{
+	    qe->pScreen = sprite.hot.pScreen;
+	    qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
+	    qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
+	}
+    }
+    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaConfineCursorToWindow(pWin, generateEvents);
+	return;
+    }	
+#endif
+
+    if (syncEvents.playingEvents)
+    {
+	CheckVirtualMotion((QdEventPtr)NULL, pWin);
+	SyntheticMotion(sprite.hot.x, sprite.hot.y);
+    }
+    else
+    {
+	sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+#ifdef SHAPE
+	sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+					       : NullRegion;
+#endif
+	CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
+			pScreen);
+    }
+}
+
+Bool
+PointerConfinedToScreen()
+{
+    return sprite.confined;
+}
+
+static void
+ChangeToCursor(CursorPtr cursor)
+{
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	XineramaChangeToCursor(cursor);
+	return;
+    }
+#endif
+
+    if (cursor != sprite.current)
+    {
+	if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
+		(sprite.current->bits->yhot != cursor->bits->yhot))
+	    CheckPhysLimits(cursor, FALSE, sprite.confined,
+			    (ScreenPtr)NULL);
+	(*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
+						  cursor);
+	FreeCursor(sprite.current, (Cursor)0);
+	sprite.current = cursor;
+	sprite.current->refcnt++;
+    }
+}
+
+/* returns true if b is a descendent of a */
+Bool
+IsParent(register WindowPtr a, register WindowPtr b)
+{
+    for (b = b->parent; b; b = b->parent)
+	if (b == a) return TRUE;
+    return FALSE;
+}
+
+static void
+PostNewCursor(void)
+{
+    register    WindowPtr win;
+    register    GrabPtr grab = inputInfo.pointer->grab;
+
+    if (syncEvents.playingEvents)
+	return;
+    if (grab)
+    {
+	if (grab->cursor)
+	{
+	    ChangeToCursor(grab->cursor);
+	    return;
+	}
+	if (IsParent(grab->window, sprite.win))
+	    win = sprite.win;
+	else
+	    win = grab->window;
+    }
+    else
+	win = sprite.win;
+    for (; win; win = win->parent)
+	if (win->optional && win->optional->cursor != NullCursor)
+	{
+	    ChangeToCursor(win->optional->cursor);
+	    return;
+	}
+}
+
+WindowPtr
+GetCurrentRootWindow()
+{
+    return ROOT;
+}
+
+WindowPtr
+GetSpriteWindow()
+{
+    return sprite.win;
+}
+
+CursorPtr
+GetSpriteCursor()
+{
+    return sprite.current;
+}
+
+void
+GetSpritePosition(int *px, int *py)
+{
+    *px = sprite.hotPhys.x;
+    *py = sprite.hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen()
+{
+    if(!noPanoramiXExtension) {
+	return sprite.screen->myNum;
+    } else {
+	return 0;
+    }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(register xEvent *xE)
+{
+    /* If the ddx/OS is careless about not processing timestamped events from
+     * different sources in sorted order, then it's possible for time to go
+     * backwards when it should not.  Here we ensure a decent time.
+     */
+    if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
+	currentTime.months++;
+    else
+	XE_KBPTR.time = currentTime.milliseconds;
+}
+
+#define NoticeTime(xE) { \
+    if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
+	MonthChangedOrBadTime(xE); \
+    currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
+    lastDeviceEventTime = currentTime; }
+
+void
+NoticeEventTime(register xEvent *xE)
+{
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE);
+}
+
+/**************************************************************************
+ *            The following procedures deal with synchronous events       *
+ **************************************************************************/
+
+void
+EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+{
+    register QdEventPtr tail = *syncEvents.pendtail;
+    register QdEventPtr qe;
+    xEvent		*qxE;
+
+    NoticeTime(xE);
+
+#ifdef XKB
+    /* Fix for key repeating bug. */
+    if (device->key != NULL && device->key->xkbInfo != NULL && 
+	xE->u.u.type == KeyRelease)
+	AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+#endif
+
+    if (DeviceEventCallback)
+    {
+	DeviceEventInfoRec eventinfo;
+	/*  The RECORD spec says that the root window field of motion events
+	 *  must be valid.  At this point, it hasn't been filled in yet, so
+	 *  we do it here.  The long expression below is necessary to get
+	 *  the current root window; the apparently reasonable alternative
+	 *  GetCurrentRootWindow()->drawable.id doesn't give you the right
+	 *  answer on the first motion event after a screen change because
+	 *  the data that GetCurrentRootWindow relies on hasn't been
+	 *  updated yet.
+	 */
+	if (xE->u.u.type == MotionNotify)
+	    XE_KBPTR.root =
+		WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	eventinfo.events = xE;
+	eventinfo.count = count;
+	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+    }
+    if (xE->u.u.type == MotionNotify)
+    {
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension) {
+	    XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
+			      panoramiXdataPtr[0].x;
+	    XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
+			      panoramiXdataPtr[0].y;
+	}
+#endif
+	sprite.hotPhys.x = XE_KBPTR.rootX;
+	sprite.hotPhys.y = XE_KBPTR.rootY;
+	/* do motion compression */
+	if (tail &&
+	    (tail->event->u.u.type == MotionNotify) &&
+	    (tail->pScreen == sprite.hotPhys.pScreen))
+	{
+	    tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
+	    tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
+	    tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+	    tail->months = currentTime.months;
+	    return;
+	}
+    }
+    qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
+    if (!qe)
+	return;
+    qe->next = (QdEventPtr)NULL;
+    qe->device = device;
+    qe->pScreen = sprite.hotPhys.pScreen;
+    qe->months = currentTime.months;
+    qe->event = (xEvent *)(qe + 1);
+    qe->evcount = count;
+    for (qxE = qe->event; --count >= 0; qxE++, xE++)
+	*qxE = *xE;
+    if (tail)
+	syncEvents.pendtail = &tail->next;
+    *syncEvents.pendtail = qe;
+}
+
+static void
+PlayReleasedEvents(void)
+{
+    register QdEventPtr *prev, qe;
+    register DeviceIntPtr dev;
+
+    prev = &syncEvents.pending;
+    while ( (qe = *prev) )
+    {
+	if (!qe->device->sync.frozen)
+	{
+	    *prev = qe->next;
+	    if (*syncEvents.pendtail == *prev)
+		syncEvents.pendtail = prev;
+	    if (qe->event->u.u.type == MotionNotify)
+		CheckVirtualMotion(qe, NullWindow);
+	    syncEvents.time.months = qe->months;
+	    syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
+#ifdef PANORAMIX
+	   /* Translate back to the sprite screen since processInputProc
+	      will translate from sprite screen to screen 0 upon reentry
+	      to the DIX layer */
+	    if(!noPanoramiXExtension) {
+		qe->event->u.keyButtonPointer.rootX += 
+			panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x;
+		qe->event->u.keyButtonPointer.rootY += 
+			panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y;
+	    }
+#endif
+	    (*qe->device->public.processInputProc)(qe->event, qe->device,
+						   qe->evcount);
+	    xfree(qe);
+	    for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
+		;
+	    if (!dev)
+		break;
+	    /* Playing the event may have unfrozen another device. */
+	    /* So to play it safe, restart at the head of the queue */
+	    prev = &syncEvents.pending;
+	}
+	else
+	    prev = &qe->next;
+    } 
+}
+
+static void
+FreezeThaw(register DeviceIntPtr dev, Bool frozen)
+{
+    dev->sync.frozen = frozen;
+    if (frozen)
+	dev->public.processInputProc = dev->public.enqueueInputProc;
+    else
+	dev->public.processInputProc = dev->public.realInputProc;
+}
+
+void
+ComputeFreezes()
+{
+    register DeviceIntPtr replayDev = syncEvents.replayDev;
+    register int i;
+    WindowPtr w;
+    register xEvent *xE;
+    int count;
+    GrabPtr grab;
+    register DeviceIntPtr dev;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+	FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
+    if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+	return;
+    syncEvents.playingEvents = TRUE;
+    if (replayDev)
+    {
+	xE = replayDev->sync.event;
+	count = replayDev->sync.evcount;
+	syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
+	for (i = 0; i < spriteTraceGood; i++)
+	{
+	    if (syncEvents.replayWin == spriteTrace[i])
+	    {
+		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
+		    if (replayDev->focus)
+			DeliverFocusedEvent(replayDev, xE, w, count);
+		    else
+			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
+					        replayDev, count);
+		}
+		goto playmore;
+	    }
+	}
+	/* must not still be in the same stack */
+	if (replayDev->focus)
+	    DeliverFocusedEvent(replayDev, xE, w, count);
+	else
+	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+    }
+playmore:
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (!dev->sync.frozen)
+	{
+	    PlayReleasedEvents();
+	    break;
+	}
+    }
+    syncEvents.playingEvents = FALSE;
+    /* the following may have been skipped during replay, so do it now */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+    PostNewCursor();
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+    GrabPtr grab;
+
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    }
+    else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+CheckGrabForSyncs(register DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+    register GrabPtr grab = thisDev->grab;
+    register DeviceIntPtr dev;
+
+    if (thisMode == GrabModeSync)
+	thisDev->sync.state = FROZEN_NO_EVENT;
+    else
+    {	/* free both if same client owns both */
+	thisDev->sync.state = THAWED;
+	if (thisDev->sync.other &&
+	    (CLIENT_BITS(thisDev->sync.other->resource) ==
+	     CLIENT_BITS(grab->resource)))
+	    thisDev->sync.other = NullGrab;
+    }
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev != thisDev)
+	{
+	    if (otherMode == GrabModeSync)
+		dev->sync.other = grab;
+	    else
+	    {	/* free both if same client owns both */
+		if (dev->sync.other &&
+		    (CLIENT_BITS(dev->sync.other->resource) ==
+		     CLIENT_BITS(grab->resource)))
+		    dev->sync.other = NullGrab;
+	    }
+	}
+    }
+    ComputeFreezes();
+}
+
+void
+ActivatePointerGrab(register DeviceIntPtr mouse, register GrabPtr grab, 
+                    TimeStamp time, Bool autoGrab)
+{
+    WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
+				     : sprite.win;
+
+    if (grab->confineTo)
+    {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
+    }
+    DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
+    mouse->valuator->motionHintWindow = NullWindow;
+    if (syncEvents.playingEvents)
+	mouse->grabTime = syncEvents.time;
+    else
+	mouse->grabTime = time;
+    if (grab->cursor)
+	grab->cursor->refcnt++;
+    mouse->activeGrab = *grab;
+    mouse->grab = &mouse->activeGrab;
+    mouse->fromPassiveGrab = autoGrab;
+    PostNewCursor();
+    CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+}
+
+void
+DeactivatePointerGrab(register DeviceIntPtr mouse)
+{
+    register GrabPtr grab = mouse->grab;
+    register DeviceIntPtr dev;
+
+    mouse->valuator->motionHintWindow = NullWindow;
+    mouse->grab = NullGrab;
+    mouse->sync.state = NOT_GRABBED;
+    mouse->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
+    if (grab->confineTo)
+	ConfineCursorToWindow(ROOT, FALSE, FALSE);
+    PostNewCursor();
+    if (grab->cursor)
+	FreeCursor(grab->cursor, (Cursor)0);
+    ComputeFreezes();
+}
+
+void
+ActivateKeyboardGrab(register DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+    WindowPtr oldWin;
+
+    if (keybd->grab)
+	oldWin = keybd->grab->window;
+    else if (keybd->focus)
+	oldWin = keybd->focus->win;
+    else
+	oldWin = sprite.win;
+    if (oldWin == FollowKeyboardWin)
+	oldWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+    if (syncEvents.playingEvents)
+	keybd->grabTime = syncEvents.time;
+    else
+	keybd->grabTime = time;
+    keybd->activeGrab = *grab;
+    keybd->grab = &keybd->activeGrab;
+    keybd->fromPassiveGrab = passive;
+    CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+void
+DeactivateKeyboardGrab(register DeviceIntPtr keybd)
+{
+    register GrabPtr grab = keybd->grab;
+    register DeviceIntPtr dev;
+    register WindowPtr focusWin = keybd->focus ? keybd->focus->win
+					       : sprite.win;
+
+    if (focusWin == FollowKeyboardWin)
+	focusWin = inputInfo.keyboard->focus->win;
+    if (keybd->valuator)
+	keybd->valuator->motionHintWindow = NullWindow;
+    keybd->grab = NullGrab;
+    keybd->sync.state = NOT_GRABBED;
+    keybd->fromPassiveGrab = FALSE;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev->sync.other == grab)
+	    dev->sync.other = NullGrab;
+    }
+    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+    ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client, TimeStamp time, DeviceIntPtr thisDev, int newState)
+{
+    Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+    TimeStamp grabTime;
+    register DeviceIntPtr dev;
+
+    thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
+    thisSynced = FALSE;
+    otherGrabbed = FALSE;
+    othersFrozen = TRUE;
+    grabTime = thisDev->grabTime;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+	if (dev == thisDev)
+	    continue;
+	if (dev->grab && SameClient(dev->grab, client))
+	{
+	    if (!(thisGrabbed || otherGrabbed) ||
+		(CompareTimeStamps(dev->grabTime, grabTime) == LATER))
+		grabTime = dev->grabTime;
+	    otherGrabbed = TRUE;
+	    if (thisDev->sync.other == dev->grab)
+		thisSynced = TRUE;
+	    if (dev->sync.state < FROZEN)
+		othersFrozen = FALSE;
+	}
+	else if (!dev->sync.other || !SameClient(dev->sync.other, client))
+	    othersFrozen = FALSE;
+    }
+    if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
+	return;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, grabTime) == EARLIER))
+	return;
+    switch (newState)
+    {
+	case THAWED:	 	       /* Async */
+	    if (thisGrabbed)
+		thisDev->sync.state = THAWED;
+	    if (thisSynced)
+		thisDev->sync.other = NullGrab;
+	    ComputeFreezes();
+	    break;
+	case FREEZE_NEXT_EVENT:		/* Sync */
+	    if (thisGrabbed)
+	    {
+		thisDev->sync.state = FREEZE_NEXT_EVENT;
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		ComputeFreezes();
+	    }
+	    break;
+	case THAWED_BOTH:		/* AsyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case FREEZE_BOTH_NEXT_EVENT:	/* SyncBoth */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+	case NOT_GRABBED:		/* Replay */
+	    if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
+	    {
+		if (thisSynced)
+		    thisDev->sync.other = NullGrab;
+		syncEvents.replayDev = thisDev;
+		syncEvents.replayWin = thisDev->grab->window;
+		(*thisDev->DeactivateGrab)(thisDev);
+		syncEvents.replayDev = (DeviceIntPtr)NULL;
+	    }
+	    break;
+	case THAW_OTHERS:		/* AsyncOthers */
+	    if (othersFrozen)
+	    {
+		for (dev = inputInfo.devices; dev; dev = dev->next)
+		{
+		    if (dev == thisDev)
+			continue;
+		    if (dev->grab && SameClient(dev->grab, client))
+			dev->sync.state = THAWED;
+		    if (dev->sync.other && SameClient(dev->sync.other, client))
+			dev->sync.other = NullGrab;
+		}
+		ComputeFreezes();
+	    }
+	    break;
+    }
+}
+
+int
+ProcAllowEvents(register ClientPtr client)
+{
+    TimeStamp		time;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    REQUEST(xAllowEventsReq);
+
+    REQUEST_SIZE_MATCH(xAllowEventsReq);
+    time = ClientTimeToServerTime(stuff->time);
+    switch (stuff->mode)
+    {
+	case ReplayPointer:
+	    AllowSome(client, time, mouse, NOT_GRABBED);
+	    break;
+	case SyncPointer: 
+	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncPointer: 
+	    AllowSome(client, time, mouse, THAWED);
+	    break;
+	case ReplayKeyboard: 
+	    AllowSome(client, time, keybd, NOT_GRABBED);
+	    break;
+	case SyncKeyboard: 
+	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+	    break;
+	case AsyncKeyboard: 
+	    AllowSome(client, time, keybd, THAWED);
+	    break;
+	case SyncBoth:
+	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+	    break;
+	case AsyncBoth:
+	    AllowSome(client, time, keybd, THAWED_BOTH);
+	    break;
+	default: 
+	    client->errorValue = stuff->mode;
+	    return BadValue;
+    }
+    return Success;
+}
+
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+    register DeviceIntPtr dev;
+    Bool    done;
+
+    /* XXX CloseDownClient should remove passive grabs before
+     * releasing active grabs.
+     */
+    do {
+    	done = TRUE;
+    	for (dev = inputInfo.devices; dev; dev = dev->next)
+    	{
+	    if (dev->grab && SameClient(dev->grab, client))
+	    {
+	    	(*dev->DeactivateGrab)(dev);
+	    	done = FALSE;
+	    }
+    	}
+    } while (!done);
+}
+
+/**************************************************************************
+ *            The following procedures deal with delivering events        *
+ **************************************************************************/
+
+int
+TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask, 
+                 Mask filter, GrabPtr grab)
+{
+    int i;
+    int type;
+
+#ifdef DEBUG
+    if (debug_events) ErrorF(
+	"Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+	((filter == CantBeFiltered) || (mask & filter)))
+    {
+	if (grab && !SameClient(grab, client))
+	    return -1; /* don't send, but notify caller */
+	type = pEvents->u.u.type;
+	if (type == MotionNotify)
+	{
+	    if (mask & PointerMotionHintMask)
+	    {
+		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
+		    pEvents->u.keyButtonPointer.event)
+		{
+#ifdef DEBUG
+		    if (debug_events) ErrorF("\n");
+	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
+		    return 1; /* don't send, but pretend we did */
+		}
+		pEvents->u.u.detail = NotifyHint;
+	    }
+	    else
+	    {
+		pEvents->u.u.detail = NotifyNormal;
+	    }
+	}
+#ifdef XINPUT
+	else
+	{
+	    if ((type == DeviceMotionNotify) &&
+		MaybeSendDeviceMotionNotifyHint
+			((deviceKeyButtonPointer*)pEvents, mask) != 0)
+		return 1;
+	}
+#endif
+	type &= 0177;
+	if (type != KeymapNotify)
+	{
+	    /* all extension events must have a sequence number */
+	    for (i = 0; i < count; i++)
+		pEvents[i].u.u.sequenceNumber = client->sequence;
+	}
+
+	if (BitIsOn(criticalEvents, type))
+	{
+#ifdef SMART_SCHEDULE
+	    if (client->smart_priority < SMART_MAX_PRIORITY)
+		client->smart_priority++;
+#endif
+	    SetCriticalOutputPending();
+	}
+
+	WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG
+	if (debug_events) ErrorF(  " delivered\n");
+#endif
+	return 1;
+    }
+    else
+    {
+#ifdef DEBUG
+	if (debug_events) ErrorF("\n");
+#endif
+	return 0;
+    }
+}
+
+int
+DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count, 
+                      Mask filter, GrabPtr grab, int mskidx)
+{
+    int deliveries = 0, nondeliveries = 0;
+    int attempt;
+    register InputClients *other;
+    ClientPtr client = NullClient;
+    Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+		              this mask is the mask of the grab. */
+    int type = pEvents->u.u.type;
+
+    /* CantBeFiltered means only window owner gets the event */
+    if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
+    {
+	/* if nobody ever wants to see this event, skip some work */
+	if (filter != CantBeFiltered &&
+	    !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+	    return 0;
+	if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
+				      pWin->eventMask, filter, grab)) )
+	{
+	    if (attempt > 0)
+	    {
+		deliveries++;
+		client = wClient(pWin);
+		deliveryMask = pWin->eventMask;
+	    } else
+		nondeliveries--;
+	}
+    }
+    if (filter != CantBeFiltered)
+    {
+	if (type & EXTENSION_EVENT_BASE)
+	{
+	    OtherInputMasks *inputMasks;
+
+	    inputMasks = wOtherInputMasks(pWin);
+	    if (!inputMasks ||
+		!(inputMasks->inputEvents[mskidx] & filter))
+		return 0;
+	    other = inputMasks->inputClients;
+	}
+	else
+	    other = (InputClients *)wOtherClients(pWin);
+	for (; other; other = other->next)
+	{
+	    if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
+					  other->mask[mskidx], filter, grab)) )
+	    {
+		if (attempt > 0)
+		{
+		    deliveries++;
+		    client = rClient(other);
+		    deliveryMask = other->mask[mskidx];
+		} else
+		    nondeliveries--;
+	    }
+	}
+    }
+    if ((type == ButtonPress) && deliveries && (!grab))
+    {
+	GrabRec tempGrab;
+
+	tempGrab.device = inputInfo.pointer;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.window = pWin;
+	tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+	tempGrab.eventMask = deliveryMask;
+	tempGrab.keyboardMode = GrabModeAsync;
+	tempGrab.pointerMode = GrabModeAsync;
+	tempGrab.confineTo = NullWindow;
+	tempGrab.cursor = NullCursor;
+	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
+					   currentTime, TRUE);
+    }
+    else if ((type == MotionNotify) && deliveries)
+	inputInfo.pointer->valuator->motionHintWindow = pWin;
+#ifdef XINPUT
+    else
+    {
+	if (((type == DeviceMotionNotify)
+#ifdef XKB
+	     || (type == DeviceButtonPress)
+#endif
+	    ) && deliveries)
+	    CheckDeviceGrabAndHintWindow (pWin, type,
+					  (deviceKeyButtonPointer*) pEvents,
+					  grab, client, deliveryMask);
+    }
+#endif
+    if (deliveries)
+	return deliveries;
+    return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0.  if
+   send works,  return 1 or if send didn't work, return 2.
+   Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int 
+XineramaTryClientEventsResult(
+    ClientPtr client,
+    GrabPtr grab,
+    Mask mask, 
+    Mask filter
+){
+    if ((client) && (client != serverClient) && (!client->clientGone) &&
+        ((filter == CantBeFiltered) || (mask & filter)))
+    {
+        if (grab && !SameClient(grab, client)) return -1;
+	else return 1;
+    }
+    return 0;
+}
+#endif
+
+int
+MaybeDeliverEventsToClient(register WindowPtr pWin, xEvent *pEvents, 
+                           int count, Mask filter, ClientPtr dontClient)
+{
+    register OtherClients *other;
+
+
+    if (pWin->eventMask & filter)
+    {
+        if (wClient(pWin) == dontClient)
+	    return 0;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	    return XineramaTryClientEventsResult(
+			wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+	return TryClientEvents(wClient(pWin), pEvents, count,
+			       pWin->eventMask, filter, NullGrab);
+    }
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->mask & filter)
+	{
+            if (SameClient(other, dontClient))
+		return 0;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
+	      return XineramaTryClientEventsResult(
+			rClient(other), NullGrab, other->mask, filter);
+#endif
+	    return TryClientEvents(rClient(other), pEvents, count,
+				   other->mask, filter, NullGrab);
+	}
+    }
+    return 2;
+}
+
+static void
+FixUpEventFromWindow(
+    xEvent *xE,
+    WindowPtr pWin,
+    Window child,
+    Bool calcChild)
+{
+    if (calcChild)
+    {
+        WindowPtr w=spriteTrace[spriteTraceGood-1];
+	/* If the search ends up past the root should the child field be 
+	 	set to none or should the value in the argument be passed 
+		through. It probably doesn't matter since everyone calls 
+		this function with child == None anyway. */
+
+        while (w) 
+        {
+            /* If the source window is same as event window, child should be
+		none.  Don't bother going all all the way back to the root. */
+
+ 	    if (w == pWin)
+	    { 
+   		child = None;
+ 		break;
+	    }
+	    
+	    if (w->parent == pWin)
+	    {
+		child = w->drawable.id;
+		break;
+            }
+ 	    w = w->parent;
+        } 	    
+    }
+    XE_KBPTR.root = ROOT->drawable.id;
+    XE_KBPTR.event = pWin->drawable.id;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	XE_KBPTR.sameScreen = xTrue;
+	XE_KBPTR.child = child;
+	XE_KBPTR.eventX =
+	XE_KBPTR.rootX - pWin->drawable.x;
+	XE_KBPTR.eventY =
+	XE_KBPTR.rootY - pWin->drawable.y;
+    }
+    else
+    {
+	XE_KBPTR.sameScreen = xFalse;
+	XE_KBPTR.child = None;
+	XE_KBPTR.eventX = 0;
+	XE_KBPTR.eventY = 0;
+    }
+}
+
+int
+DeliverDeviceEvents(register WindowPtr pWin, register xEvent *xE, GrabPtr grab, 
+                    register WindowPtr stopAt, DeviceIntPtr dev, int count)
+{
+    Window child = None;
+    int type = xE->u.u.type;
+    Mask filter = filters[type];
+    int deliveries = 0;
+
+    if (type & EXTENSION_EVENT_BASE)
+    {
+	register OtherInputMasks *inputMasks;
+	int mskidx = dev->id;
+
+	inputMasks = wOtherInputMasks(pWin);
+	if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
+	    return 0;
+	while (pWin)
+	{
+	    if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, mskidx);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(inputMasks &&
+		 (filter & inputMasks->dontPropagateMask[mskidx])))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	    if (pWin)
+		inputMasks = wOtherInputMasks(pWin);
+	}
+    }
+    else
+    {
+	if (!(filter & pWin->deliverableEvents))
+	    return 0;
+	while (pWin)
+	{
+	    if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+	    {
+		FixUpEventFromWindow(xE, pWin, child, FALSE);
+		deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
+						   grab, 0);
+		if (deliveries > 0)
+		    return deliveries;
+	    }
+	    if ((deliveries < 0) ||
+		(pWin == stopAt) ||
+		(filter & wDontPropagateMask(pWin)))
+		return 0;
+	    child = pWin->drawable.id;
+	    pWin = pWin->parent;
+	}
+    }
+    return 0;
+}
+
+/* not useful for events that propagate up the tree or extension events */
+int
+DeliverEvents(register WindowPtr pWin, register xEvent *xE, int count, 
+              register WindowPtr otherParent)
+{
+    Mask filter;
+    int     deliveries;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+	return count;
+#endif
+
+    if (!count)
+	return 0;
+    filter = filters[xE->u.u.type];
+    if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+	xE->u.destroyNotify.event = pWin->drawable.id;
+    if (filter != StructureAndSubMask)
+	return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
+    deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
+				       NullGrab, 0);
+    if (pWin->parent)
+    {
+	xE->u.destroyNotify.event = pWin->parent->drawable.id;
+	deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
+					    SubstructureNotifyMask, NullGrab,
+					    0);
+	if (xE->u.u.type == ReparentNotify)
+	{
+	    xE->u.destroyNotify.event = otherParent->drawable.id;
+	    deliveries += DeliverEventsToWindow(otherParent, xE, count,
+						SubstructureNotifyMask,
+						NullGrab, 0);
+	}
+    }
+    return deliveries;
+}
+
+
+static Bool 
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+	return TRUE;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	   if(POINT_IN_REGION(sprite.screen, 
+			&sprite.windows[i]->borderSize, 
+			x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, 
+			y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, 
+			&box))
+		return TRUE;
+	}
+    }
+#endif
+    return FALSE;
+}
+
+static WindowPtr 
+XYToWindow(int x, int y)
+{
+    register WindowPtr  pWin;
+    BoxRec		box;
+
+    spriteTraceGood = 1;	/* root window still there */
+    pWin = ROOT->firstChild;
+    while (pWin)
+    {
+	if ((pWin->mapped) &&
+	    (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+	    (x < pWin->drawable.x + (int)pWin->drawable.width +
+	     wBorderWidth(pWin)) &&
+	    (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+	    (y < pWin->drawable.y + (int)pWin->drawable.height +
+	     wBorderWidth (pWin))
+#ifdef SHAPE
+	    /* When a window is shaped, a further check
+	     * is made to see if the point is inside
+	     * borderSize
+	     */
+	    && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+	    && (!wInputShape(pWin) ||
+		POINT_IN_REGION(pWin->drawable.pScreen,
+				wInputShape(pWin),
+				x - pWin->drawable.x,
+				y - pWin->drawable.y, &box))
+#endif
+	    )
+	{
+	    if (spriteTraceGood >= spriteTraceSize)
+	    {
+		spriteTraceSize += 10;
+		Must_have_memory = TRUE; /* XXX */
+		spriteTrace = (WindowPtr *)xrealloc(
+		    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    spriteTrace[spriteTraceGood++] = pWin;
+	    pWin = pWin->firstChild;
+	}
+	else
+	    pWin = pWin->nextSib;
+    }
+    return spriteTrace[spriteTraceGood-1];
+}
+
+static Bool
+CheckMotion(xEvent *xE)
+{
+    WindowPtr prevSpriteWin = sprite.win;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaCheckMotion(xE);
+#endif
+
+    if (xE && !syncEvents.playingEvents)
+    {
+	if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
+	{
+	    sprite.hot.pScreen = sprite.hotPhys.pScreen;
+	    ROOT = WindowTable[sprite.hot.pScreen->myNum];
+	}
+#ifdef XEVIE
+	xeviehot.x =
+#endif
+	sprite.hot.x = XE_KBPTR.rootX;
+#ifdef XEVIE
+	xeviehot.y =
+#endif
+	sprite.hot.y = XE_KBPTR.rootY;
+	if (sprite.hot.x < sprite.physLimits.x1)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x1;
+	else if (sprite.hot.x >= sprite.physLimits.x2)
+#ifdef XEVIE
+	    xeviehot.x =
+#endif
+	    sprite.hot.x = sprite.physLimits.x2 - 1;
+	if (sprite.hot.y < sprite.physLimits.y1)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y1;
+	else if (sprite.hot.y >= sprite.physLimits.y2)
+#ifdef XEVIE
+	    xeviehot.y =
+#endif
+	    sprite.hot.y = sprite.physLimits.y2 - 1;
+#ifdef SHAPE
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
+#endif
+	sprite.hotPhys = sprite.hot;
+	if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
+	    (sprite.hotPhys.y != XE_KBPTR.rootY))
+	{
+	    (*sprite.hotPhys.pScreen->SetCursorPosition)(
+		sprite.hotPhys.pScreen,
+		sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
+	}
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+    }
+
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
+#ifdef notyet
+    if (!(sprite.win->deliverableEvents &
+	  Motion_Filter(inputInfo.pointer->button))
+	!syncEvents.playingEvents)
+    {
+	/* XXX Do PointerNonInterestBox here */
+    }
+#endif
+    if (sprite.win != prevSpriteWin)
+    {
+	if (prevSpriteWin != NullWindow) {
+	    if (!xE)
+		UpdateCurrentTimeIf();
+	    DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
+	}
+	PostNewCursor();
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void
+WindowsRestructured()
+{
+    (void) CheckMotion((xEvent *)NULL);
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx.  The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+    ScreenPtr pScreen = win->drawable.pScreen;
+    GrabPtr   grab;
+
+    if (noPanoramiXExtension) return;
+    
+    sprite.hot.x        -= xoff;
+    sprite.hot.y        -= yoff;
+
+    sprite.hotPhys.x    -= xoff;
+    sprite.hotPhys.y    -= yoff;
+
+    sprite.hotLimits.x1 -= xoff; 
+    sprite.hotLimits.y1 -= yoff;
+    sprite.hotLimits.x2 -= xoff;
+    sprite.hotLimits.y2 -= yoff;
+
+    if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg1))
+        REGION_TRANSLATE(sprite.screen, &sprite.Reg1,    xoff, yoff);
+    if (REGION_NOTEMPTY(sprite.screen, &sprite.Reg2))
+        REGION_TRANSLATE(sprite.screen, &sprite.Reg2,    xoff, yoff);
+
+    /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+    if ((grab = inputInfo.pointer->grab) && grab->confineTo) {
+	if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
+	    sprite.hotPhys.x = sprite.hotPhys.y = 0;
+	ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
+    } else
+	ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
+			      TRUE, FALSE);
+}
+#endif
+
+void
+DefineInitialRootWindow(register WindowPtr win)
+{
+    register ScreenPtr pScreen = win->drawable.pScreen;
+
+    sprite.hotPhys.pScreen = pScreen;
+    sprite.hotPhys.x = pScreen->width / 2;
+    sprite.hotPhys.y = pScreen->height / 2;
+    sprite.hot = sprite.hotPhys;
+    sprite.hotLimits.x2 = pScreen->width;
+    sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = win;
+    sprite.current = wCursor (win);
+    sprite.current->refcnt++;
+    spriteTraceGood = 1;
+    ROOT = win;
+    (*pScreen->CursorLimits) (
+	pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
+    sprite.confined = FALSE;
+    (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+    (*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
+    (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+	sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+	sprite.hotLimits.x2 = PanoramiXPixWidth  - panoramiXdataPtr[0].x;
+	sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+	sprite.physLimits = sprite.hotLimits;
+	sprite.confineWin = NullWindow;
+#ifdef SHAPE
+        sprite.hotShape = NullRegion;
+#endif
+	sprite.screen = pScreen;
+	/* gotta UNINIT these someplace */
+	REGION_NULL(pScreen, &sprite.Reg1);
+	REGION_NULL(pScreen, &sprite.Reg2);
+    }
+#endif
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+    PostNewCursor();
+}
+
+void
+NewCurrentScreen(ScreenPtr newScreen, int x, int y)
+{
+    sprite.hotPhys.x = x;
+    sprite.hotPhys.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - 
+			    panoramiXdataPtr[0].x;
+	sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - 
+			    panoramiXdataPtr[0].y;
+	if (newScreen != sprite.screen) {
+	    sprite.screen = newScreen;
+	    /* Make sure we tell the DDX to update its copy of the screen */
+	    if(sprite.confineWin)
+		XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
+	    else
+		XineramaConfineCursorToWindow(WindowTable[0], TRUE);
+	    /* if the pointer wasn't confined, the DDX won't get 
+	       told of the pointer warp so we reposition it here */
+	    if(!syncEvents.playingEvents)
+		(*sprite.screen->SetCursorPosition)(sprite.screen,
+		    sprite.hotPhys.x + panoramiXdataPtr[0].x - 
+			panoramiXdataPtr[sprite.screen->myNum].x,
+		    sprite.hotPhys.y + panoramiXdataPtr[0].y - 
+			panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
+	}
+    } else 
+#endif
+    if (newScreen != sprite.hotPhys.pScreen)
+	ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+    WindowPtr pWin,
+    int x,
+    int y
+)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    BoxRec box;
+    int i, xoff, yoff;
+
+    if (!pWin->realized) return FALSE;
+
+    if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+        return TRUE;
+    
+    if(!XineramaSetWindowPntrs(pWin)) return FALSE;
+
+    xoff = x + panoramiXdataPtr[0].x;  
+    yoff = y + panoramiXdataPtr[0].y;  
+
+    for(i = 1; i < PanoramiXNumScreens; i++) {
+	pWin = sprite.windows[i];
+	pScreen = pWin->drawable.pScreen;
+	x = xoff - panoramiXdataPtr[i].x;
+	y = yoff - panoramiXdataPtr[i].y;
+
+	if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+	   && (!wInputShape(pWin) ||
+	       POINT_IN_REGION(pWin->drawable.pScreen,
+			       wInputShape(pWin),
+			       x - pWin->drawable.x, 
+			       y - pWin->drawable.y, &box)))
+            return TRUE;
+
+    }
+
+    return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+
+    REQUEST(xWarpPointerReq);
+
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if(source == WindowTable[0]) {
+	    winX -= panoramiXdataPtr[0].x;
+	    winY -= panoramiXdataPtr[0].y;
+	}
+	if (x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !XineramaPointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	if(dest == WindowTable[0]) {
+	    x -= panoramiXdataPtr[0].x;
+	    y -= panoramiXdataPtr[0].y;
+	}
+    } 
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < sprite.physLimits.x1)
+	x = sprite.physLimits.x1;
+    else if (x >= sprite.physLimits.x2)
+	x = sprite.physLimits.x2 - 1;
+    if (y < sprite.physLimits.y1)
+	y = sprite.physLimits.y1;
+    else if (y >= sprite.physLimits.y2)
+	y = sprite.physLimits.y2 - 1;
+    if (sprite.hotShape)
+	ConfineToShape(sprite.hotShape, &x, &y);
+
+    XineramaSetCursorPosition(x, y, TRUE);
+
+    return Success;
+}
+
+#endif
+
+
+int
+ProcWarpPointer(ClientPtr client)
+{
+    WindowPtr	dest = NULL;
+    int		x, y;
+    ScreenPtr	newScreen;
+
+    REQUEST(xWarpPointerReq);
+
+    REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension)
+	return XineramaWarpPointer(client);
+#endif
+
+    if (stuff->dstWid != None)
+    {
+	dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
+	if (!dest)
+	    return BadWindow;
+    }
+    x = sprite.hotPhys.x;
+    y = sprite.hotPhys.y;
+
+    if (stuff->srcWid != None)
+    {
+	int     winX, winY;
+ 	XID 	winID = stuff->srcWid;
+        WindowPtr source;
+	
+	source = SecurityLookupWindow(winID, client, SecurityReadAccess);
+	if (!source) return BadWindow;
+
+	winX = source->drawable.x;
+	winY = source->drawable.y;
+	if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
+	    x < winX + stuff->srcX ||
+	    y < winY + stuff->srcY ||
+	    (stuff->srcWidth != 0 &&
+	     winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+	    (stuff->srcHeight != 0 &&
+	     winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+	    !PointInWindowIsVisible(source, x, y))
+	    return Success;
+    }
+    if (dest) 
+    {
+	x = dest->drawable.x;
+	y = dest->drawable.y;
+	newScreen = dest->drawable.pScreen;
+    } else 
+	newScreen = sprite.hotPhys.pScreen;
+
+    x += stuff->dstX;
+    y += stuff->dstY;
+
+    if (x < 0)
+	x = 0;
+    else if (x >= newScreen->width)
+	x = newScreen->width - 1;
+    if (y < 0)
+	y = 0;
+    else if (y >= newScreen->height)
+	y = newScreen->height - 1;
+
+    if (newScreen == sprite.hotPhys.pScreen)
+    {
+	if (x < sprite.physLimits.x1)
+	    x = sprite.physLimits.x1;
+	else if (x >= sprite.physLimits.x2)
+	    x = sprite.physLimits.x2 - 1;
+	if (y < sprite.physLimits.y1)
+	    y = sprite.physLimits.y1;
+	else if (y >= sprite.physLimits.y2)
+	    y = sprite.physLimits.y2 - 1;
+#if defined(SHAPE)
+	if (sprite.hotShape)
+	    ConfineToShape(sprite.hotShape, &x, &y);
+#endif
+	(*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
+    }
+    else if (!PointerConfinedToScreen())
+    {
+	NewCurrentScreen(newScreen, x, y);
+    }
+    return Success;
+}
+
+static Bool 
+BorderSizeNotEmpty(WindowPtr pWin)
+{
+     if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
+	return TRUE;
+
+#ifdef PANORAMIX
+     if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
+	int i;
+
+	for(i = 1; i < PanoramiXNumScreens; i++) {
+	    if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
+		return TRUE;
+	}
+     }
+#endif
+     return FALSE;
+}
+
+/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+	passive grab set on the window to be activated. */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+    WindowPtr pWin,
+    register DeviceIntPtr device,
+    register xEvent *xE,
+    int count)
+{
+    register GrabPtr grab = wPassiveGrabs(pWin);
+    GrabRec tempGrab;
+    register xEvent *dxE;
+
+    if (!grab)
+	return FALSE;
+    tempGrab.window = pWin;
+    tempGrab.device = device;
+    tempGrab.type = xE->u.u.type;
+    tempGrab.detail.exact = xE->u.u.detail;
+    tempGrab.detail.pMask = NULL;
+    tempGrab.modifiersDetail.pMask = NULL;
+    for (; grab; grab = grab->next)
+    {
+#ifdef XKB
+	DeviceIntPtr	gdev;
+	XkbSrvInfoPtr	xkbi;
+
+	gdev= grab->modifierDevice;
+	xkbi= gdev->key->xkbInfo;
+#endif
+	tempGrab.modifierDevice = grab->modifierDevice;
+	if ((device == grab->modifierDevice) &&
+	    ((xE->u.u.type == KeyPress)
+#if defined(XINPUT) && defined(XKB)
+	     || (xE->u.u.type == DeviceKeyPress)
+#endif
+	     ))
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->prev_state;
+#endif
+	else
+	    tempGrab.modifiersDetail.exact =
+#ifdef XKB
+		(noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
+#else
+		grab->modifierDevice->key->state;
+#endif
+	if (GrabMatchesSecond(&tempGrab, grab) &&
+	    (!grab->confineTo ||
+	     (grab->confineTo->realized && 
+				BorderSizeNotEmpty(grab->confineTo))))
+	{
+#ifdef XCSECURITY
+	    if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
+		return FALSE;
+#endif
+#ifdef XKB
+	    if (!noXkbExtension) {
+		XE_KBPTR.state &= 0x1f00;
+		XE_KBPTR.state |=
+				tempGrab.modifiersDetail.exact&(~0x1f00);
+	    }
+#endif
+	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
+ 
+	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
+
+	    (void) TryClientEvents(rClient(grab), xE, count,
+				   filters[xE->u.u.type],
+				   filters[xE->u.u.type],  grab);
+
+	    if (device->sync.state == FROZEN_NO_EVENT)
+	    {
+		if (device->sync.evcount < count)
+		{
+		    Must_have_memory = TRUE; /* XXX */
+		    device->sync.event = (xEvent *)xrealloc(device->sync.event,
+							    count*
+							    sizeof(xEvent));
+		    Must_have_memory = FALSE; /* XXX */
+		}
+		device->sync.evcount = count;
+		for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
+		    *dxE = *xE;
+	    	device->sync.state = FROZEN_WITH_EVENT;
+            }	
+	    return TRUE;
+	}
+    }
+    return FALSE;
+}
+
+/**
+"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
+a passive grab to be activated.  If the event is a keyboard event, the
+ancestors of the focus window are traced down and tried to see if they have
+any passive grabs to be activated.  If the focus window itself is reached and
+it's descendants contain they pointer, the ancestors of the window that the
+pointer is in are then traced down starting at the focus window, otherwise no
+grabs are activated.  If the event is a pointer event, the ancestors of the
+window that the pointer is in are traced down starting at the root until
+CheckPassiveGrabs causes a passive grab to activate or all the windows are
+tried. PRH
+*/
+
+Bool
+CheckDeviceGrabs(register DeviceIntPtr device, register xEvent *xE, 
+                 int checkFirst, int count)
+{
+    register int i;
+    register WindowPtr pWin = NULL;
+    register FocusClassPtr focus = device->focus;
+
+    if (((xE->u.u.type == ButtonPress)
+#if defined(XINPUT) && defined(XKB)
+	 || (xE->u.u.type == DeviceButtonPress)
+#endif
+	 ) && (device->button->buttonsDown != 1))
+	return FALSE;
+
+    i = checkFirst;
+
+    if (focus)
+    {
+	for (; i < focus->traceGood; i++)
+	{
+	    pWin = focus->trace[i];
+	    if (pWin->optional &&
+		CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+		return TRUE;
+	}
+  
+	if ((focus->win == NoneWin) ||
+	    (i >= spriteTraceGood) ||
+	    ((i > checkFirst) && (pWin != spriteTrace[i-1])))
+	    return FALSE;
+    }
+
+    for (; i < spriteTraceGood; i++)
+    {
+	pWin = spriteTrace[i];
+	if (pWin->optional &&
+	    CheckPassiveGrabsOnWindow(pWin, device, xE, count))
+	    return TRUE;
+    }
+
+    return FALSE;
+}
+
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+{
+    WindowPtr focus = keybd->focus->win;
+    int mskidx = 0;
+
+    if (focus == FollowKeyboardWin)
+	focus = inputInfo.keyboard->focus->win;
+    if (!focus)
+	return;
+    if (focus == PointerRootWin)
+    {
+	DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+	return;
+    }
+    if ((focus == window) || IsParent(focus, window))
+    {
+	if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+	    return;
+    }
+    /* just deliver it to the focus window */
+    FixUpEventFromWindow(xE, focus, None, FALSE);
+    if (xE->u.u.type & EXTENSION_EVENT_BASE)
+	mskidx = keybd->id;
+    (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
+				NullGrab, mskidx);
+}
+
+void
+DeliverGrabbedEvent(register xEvent *xE, register DeviceIntPtr thisDev, 
+                    Bool deactivateGrab, int count)
+{
+    register GrabPtr grab = thisDev->grab;
+    int deliveries = 0;
+    register DeviceIntPtr dev;
+    register xEvent *dxE;
+
+    if (grab->ownerEvents)
+    {
+	WindowPtr focus;
+
+	if (thisDev->focus)
+	{
+	    focus = thisDev->focus->win;
+	    if (focus == FollowKeyboardWin)
+		focus = inputInfo.keyboard->focus->win;
+	}
+	else
+	    focus = PointerRootWin;
+	if (focus == PointerRootWin)
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
+					     thisDev, count);
+	else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
+	    deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
+					     thisDev, count);
+	else if (focus)
+	    deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
+					     thisDev, count);
+    }
+    if (!deliveries)
+    {
+	FixUpEventFromWindow(xE, grab->window, None, TRUE);
+	deliveries = TryClientEvents(rClient(grab), xE, count,
+				     (Mask)grab->eventMask,
+				     filters[xE->u.u.type], grab);
+	if (deliveries && (xE->u.u.type == MotionNotify
+#ifdef XINPUT
+			   || xE->u.u.type == DeviceMotionNotify
+#endif
+			   ))
+	    thisDev->valuator->motionHintWindow = grab->window;
+    }
+    if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
+#ifdef XINPUT
+					  && xE->u.u.type != DeviceMotionNotify
+#endif
+					  ))
+	switch (thisDev->sync.state)
+	{
+	case FREEZE_BOTH_NEXT_EVENT:
+	    for (dev = inputInfo.devices; dev; dev = dev->next)
+	    {
+		if (dev == thisDev)
+		    continue;
+		FreezeThaw(dev, TRUE);
+		if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+		    (CLIENT_BITS(dev->grab->resource) ==
+		     CLIENT_BITS(thisDev->grab->resource)))
+		    dev->sync.state = FROZEN_NO_EVENT;
+		else
+		    dev->sync.other = thisDev->grab;
+	    }
+	    /* fall through */
+	case FREEZE_NEXT_EVENT:
+	    thisDev->sync.state = FROZEN_WITH_EVENT;
+	    FreezeThaw(thisDev, TRUE);
+	    if (thisDev->sync.evcount < count)
+	    {
+		Must_have_memory = TRUE; /* XXX */
+		thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
+							 count*sizeof(xEvent));
+		Must_have_memory = FALSE; /* XXX */
+	    }
+	    thisDev->sync.evcount = count;
+	    for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
+		*dxE = *xE;
+	    break;
+	}
+}
+
+void
+#ifdef XKB
+CoreProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#else
+ProcessKeyboardEvent (register xEvent *xE, register DeviceIntPtr keybd, int count)
+#endif
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register int    i;
+    register CARD8  modifiers;
+    register CARD16 mask;
+    GrabPtr         grab = keybd->grab;
+    Bool            deactivateGrab = FALSE;
+    register KeyClassPtr keyc = keybd->key;
+#ifdef XEVIE
+    static Window           rootWin = 0;
+
+    if(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+          (xevieMask & xevieFilters[xE->u.u.type])) {
+      key = xE->u.u.detail;
+      kptr = &keyc->down[key >> 3];
+      bit = 1 << (key & 7);
+      if((xE->u.u.type == KeyPress &&  (*kptr & bit)) ||
+         (xE->u.u.type == KeyRelease && !(*kptr & bit)))
+      {} else {
+#ifdef XKB
+        if(!noXkbExtension)
+	    xevieKBEventSent = 1;
+#endif
+        if(!xevieKBEventSent)
+        {
+          xeviekb = keybd;
+          if(!rootWin) {
+	      rootWin = GetCurrentRootWindow()->drawable.id;
+          }
+          xE->u.keyButtonPointer.event = xeviewin->drawable.id;
+          xE->u.keyButtonPointer.root = rootWin;
+          xE->u.keyButtonPointer.child = (xeviewin->firstChild) ? xeviewin->firstChild->
+drawable.id:0;
+          xE->u.keyButtonPointer.rootX = xeviehot.x;
+          xE->u.keyButtonPointer.rootY = xeviehot.y;
+          xE->u.keyButtonPointer.state = keyc->state;
+          WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+#ifdef XKB
+          if(noXkbExtension)
+#endif
+            return;
+        } else {
+	    xevieKBEventSent = 0;
+        }
+      }
+    }
+#endif
+
+    if (!syncEvents.playingEvents)
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+#ifdef XEVIE
+    /* fix for bug5094030: don't change the state bit if the event is from XEvIE client */
+    if(!(!xeviegrabState && xevieFlag && clients[xevieClientIndex] &&
+	 (xevieMask & xevieFilters[xE->u.u.type]
+#ifdef XKB
+	  && !noXkbExtension
+#endif
+    )))
+#endif
+    XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
+    XE_KBPTR.rootX = sprite.hot.x;
+    XE_KBPTR.rootY = sprite.hot.y;
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+    modifiers = keyc->modifierMap[key];
+#if defined(XKB) && defined(XEVIE)
+    if(!noXkbExtension && !xeviegrabState &&
+       xevieFlag && clients[xevieClientIndex] &&
+       (xevieMask & xevieFilters[xE->u.u.type])) {
+	switch(xE->u.u.type) {
+	  case KeyPress: *kptr &= ~bit; break;
+	  case KeyRelease: *kptr |= bit; break;
+	}
+    }
+#endif
+
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    if (*kptr & bit) /* allow ddx to generate multiple downs */
+	    {   
+		if (!modifiers)
+		{
+		    xE->u.u.type = KeyRelease;
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		    xE->u.u.type = KeyPress;
+		    /* release can have side effects, don't fall through */
+		    (*keybd->public.processInputProc)(xE, keybd, count);
+		}
+		return;
+	    }
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr |= bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers)
+		{
+		    /* This key affects modifier "i" */
+		    keyc->modifierKeyCount[i]++;
+		    keyc->state |= mask;
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
+	    {
+		keybd->activatingKey = key;
+		return;
+	    }
+	    break;
+	case KeyRelease: 
+	    if (!(*kptr & bit)) /* guard against duplicates */
+		return;
+	    inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+	    *kptr &= ~bit;
+	    keyc->prev_state = keyc->state;
+	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
+	    {
+		if (mask & modifiers) {
+		    /* This key affects modifier "i" */
+		    if (--keyc->modifierKeyCount[i] <= 0) {
+			keyc->state &= ~mask;
+			keyc->modifierKeyCount[i] = 0;
+		    }
+		    modifiers &= ~mask;
+		}
+	    }
+	    if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+    if (grab)
+	DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
+    else
+	DeliverFocusedEvent(keybd, xE, sprite.win, count);
+    if (deactivateGrab)
+        (*keybd->DeactivateGrab)(keybd);
+}
+
+#ifdef XKB
+/* This function is used to set the key pressed or key released state -
+   this is only used when the pressing of keys does not cause 
+   CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (register xEvent *xE, register DeviceIntPtr keybd)
+{
+    int             key, bit;
+    register BYTE   *kptr;
+    register KeyClassPtr keyc = keybd->key;
+
+    key = xE->u.u.detail;
+    kptr = &keyc->down[key >> 3];
+    bit = 1 << (key & 7);
+#ifdef DEBUG
+    if ((xkbDebugFlags&0x4)&&
+	((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+	ErrorF("FixKeyState: Key %d %s\n",key,
+			(xE->u.u.type==KeyPress?"down":"up"));
+    }
+#endif
+    switch (xE->u.u.type)
+    {
+	case KeyPress: 
+	    *kptr |= bit;
+	    break;
+	case KeyRelease: 
+	    *kptr &= ~bit;
+	    break;
+	default: 
+	    FatalError("Impossible keyboard event");
+    }
+}
+#endif
+
+void
+#ifdef XKB
+CoreProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#else
+ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count)
+#endif
+{
+    register GrabPtr	grab = mouse->grab;
+    Bool                deactivateGrab = FALSE;
+    register ButtonClassPtr butc = mouse->button;
+#ifdef XKB
+    XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
+#endif
+#ifdef XEVIE
+    if(xevieFlag && clients[xevieClientIndex] && !xeviegrabState &&
+       (xevieMask & xevieFilters[xE->u.u.type])) {
+      if(xevieEventSent)
+        xevieEventSent = 0;
+      else {
+        xeviemouse = mouse;
+        WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
+        return;
+      }
+    }
+#endif
+
+    if (!syncEvents.playingEvents)
+	NoticeTime(xE)
+    XE_KBPTR.state = (butc->state | (
+#ifdef XKB
+			(noXkbExtension ?
+				inputInfo.keyboard->key->state :
+				xkbi->state.grab_mods)
+#else
+			inputInfo.keyboard->key->state
+#endif
+				    ));
+    {
+	NoticeTime(xE);
+	if (DeviceEventCallback)
+	{
+	    DeviceEventInfoRec eventinfo;
+	    /* see comment in EnqueueEvents regarding the next three lines */
+	    if (xE->u.u.type == MotionNotify)
+		XE_KBPTR.root =
+		    WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
+	    eventinfo.events = xE;
+	    eventinfo.count = count;
+	    CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
+	}
+    }
+    if (xE->u.u.type != MotionNotify)
+    {
+	register int  key;
+	register BYTE *kptr;
+	int           bit;
+
+	XE_KBPTR.rootX = sprite.hot.x;
+	XE_KBPTR.rootY = sprite.hot.y;
+
+	key = xE->u.u.detail;
+	kptr = &butc->down[key >> 3];
+	bit = 1 << (key & 7);
+	switch (xE->u.u.type)
+	{
+	case ButtonPress: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (!(*kptr & bit))
+		butc->buttonsDown++;
+	    butc->motionMask = ButtonMotionMask;
+	    *kptr |= bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!grab)
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		    return;
+	    break;
+	case ButtonRelease: 
+	    mouse->valuator->motionHintWindow = NullWindow;
+	    if (*kptr & bit)
+		--butc->buttonsDown;
+	    if (!butc->buttonsDown)
+		butc->motionMask = 0;
+	    *kptr &= ~bit;
+#if !defined(XFree86Server) || !defined(XINPUT)
+	    xE->u.u.detail = butc->map[key];
+#endif
+	    if (xE->u.u.detail == 0)
+		return;
+	    if (xE->u.u.detail <= 5)
+		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
+	    filters[MotionNotify] = Motion_Filter(butc);
+	    if (!butc->state && mouse->fromPassiveGrab)
+		deactivateGrab = TRUE;
+	    break;
+	default: 
+	    FatalError("bogus pointer event from ddx");
+	}
+    }
+    else if (!CheckMotion(xE))
+	return;
+    if (grab)
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    else
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    if (deactivateGrab)
+        (*mouse->DeactivateGrab)(mouse);
+}
+
+#define AtMostOneClient \
+	(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+
+void
+RecalculateDeliverableEvents(pWin)
+    register WindowPtr pWin;
+{
+    register OtherClients *others;
+    register WindowPtr pChild;
+
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->optional)
+	{
+	    pChild->optional->otherEventMasks = 0;
+	    for (others = wOtherClients(pChild); others; others = others->next)
+	    {
+		pChild->optional->otherEventMasks |= others->mask;
+	    }
+	}
+	pChild->deliverableEvents = pChild->eventMask|
+				    wOtherEventMasks(pChild);
+	if (pChild->parent)
+	    pChild->deliverableEvents |=
+		(pChild->parent->deliverableEvents &
+		 ~wDontPropagateMask(pChild) & PropagateMask);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+/**
+ *
+ *  \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+    register OtherClientsPtr other, prev;
+    register WindowPtr pWin = (WindowPtr)value;
+
+    prev = 0;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (other->resource == id)
+	{
+	    if (prev)
+		prev->next = other->next;
+	    else
+	    {
+		if (!(pWin->optional->otherClients = other->next))
+		    CheckWindowOptionalNeed (pWin);
+	    }
+	    xfree(other);
+	    RecalculateDeliverableEvents(pWin);
+	    return(Success);
+	}
+	prev = other;
+    }
+    FatalError("client not on event list");
+    /*NOTREACHED*/
+    return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(register WindowPtr pWin, register ClientPtr client, Mask mask)
+{
+    Mask check;
+    OtherClients * others;
+
+    if (mask & ~AllEventMasks)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    check = (mask & AtMostOneClient);
+    if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+    {				       /* It is illegal for two different
+				          clients to select on any of the
+				          events for AtMostOneClient. However,
+				          it is OK, for some client to
+				          continue selecting on one of those
+				          events.  */
+	if ((wClient(pWin) != client) && (check & pWin->eventMask))
+	    return BadAccess;
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (!SameClient(others, client) && (check & others->mask))
+		return BadAccess;
+	}
+    }
+    if (wClient (pWin) == client)
+    {
+	check = pWin->eventMask;
+#ifdef SGIMISC
+	pWin->eventMask =
+	    (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
+#else
+	pWin->eventMask = mask;
+#endif
+    }
+    else
+    {
+	for (others = wOtherClients (pWin); others; others = others->next)
+	{
+	    if (SameClient(others, client))
+	    {
+		check = others->mask;
+#ifdef SGIMISC
+		mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
+#endif
+		if (mask == 0)
+		{
+		    FreeResource(others->resource, RT_NONE);
+		    return Success;
+		}
+		else
+		    others->mask = mask;
+		goto maskSet;
+	    }
+	}
+	check = 0;
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return BadAlloc;
+	others = (OtherClients *) xalloc(sizeof(OtherClients));
+	if (!others)
+	    return BadAlloc;
+	others->mask = mask;
+	others->resource = FakeClientID(client->index);
+	others->next = pWin->optional->otherClients;
+	pWin->optional->otherClients = others;
+	if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+	    return BadAlloc;
+    }
+maskSet: 
+    if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
+	(mask & PointerMotionHintMask) &&
+	!(check & PointerMotionHintMask) &&
+	!inputInfo.pointer->grab)
+	inputInfo.pointer->valuator->motionHintWindow = NullWindow;
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+int
+EventSuppressForWindow(register WindowPtr pWin, register ClientPtr client, 
+                       Mask mask, Bool *checkOptional)
+{
+    register int i, free;
+
+    if ((mask & ~PropagateMask) && !permitOldBugs)
+    {
+	client->errorValue = mask;
+	return BadValue;
+    }
+    if (pWin->dontPropagate)
+	DontPropagateRefCnts[pWin->dontPropagate]--;
+    if (!mask)
+	i = 0;
+    else
+    {
+	for (i = DNPMCOUNT, free = 0; --i > 0; )
+	{
+	    if (!DontPropagateRefCnts[i])
+		free = i;
+	    else if (mask == DontPropagateMasks[i])
+		break;
+	}
+	if (!i && free)
+	{
+	    i = free;
+	    DontPropagateMasks[i] = mask;
+	}
+    }
+    if (i || !mask)
+    {
+	pWin->dontPropagate = i;
+	if (i)
+	    DontPropagateRefCnts[i]++;
+	if (pWin->optional)
+	{
+	    pWin->optional->dontPropagateMask = mask;
+	    *checkOptional = TRUE;
+	}
+    }
+    else
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	{
+	    if (pWin->dontPropagate)
+		DontPropagateRefCnts[pWin->dontPropagate]++;
+	    return BadAlloc;
+	}
+	pWin->dontPropagate = 0;
+        pWin->optional->dontPropagateMask = mask;
+    }
+    RecalculateDeliverableEvents(pWin);
+    return Success;
+}
+
+static WindowPtr 
+CommonAncestor(
+    register WindowPtr a,
+    register WindowPtr b)
+{
+    for (b = b->parent; b; b = b->parent)
+	if (IsParent(b, a)) return b;
+    return NullWindow;
+}
+
+static void
+EnterLeaveEvent(
+    int type,
+    int mode,
+    int detail,
+    register WindowPtr pWin,
+    Window child)
+{
+    xEvent		event;
+    register DeviceIntPtr keybd = inputInfo.keyboard;
+    WindowPtr		focus;
+    register DeviceIntPtr mouse = inputInfo.pointer;
+    register GrabPtr	grab = mouse->grab;
+    Mask		mask;
+
+    if ((pWin == mouse->valuator->motionHintWindow) &&
+	(detail != NotifyInferior))
+	mouse->valuator->motionHintWindow = NullWindow;
+    if (grab)
+    {
+	mask = (pWin == grab->window) ? grab->eventMask : 0;
+	if (grab->ownerEvents)
+	    mask |= EventMaskForClient(pWin, rClient(grab));
+    }
+    else
+    {
+	mask = pWin->eventMask | wOtherEventMasks(pWin);
+    }
+    if (mask & filters[type])
+    {
+	event.u.u.type = type;
+	event.u.u.detail = detail;
+	event.u.enterLeave.time = currentTime.milliseconds;
+	event.u.enterLeave.rootX = sprite.hot.x;
+	event.u.enterLeave.rootY = sprite.hot.y;
+	/* Counts on the same initial structure of crossing & button events! */
+	FixUpEventFromWindow(&event, pWin, None, FALSE);
+	/* Enter/Leave events always set child */
+	event.u.enterLeave.child = child;
+	event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+					    ELFlagSameScreen : 0;
+#ifdef XKB
+	if (!noXkbExtension) {
+	    event.u.enterLeave.state = mouse->button->state & 0x1f00;
+	    event.u.enterLeave.state |= 
+			XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+	} else
+#endif
+	event.u.enterLeave.state = keybd->key->state | mouse->button->state;
+	event.u.enterLeave.mode = mode;
+	focus = keybd->focus->win;
+	if ((focus != NoneWin) &&
+	    ((pWin == focus) || (focus == PointerRootWin) ||
+	     IsParent(focus, pWin)))
+	    event.u.enterLeave.flags |= ELFlagFocus;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), &event, 1, mask,
+				  filters[type], grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
+					NullGrab, 0);
+    }
+    if ((type == EnterNotify) && (mask & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+
+#ifdef XCSECURITY
+	ClientPtr client = grab ? rClient(grab)
+				: clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+	ke.type = KeymapNotify;
+	if (grab)
+	    (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
+				  KeymapStateMask, grab);
+	else
+	    (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+					KeymapStateMask, NullGrab, 0);
+    }
+}
+
+static void
+EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
+{
+    WindowPtr	parent = child->parent;
+
+    if (ancestor == parent)
+	return;
+    EnterNotifies(ancestor, parent, mode, detail);
+    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
+}
+
+static void
+LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
+{
+    register WindowPtr  pWin;
+
+    if (ancestor == child)
+	return;
+    for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
+    {
+	EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
+	child = pWin;
+    }
+}
+
+static void
+DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+    if (fromWin == toWin)
+	return;
+    if (IsParent(fromWin, toWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
+	EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
+    }
+    else if (IsParent(toWin, fromWin))
+    {
+	EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
+	LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
+    }
+    else
+    { /* neither fromWin nor toWin is descendent of the other */
+	WindowPtr common = CommonAncestor(toWin, fromWin);
+	/* common == NullWindow ==> different screens */
+	EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
+	LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
+	EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
+	EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
+    }
+}
+
+static void
+FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
+{
+    xEvent event;
+
+#ifdef XINPUT
+    if (dev != inputInfo.keyboard)
+    {
+	DeviceFocusEvent(dev, type, mode, detail, pWin);
+	return;
+    }
+#endif
+    event.u.focus.mode = mode;
+    event.u.u.type = type;
+    event.u.u.detail = detail;
+    event.u.focus.window = pWin->drawable.id;
+    (void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
+				0);
+    if ((type == FocusIn) &&
+	((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+    {
+	xKeymapEvent ke;
+#ifdef XCSECURITY
+	ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
+	if (!SecurityCheckDeviceAccess(client, dev, FALSE))
+	{
+	    bzero((char *)&ke.map[0], 31);
+	}
+	else
+#endif
+	memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+	ke.type = KeymapNotify;
+	(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
+				    KeymapStateMask, NullGrab, 0);
+    }
+}
+
+ /*
+  * recursive because it is easier
+  * no-op if child not descended from ancestor
+  */
+static Bool
+FocusInEvents(
+    DeviceIntPtr dev,
+    WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
+    int mode, int detail,
+    Bool doAncestor)
+{
+    if (child == NullWindow)
+	return ancestor == NullWindow;
+    if (ancestor == child)
+    {
+	if (doAncestor)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
+		      doAncestor))
+    {
+	if (child != skipChild)
+	    FocusEvent(dev, FocusIn, mode, detail, child);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+/* dies horribly if ancestor is not an ancestor of child */
+static void
+FocusOutEvents(
+    DeviceIntPtr dev,
+    WindowPtr child, WindowPtr ancestor,
+    int mode, int detail,
+    Bool doAncestor)
+{
+    register WindowPtr  pWin;
+
+    for (pWin = child; pWin != ancestor; pWin = pWin->parent)
+	FocusEvent(dev, FocusOut, mode, detail, pWin);
+    if (doAncestor)
+	FocusEvent(dev, FocusOut, mode, detail, ancestor);
+}
+
+void
+DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
+{
+    int     out, in;		       /* for holding details for to/from
+				          PointerRoot/None */
+    int     i;
+
+    if (fromWin == toWin)
+	return;
+    out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+    in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
+ /* wrong values if neither, but then not referenced */
+
+    if ((toWin == NullWindow) || (toWin == PointerRootWin))
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+   	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+	    /* Notify all the roots */
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	}
+	else
+	{
+	    if (IsParent(fromWin, sprite.win))
+	      FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
+			     FALSE);
+	    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+	    /* next call catches the root too, if the screen changed */
+	    FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
+			   NotifyNonlinearVirtual, FALSE);
+	}
+	/* Notify all the roots */
+#ifdef PANORAMIX
+	if ( !noPanoramiXExtension )
+	    FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
+	else 
+#endif
+	    for (i=0; i<screenInfo.numScreens; i++)
+	        FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+	if (toWin == PointerRootWin)
+	    (void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
+				NotifyPointer, TRUE);
+    }
+    else
+    {
+	if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
+	{
+	    if (fromWin == PointerRootWin)
+		FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
+			       TRUE);
+#ifdef PANORAMIX
+ 	    if ( !noPanoramiXExtension )
+	        FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
+	    else 
+#endif
+	        for (i=0; i<screenInfo.numScreens; i++)
+	            FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+	    if (toWin->parent != NullWindow)
+	      (void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
+				  NotifyNonlinearVirtual, TRUE);
+	    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+	    if (IsParent(toWin, sprite.win))
+    	       (void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
+				   NotifyPointer, FALSE);
+	}
+	else
+	{
+	    if (IsParent(toWin, fromWin))
+	    {
+		FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
+		FocusOutEvents(dev, fromWin->parent, toWin, mode,
+			       NotifyVirtual, FALSE);
+		FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
+		if ((IsParent(toWin, sprite.win)) &&
+			(sprite.win != fromWin) &&
+			(!IsParent(fromWin, sprite.win)) &&
+			(!IsParent(sprite.win, fromWin)))
+		    (void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					mode, NotifyPointer, FALSE);
+	    }
+	    else
+		if (IsParent(fromWin, toWin))
+		{
+		    if ((IsParent(fromWin, sprite.win)) &&
+			    (sprite.win != fromWin) &&
+			    (!IsParent(toWin, sprite.win)) &&
+			    (!IsParent(sprite.win, toWin)))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
+		    (void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
+					NotifyVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
+		}
+		else
+		{
+		/* neither fromWin or toWin is child of other */
+		    WindowPtr common = CommonAncestor(toWin, fromWin);
+		/* common == NullWindow ==> different screens */
+		    if (IsParent(fromWin, sprite.win))
+			FocusOutEvents(dev, sprite.win, fromWin, mode,
+				       NotifyPointer, FALSE);
+		    FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
+		    if (fromWin->parent != NullWindow)
+		      FocusOutEvents(dev, fromWin->parent, common, mode,
+				     NotifyNonlinearVirtual, FALSE);
+		    if (toWin->parent != NullWindow)
+		      (void)FocusInEvents(dev, common, toWin, toWin, mode,
+					  NotifyNonlinearVirtual, FALSE);
+		    FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
+		    if (IsParent(toWin, sprite.win))
+			(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
+					    mode, NotifyPointer, FALSE);
+		}
+	}
+    }
+}
+
+int
+SetInputFocus(
+    ClientPtr client,
+    DeviceIntPtr dev,
+    Window focusID,
+    CARD8 revertTo,
+    Time ctime,
+    Bool followOK)
+{
+    register FocusClassPtr focus;
+    register WindowPtr focusWin;
+    int mode;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((revertTo != RevertToParent) &&
+	(revertTo != RevertToPointerRoot) &&
+	(revertTo != RevertToNone) &&
+	((revertTo != RevertToFollowKeyboard) || !followOK))
+    {
+	client->errorValue = revertTo;
+	return BadValue;
+    }
+    time = ClientTimeToServerTime(ctime);
+    if ((focusID == None) || (focusID == PointerRoot))
+	focusWin = (WindowPtr)(long)focusID;
+    else if ((focusID == FollowKeyboard) && followOK)
+	focusWin = inputInfo.keyboard->focus->win;
+    else if (!(focusWin = SecurityLookupWindow(focusID, client,
+					       SecurityReadAccess)))
+	return BadWindow;
+    else
+    {
+ 	/* It is a match error to try to set the input focus to an 
+	unviewable window. */
+
+	if(!focusWin->realized)
+	    return(BadMatch);
+    }
+    focus = dev->focus;
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	(CompareTimeStamps(time, focus->time) == EARLIER))
+	return Success;
+    mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
+    if (focus->win == FollowKeyboardWin)
+	DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
+    else
+	DoFocusEvents(dev, focus->win, focusWin, mode);
+    focus->time = time;
+    focus->revert = revertTo;
+    if (focusID == FollowKeyboard)
+	focus->win = FollowKeyboardWin;
+    else
+	focus->win = focusWin;
+    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+	focus->traceGood = 0;
+    else
+    {
+        int depth = 0;
+	register WindowPtr pWin;
+
+        for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+        if (depth > focus->traceSize)
+        {
+	    focus->traceSize = depth+1;
+	    Must_have_memory = TRUE; /* XXX */
+	    focus->trace = (WindowPtr *)xrealloc(focus->trace,
+						 focus->traceSize *
+						 sizeof(WindowPtr));
+	    Must_have_memory = FALSE; /* XXX */
+	}
+	focus->traceGood = depth;
+        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
+	    focus->trace[depth] = pWin;
+    }
+    return Success;
+}
+
+int
+ProcSetInputFocus(client)
+    ClientPtr client;
+{
+    REQUEST(xSetInputFocusReq);
+
+    REQUEST_SIZE_MATCH(xSetInputFocusReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+	return Success;
+#endif
+    return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
+			 stuff->revertTo, stuff->time, FALSE);
+}
+
+int
+ProcGetInputFocus(ClientPtr client)
+{
+    xGetInputFocusReply rep;
+    /* REQUEST(xReq); */
+    FocusClassPtr focus = inputInfo.keyboard->focus;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    if (focus->win == NoneWin)
+	rep.focus = None;
+    else if (focus->win == PointerRootWin)
+	rep.focus = PointerRoot;
+    else rep.focus = focus->win->drawable.id;
+    rep.revertTo = focus->revert;
+    WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+    return Success;
+}
+
+int
+ProcGrabPointer(ClientPtr client)
+{
+    xGrabPointerReply rep;
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    WindowPtr pWin, confineTo;
+    CursorPtr cursor, oldCursor;
+    REQUEST(xGrabPointerReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xGrabPointerReq);
+    UpdateCurrentTime();
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+        return BadValue;
+    }
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+	confineTo = NullWindow;
+    else 
+    {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+	/* at this point, some sort of reply is guaranteed. */
+    time = ClientTimeToServerTime(stuff->time);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    grab = device->grab;
+    if ((grab) && !SameClient(grab, client))
+	rep.status = AlreadyGrabbed;
+    else if ((!pWin->realized) ||
+             (confineTo &&
+                !(confineTo->realized && BorderSizeNotEmpty(confineTo))))
+	rep.status = GrabNotViewable;
+    else if (device->sync.frozen &&
+	     device->sync.other && !SameClient(device->sync.other, client))
+	rep.status = GrabFrozen;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	rep.status = GrabInvalidTime;
+    else
+    {
+	GrabRec tempGrab;
+
+	oldCursor = NullCursor;
+	if (grab)
+ 	{
+	    if (grab->confineTo && !confineTo)
+		ConfineCursorToWindow(ROOT, FALSE, FALSE);
+	    oldCursor = grab->cursor;
+	}
+	tempGrab.cursor = cursor;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = stuff->ownerEvents;
+	tempGrab.eventMask = stuff->eventMask;
+	tempGrab.confineTo = confineTo;
+	tempGrab.window = pWin;
+	tempGrab.keyboardMode = stuff->keyboardMode;
+	tempGrab.pointerMode = stuff->pointerMode;
+	tempGrab.device = device;
+	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
+	if (oldCursor)
+	    FreeCursor (oldCursor, (Cursor)0);
+	rep.status = GrabSuccess;
+    }
+    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+    return Success;
+}
+
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    register GrabPtr grab = device->grab;
+    CursorPtr newCursor, oldCursor;
+    REQUEST(xChangeActivePointerGrabReq);
+    TimeStamp time;
+
+    REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    if (stuff->cursor == None)
+	newCursor = NullCursor;
+    else
+    {
+	newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!newCursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+    if (!grab)
+	return Success;
+    if (!SameClient(grab, client))
+	return Success;
+    time = ClientTimeToServerTime(stuff->time);
+    if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, device->grabTime) == EARLIER))
+	return Success;
+    oldCursor = grab->cursor;
+    grab->cursor = newCursor;
+    if (newCursor)
+	newCursor->refcnt++;
+    PostNewCursor();
+    if (oldCursor)
+	FreeCursor(oldCursor, (Cursor)0);
+    grab->eventMask = stuff->eventMask;
+    return Success;
+}
+
+int
+ProcUngrabPointer(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.pointer;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	    (grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+GrabDevice(register ClientPtr client, register DeviceIntPtr dev, 
+           unsigned this_mode, unsigned other_mode, Window grabWindow, 
+           unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status)
+{
+    register WindowPtr pWin;
+    register GrabPtr grab;
+    TimeStamp time;
+
+    UpdateCurrentTime();
+    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+    {
+	client->errorValue = this_mode;
+        return BadValue;
+    }
+    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+    {
+	client->errorValue = other_mode;
+        return BadValue;
+    }
+    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+    {
+	client->errorValue = ownerEvents;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    time = ClientTimeToServerTime(ctime);
+    grab = dev->grab;
+    if (grab && !SameClient(grab, client))
+	*status = AlreadyGrabbed;
+    else if (!pWin->realized)
+	*status = GrabNotViewable;
+    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+	     (CompareTimeStamps(time, dev->grabTime) == EARLIER))
+	*status = GrabInvalidTime;
+    else if (dev->sync.frozen &&
+	     dev->sync.other && !SameClient(dev->sync.other, client))
+	*status = GrabFrozen;
+    else
+    {
+	GrabRec tempGrab;
+
+	tempGrab.window = pWin;
+	tempGrab.resource = client->clientAsMask;
+	tempGrab.ownerEvents = ownerEvents;
+	tempGrab.keyboardMode = this_mode;
+	tempGrab.pointerMode = other_mode;
+	tempGrab.eventMask = mask;
+	tempGrab.device = dev;
+	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
+	*status = GrabSuccess;
+    }
+    return Success;
+}
+
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+    xGrabKeyboardReply rep;
+    REQUEST(xGrabKeyboardReq);
+    int result;
+
+    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+#ifdef XCSECURITY
+    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
+    {
+	result = Success;
+	rep.status = AlreadyGrabbed;
+    }
+    else
+#endif
+    result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
+			stuff->pointerMode, stuff->grabWindow,
+			stuff->ownerEvents, stuff->time,
+			KeyPressMask | KeyReleaseMask, &rep.status);
+    if (result != Success)
+	return result;
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+    return Success;
+}
+
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+    DeviceIntPtr device = inputInfo.keyboard;
+    GrabPtr grab;
+    TimeStamp time;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    UpdateCurrentTime();
+    grab = device->grab;
+    time = ClientTimeToServerTime(stuff->id);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
+	(grab) && SameClient(grab, client))
+	(*device->DeactivateGrab)(device);
+    return Success;
+}
+
+int
+ProcQueryPointer(ClientPtr client)
+{
+    xQueryPointerReply rep;
+    WindowPtr pWin, t;
+    REQUEST(xResourceReq);
+    DeviceIntPtr mouse = inputInfo.pointer;
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (mouse->valuator->motionHintWindow)
+	MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
+    rep.length = 0;
+    rep.root = (ROOT)->drawable.id;
+    rep.rootX = sprite.hot.x;
+    rep.rootY = sprite.hot.y;
+    rep.child = None;
+    if (sprite.hot.pScreen == pWin->drawable.pScreen)
+    {
+	rep.sameScreen = xTrue;
+	rep.winX = sprite.hot.x - pWin->drawable.x;
+	rep.winY = sprite.hot.y - pWin->drawable.y;
+	for (t = sprite.win; t; t = t->parent)
+	    if (t->parent == pWin)
+	    {
+		rep.child = t->drawable.id;
+		break;
+	    }
+    }
+    else
+    {
+	rep.sameScreen = xFalse;
+	rep.winX = 0;
+	rep.winY = 0;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	rep.rootX += panoramiXdataPtr[0].x;
+	rep.rootY += panoramiXdataPtr[0].y;
+	if(stuff->id == rep.root) {
+	    rep.winX += panoramiXdataPtr[0].x;
+	    rep.winY += panoramiXdataPtr[0].y;
+	}
+    }
+#endif
+
+    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+    return(Success);    
+}
+
+void
+InitEvents()
+{
+    int i;
+
+    sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
+    inputInfo.numDevices = 0;
+    inputInfo.devices = (DeviceIntPtr)NULL;
+    inputInfo.off_devices = (DeviceIntPtr)NULL;
+    inputInfo.keyboard = (DeviceIntPtr)NULL;
+    inputInfo.pointer = (DeviceIntPtr)NULL;
+    if (spriteTraceSize == 0)
+    {
+	spriteTraceSize = 32;
+	spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
+	if (!spriteTrace)
+	    FatalError("failed to allocate spriteTrace");
+    }
+    spriteTraceGood = 0;
+    lastEventMask = OwnerGrabButtonMask;
+    filters[MotionNotify] = PointerMotionMask;
+#ifdef XEVIE
+    xeviewin =
+#endif
+    sprite.win = NullWindow;
+    sprite.current = NullCursor;
+    sprite.hotLimits.x1 = 0;
+    sprite.hotLimits.y1 = 0;
+    sprite.hotLimits.x2 = 0;
+    sprite.hotLimits.y2 = 0;
+    sprite.confined = FALSE;
+    syncEvents.replayDev = (DeviceIntPtr)NULL;
+    syncEvents.replayWin = NullWindow;
+    while (syncEvents.pending)
+    {
+	QdEventPtr next = syncEvents.pending->next;
+	xfree(syncEvents.pending);
+	syncEvents.pending = next;
+    }
+    syncEvents.pendtail = &syncEvents.pending;
+    syncEvents.playingEvents = FALSE;
+    syncEvents.time.months = 0;
+    syncEvents.time.milliseconds = 0;	/* hardly matters */
+    currentTime.months = 0;
+    currentTime.milliseconds = GetTimeInMillis();
+    lastDeviceEventTime = currentTime;
+    for (i = 0; i < DNPMCOUNT; i++)
+    {
+	DontPropagateMasks[i] = 0;
+	DontPropagateRefCnts[i] = 0;
+    }
+}
+
+void
+CloseDownEvents(void)
+{
+  xfree(spriteTrace);
+  spriteTrace = NULL;
+  spriteTraceSize = 0;
+}
+
+int
+ProcSendEvent(ClientPtr client)
+{
+    WindowPtr pWin;
+    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+    REQUEST(xSendEventReq);
+
+    REQUEST_SIZE_MATCH(xSendEventReq);
+
+    /* The client's event type must be a core event type or one defined by an
+	extension. */
+
+    if ( ! ((stuff->event.u.u.type > X_Reply &&
+	     stuff->event.u.u.type < LASTEvent) || 
+	    (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+	     stuff->event.u.u.type < (unsigned)lastEvent)))
+    {
+	client->errorValue = stuff->event.u.u.type;
+	return BadValue;
+    }
+    if (stuff->event.u.u.type == ClientMessage &&
+	stuff->event.u.u.detail != 8 &&
+	stuff->event.u.u.detail != 16 &&
+	stuff->event.u.u.detail != 32 &&
+	!permitOldBugs)
+    {
+	client->errorValue = stuff->event.u.u.detail;
+	return BadValue;
+    }
+    if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
+    {
+	client->errorValue = stuff->eventMask;
+	return BadValue;
+    }
+
+    if (stuff->destination == PointerWindow)
+	pWin = sprite.win;
+    else if (stuff->destination == InputFocus)
+    {
+	WindowPtr inputFocus = inputInfo.keyboard->focus->win;
+
+	if (inputFocus == NoneWin)
+	    return Success;
+
+	/* If the input focus is PointerRootWin, send the event to where
+	the pointer is if possible, then perhaps propogate up to root. */
+   	if (inputFocus == PointerRootWin)
+	    inputFocus = ROOT;
+
+	if (IsParent(inputFocus, sprite.win))
+	{
+	    effectiveFocus = inputFocus;
+	    pWin = sprite.win;
+	}
+	else
+	    effectiveFocus = pWin = inputFocus;
+    }
+    else
+	pWin = SecurityLookupWindow(stuff->destination, client,
+				    SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+    {
+	client->errorValue = stuff->propagate;
+	return BadValue;
+    }
+    stuff->event.u.u.type |= 0x80;
+    if (stuff->propagate)
+    {
+	for (;pWin; pWin = pWin->parent)
+	{
+	    if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				      NullGrab, 0))
+		return Success;
+	    if (pWin == effectiveFocus)
+		return Success;
+	    stuff->eventMask &= ~wDontPropagateMask(pWin);
+	    if (!stuff->eventMask)
+		break;
+	}
+    }
+    else
+	(void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
+				    NullGrab, 0);
+    return Success;
+}
+
+int
+ProcUngrabKey(ClientPtr client)
+{
+    REQUEST(xUngrabKeyReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xUngrabKeyReq);
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = keybd;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = KeyPress;
+    tempGrab.detail.exact = stuff->key;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+int
+ProcGrabKey(ClientPtr client)
+{
+    WindowPtr pWin;
+    REQUEST(xGrabKeyReq);
+    GrabPtr grab;
+    DeviceIntPtr keybd = inputInfo.keyboard;
+
+    REQUEST_SIZE_MATCH(xGrabKeyReq);
+    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return(BadValue);
+    }
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
+	 (stuff->key < keybd->key->curKeySyms.minKeyCode))
+	&& (stuff->key != AnyKey))
+    {
+	client->errorValue = stuff->key;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    grab = CreateGrab(client->index, keybd, pWin, 
+	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
+	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
+	keybd, stuff->modifiers, KeyPress, stuff->key, 
+	NullWindow, NullCursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+
+int
+ProcGrabButton(ClientPtr client)
+{
+    WindowPtr pWin, confineTo;
+    REQUEST(xGrabButtonReq);
+    CursorPtr cursor;
+    GrabPtr grab;
+
+    REQUEST_SIZE_MATCH(xGrabButtonReq);
+    if ((stuff->pointerMode != GrabModeSync) &&
+	(stuff->pointerMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->pointerMode;
+        return BadValue;
+    }
+    if ((stuff->keyboardMode != GrabModeSync) &&
+	(stuff->keyboardMode != GrabModeAsync))
+    {
+	client->errorValue = stuff->keyboardMode;
+        return BadValue;
+    }
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+    {
+	client->errorValue = stuff->ownerEvents;
+	return BadValue;
+    }
+    if (stuff->eventMask & ~PointerGrabMask)
+    {
+	client->errorValue = stuff->eventMask;
+        return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    if (stuff->confineTo == None)
+       confineTo = NullWindow;
+    else {
+	confineTo = SecurityLookupWindow(stuff->confineTo, client,
+					 SecurityReadAccess);
+	if (!confineTo)
+	    return BadWindow;
+    }
+    if (stuff->cursor == None)
+	cursor = NullCursor;
+    else
+    {
+	cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+						RT_CURSOR, SecurityReadAccess);
+	if (!cursor)
+	{
+	    client->errorValue = stuff->cursor;
+	    return BadCursor;
+	}
+    }
+
+
+    grab = CreateGrab(client->index, inputInfo.pointer, pWin, 
+    permitOldBugs ? (Mask)(stuff->eventMask |
+			       ButtonPressMask | ButtonReleaseMask) :
+			(Mask)stuff->eventMask,
+	(Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
+	(Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
+	ButtonPress, stuff->button, confineTo, cursor);
+    if (!grab)
+	return BadAlloc;
+    return AddPassiveGrabToList(grab);
+}
+
+int
+ProcUngrabButton(ClientPtr client)
+{
+    REQUEST(xUngrabButtonReq);
+    WindowPtr pWin;
+    GrabRec tempGrab;
+
+    REQUEST_SIZE_MATCH(xUngrabButtonReq);
+    if ((stuff->modifiers != AnyModifier) &&
+	(stuff->modifiers & ~AllModifiersMask))
+    {
+	client->errorValue = stuff->modifiers;
+	return BadValue;
+    }
+    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = inputInfo.pointer;
+    tempGrab.window = pWin;
+    tempGrab.modifiersDetail.exact = stuff->modifiers;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.modifierDevice = inputInfo.keyboard;
+    tempGrab.type = ButtonPress;
+    tempGrab.detail.exact = stuff->button;
+    tempGrab.detail.pMask = NULL;
+
+    if (!DeletePassiveGrabFromList(&tempGrab))
+	return(BadAlloc);
+    return(Success);
+}
+
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+    WindowPtr		parent;
+    DeviceIntPtr	mouse = inputInfo.pointer;
+    DeviceIntPtr	keybd = inputInfo.keyboard;
+    FocusClassPtr	focus = keybd->focus;
+    OtherClientsPtr	oc;
+    GrabPtr		passive;
+
+
+    /* Deactivate any grabs performed on this window, before making any
+	input focus changes. */
+
+    if (mouse->grab &&
+	((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
+	(*mouse->DeactivateGrab)(mouse);
+
+    /* Deactivating a keyboard grab should cause focus events. */
+
+    if (keybd->grab && (keybd->grab->window == pWin))
+	(*keybd->DeactivateGrab)(keybd);
+
+    /* If the focus window is a root window (ie. has no parent) then don't 
+	delete the focus from it. */
+    
+    if ((pWin == focus->win) && (pWin->parent != NullWindow))
+    {
+	int focusEventMode = NotifyNormal;
+
+ 	/* If a grab is in progress, then alter the mode of focus events. */
+
+	if (keybd->grab)
+	    focusEventMode = NotifyWhileGrabbed;
+
+	switch (focus->revert)
+	{
+	case RevertToNone:
+	    DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+	    focus->win = NoneWin;
+	    focus->traceGood = 0;
+	    break;
+	case RevertToParent:
+	    parent = pWin;
+	    do
+	    {
+		parent = parent->parent;
+		focus->traceGood--;
+	    } while (!parent->realized
+/* This would be a good protocol change -- windows being reparented
+   during SaveSet processing would cause the focus to revert to the
+   nearest enclosing window which will survive the death of the exiting
+   client, instead of ending up reverting to a dying window and thence
+   to None
+ */
+#ifdef NOTDEF
+ 	      || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+#endif
+		);
+	    DoFocusEvents(keybd, pWin, parent, focusEventMode);
+	    focus->win = parent;
+	    focus->revert = RevertToNone;
+	    break;
+	case RevertToPointerRoot:
+	    DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+	    focus->win = PointerRootWin;
+	    focus->traceGood = 0;
+	    break;
+	}
+    }
+
+    if (mouse->valuator->motionHintWindow == pWin)
+	mouse->valuator->motionHintWindow = NullWindow;
+
+    if (freeResources)
+    {
+	if (pWin->dontPropagate)
+	    DontPropagateRefCnts[pWin->dontPropagate]--;
+	while ( (oc = wOtherClients(pWin)) )
+	    FreeResource(oc->resource, RT_NONE);
+	while ( (passive = wPassiveGrabs(pWin)) )
+	    FreeResource(passive->resource, RT_NONE);
+     }
+#ifdef XINPUT
+    DeleteWindowFromAnyExtEvents(pWin, freeResources);
+#endif
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry 
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+    GrabPtr grab = inputInfo.pointer->grab;
+    WindowPtr confineTo;
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+    if (grab && (confineTo = grab->confineTo))
+    {
+	if (!BorderSizeNotEmpty(confineTo))
+	    (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
+	else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+	    ConfineCursorToWindow(confineTo, TRUE, TRUE);
+    }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+    register OtherClientsPtr	other;
+
+    if (wClient (pWin) == client)
+	return pWin->eventMask;
+    for (other = wOtherClients(pWin); other; other = other->next)
+    {
+	if (SameClient(other, client))
+	    return other->mask;
+    }
+    return 0;
+}
+
+int
+ProcRecolorCursor(ClientPtr client)
+{
+    CursorPtr pCursor;
+    int		nscr;
+    ScreenPtr	pscr;
+    Bool 	displayed;
+    REQUEST(xRecolorCursorReq);
+
+    REQUEST_SIZE_MATCH(xRecolorCursorReq);
+    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
+					RT_CURSOR, SecurityWriteAccess);
+    if ( !pCursor) 
+    {
+	client->errorValue = stuff->cursor;
+	return (BadCursor);
+    }
+
+    pCursor->foreRed = stuff->foreRed;
+    pCursor->foreGreen = stuff->foreGreen;
+    pCursor->foreBlue = stuff->foreBlue;
+
+    pCursor->backRed = stuff->backRed;
+    pCursor->backGreen = stuff->backGreen;
+    pCursor->backBlue = stuff->backBlue;
+
+    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+    {
+	pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension)
+	    displayed = (pscr == sprite.screen);
+	else
+#endif
+	    displayed = (pscr == sprite.hotPhys.pScreen);
+	( *pscr->RecolorCursor)(pscr, pCursor,
+				(pCursor == sprite.current) && displayed);
+    }
+    return (Success);
+}
+
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+    xEvent    eventCopy;
+#endif
+    xEvent    eventTo, *eventFrom;
+    int       i;
+
+#ifdef XKB
+    if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
+	return;
+#endif
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && 
+       (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 
+    {
+	switch(events->u.u.type) {
+	case MotionNotify:
+	case ButtonPress:
+	case ButtonRelease:
+	case KeyPress:
+	case KeyRelease:
+	case EnterNotify:
+	case LeaveNotify:
+	/* 
+	   When multiple clients want the same event DeliverEventsToWindow
+	   passes the same event structure multiple times so we can't 
+	   modify the one passed to us 
+        */
+	    count = 1;  /* should always be 1 */
+	    memcpy(&eventCopy, events, sizeof(xEvent));
+	    eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+	    eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+	    if(eventCopy.u.keyButtonPointer.event == 
+	       eventCopy.u.keyButtonPointer.root) 
+	    {
+		eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+		eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+	    }
+	    events = &eventCopy;
+	    break;
+	default: break;
+	}
+    }
+#endif
+
+    if (EventCallback)
+    {
+	EventInfoRec eventinfo;
+	eventinfo.client = pClient;
+	eventinfo.events = events;
+	eventinfo.count = count;
+	CallCallbacks(&EventCallback, (pointer)&eventinfo);
+    }
+    if(pClient->swapped)
+    {
+	for(i = 0; i < count; i++)
+	{
+	    eventFrom = &events[i];
+	    /* Remember to strip off the leading bit of type in case
+	       this event was sent with "SendEvent." */
+	    (*EventSwapVector[eventFrom->u.u.type & 0177])
+		(eventFrom, &eventTo);
+	    (void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
+	}
+    }
+    else
+    {
+	(void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
new file mode 100644
index 000000000..a510c9356
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
@@ -0,0 +1,508 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "../../dix/dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#include "Trap.h"
+
+#define EXTENSION_BASE  128
+#define EXTENSION_EVENT_BASE  64
+#define LAST_EVENT  128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors, 
+	     int (*MainProc)(ClientPtr c1), 
+	     int (*SwappedMainProc)(ClientPtr c2), 
+	     void (*CloseDownProc)(ExtensionEntry *e), 
+	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+    int i;
+    register ExtensionEntry *ext, **newexts;
+
+    if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+        return((ExtensionEntry *) NULL);
+    if ((lastEvent + NumEvents > LAST_EVENT) || 
+	        (unsigned)(lastError + NumErrors > LAST_ERROR))
+        return((ExtensionEntry *) NULL);
+
+    ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+    if (!ext)
+	return((ExtensionEntry *) NULL);
+    ext->name = (char *)xalloc(strlen(name) + 1);
+    ext->num_aliases = 0;
+    ext->aliases = (char **)NULL;
+    if (!ext->name)
+    {
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    strcpy(ext->name,  name);
+    i = NumExtensions;
+    newexts = (ExtensionEntry **) xrealloc(extensions,
+					   (i + 1) * sizeof(ExtensionEntry *));
+    if (!newexts)
+    {
+	xfree(ext->name);
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    NumExtensions++;
+    extensions = newexts;
+    extensions[i] = ext;
+    ext->index = i;
+    ext->base = i + EXTENSION_BASE;
+    ext->CloseDown = CloseDownProc;
+    ext->MinorOpcode = MinorOpcodeProc;
+    ProcVector[i + EXTENSION_BASE] = MainProc;
+    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+    if (NumEvents)
+    {
+        ext->eventBase = lastEvent;
+	ext->eventLast = lastEvent + NumEvents;
+	lastEvent += NumEvents;
+    }
+    else
+    {
+        ext->eventBase = 0;
+        ext->eventLast = 0;
+    }
+    if (NumErrors)
+    {
+        ext->errorBase = lastError;
+	ext->errorLast = lastError + NumErrors;
+	lastError += NumErrors;
+    }
+    else
+    {
+        ext->errorBase = 0;
+        ext->errorLast = 0;
+    }
+#ifdef XCSECURITY
+    ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+    (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+    return(ext);
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+    char *name;
+    char **aliases;
+
+    aliases = (char **)xrealloc(ext->aliases,
+				(ext->num_aliases + 1) * sizeof(char *));
+    if (!aliases)
+	return FALSE;
+    ext->aliases = aliases;
+    name = (char *)xalloc(strlen(alias) + 1);
+    if (!name)
+	return FALSE;
+    strcpy(name,  alias);
+    ext->aliases[ext->num_aliases] = name;
+    ext->num_aliases++;
+#ifdef LBX
+    return LbxAddExtensionAlias(ext->index, alias);
+#else
+    return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+    int i, j;
+
+    for (i=0; i<NumExtensions; i++)
+    {
+	if ((strlen(extensions[i]->name) == len) &&
+	    !strncmp(extname, extensions[i]->name, len))
+	    break;
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	{
+	    if ((strlen(extensions[i]->aliases[j]) == len) &&
+		!strncmp(extname, extensions[i]->aliases[j], len))
+		break;
+	}
+	if (j >= 0) break;
+    }
+    return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name.  Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+    int n;
+
+    n = FindExtension((char*)extname, strlen(extname));
+    if (n != -1)
+	return extensions[n];
+    else
+	return NULL;
+}
+
+void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XCSECURITY
+    int i = FindExtension(extname, strlen(extname));
+    if (i >= 0)
+    {
+	int majorop = extensions[i]->base;
+	extensions[i]->secure = secure;
+	if (secure)
+	{
+	    UntrustedProcVector[majorop] = ProcVector[majorop];
+	    SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+	}
+	else
+	{
+	    UntrustedProcVector[majorop]	= ProcBadRequest;
+	    SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+	}
+    }
+#endif
+#ifdef LBX
+    LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+    return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+    unsigned char major;
+
+    major = ((xReq *)client->requestBuffer)->reqType;
+    if (major < EXTENSION_BASE)
+	return 0;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return 0;
+    return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+    register int i,j;
+
+#ifdef LBX
+    LbxCloseDownExtensions();
+#endif
+
+    for (i = NumExtensions - 1; i >= 0; i--)
+    {
+	(* extensions[i]->CloseDown)(extensions[i]);
+	NumExtensions = i;
+	xfree(extensions[i]->name);
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	    xfree(extensions[i]->aliases[j]);
+	xfree(extensions[i]->aliases);
+	xfree(extensions[i]);
+    }
+    xfree(extensions);
+    extensions = (ExtensionEntry **)NULL;
+    lastEvent = EXTENSION_EVENT_BASE;
+    lastError = FirstExtensionError;
+    for (i=0; i<MAXSCREENS; i++)
+    {
+	register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+	while (spentry->num)
+	{
+	    spentry->num--;
+	    xfree(spentry->procList[spentry->num].name);
+	}
+	xfree(spentry->procList);
+	spentry->procList = (ProcEntryPtr)NULL;
+    }
+}
+
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+    xQueryExtensionReply reply;
+    int i;
+    REQUEST(xQueryExtensionReq);
+
+    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+    
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.major_opcode = 0;
+    reply.sequenceNumber = client->sequence;
+
+    if ( ! NumExtensions )
+        reply.present = xFalse;
+    else
+    {
+	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+        if (i < 0
+
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    || (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+#endif
+	    )
+            reply.present = xFalse;
+        else
+        {            
+            reply.present = xTrue;
+	    reply.major_opcode = extensions[i]->base;
+	    reply.first_event = extensions[i]->eventBase;
+	    reply.first_error = extensions[i]->errorBase;
+	}
+    }
+    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+    xListExtensionsReply reply;
+    char *bufptr, *buffer;
+    int total_length = 0;
+
+    REQUEST_SIZE_MATCH(xReq);
+
+    reply.type = X_Reply;
+    reply.nExtensions = 0;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    buffer = NULL;
+
+    if ( NumExtensions )
+    {
+        register int i, j;
+
+        for (i=0;  i<NumExtensions; i++)
+	{
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+                continue;
+
+	    total_length += strlen(extensions[i]->name) + 1;
+	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+		total_length += strlen(extensions[i]->aliases[j]) + 1;
+	}
+        reply.length = (total_length + 3) >> 2;
+	buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+	if (!buffer)
+	    return(BadAlloc);
+        for (i=0;  i<NumExtensions; i++)
+        {
+	    int len;
+#ifdef XCSECURITY
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            *bufptr++ = len = strlen(extensions[i]->name);
+	    memmove(bufptr, extensions[i]->name,  len);
+	    bufptr += len;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+	    {
+		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
+		memmove(bufptr, extensions[i]->aliases[j],  len);
+		bufptr += len;
+	    }
+	}
+    }
+    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+    if (reply.length)
+    {
+        WriteToClient(client, total_length, buffer);
+    	DEALLOCATE_LOCAL(buffer);
+    }
+    return(client->noClientException);
+}
+
+
+ExtensionLookupProc 
+LookupProc(char *name, GCPtr pGC)
+{
+    register int i;
+    register ScreenProcEntry *spentry;
+    spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+    if (spentry->num)    
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+                return(spentry->procList[i].proc);
+    }
+    return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+    return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+    register ScreenProcEntry *spentry;
+    register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+    char *newname;
+    int i;
+
+    spentry = &AuxillaryScreenProcs[pScreen->myNum];
+    /* first replace duplicates */
+    if (spentry->num)
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+	    {
+                procEntry = &spentry->procList[i];
+		break;
+	    }
+    }
+    if (procEntry)
+        procEntry->proc = proc;
+    else
+    {
+	newname = (char *)xalloc(strlen(name)+1);
+	if (!newname)
+	    return FALSE;
+	procEntry = (ProcEntryPtr)
+			    xrealloc(spentry->procList,
+				     sizeof(ProcEntryRec) * (spentry->num+1));
+	if (!procEntry)
+	{
+	    xfree(newname);
+	    return FALSE;
+	}
+	spentry->procList = procEntry;
+        procEntry += spentry->num;
+        procEntry->name = newname;
+        strcpy(newname, name);
+        procEntry->proc = proc;
+        spentry->num++;        
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
new file mode 100644
index 000000000..a510c9356
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
@@ -0,0 +1,508 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "../../dix/dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#include "Trap.h"
+
+#define EXTENSION_BASE  128
+#define EXTENSION_EVENT_BASE  64
+#define LAST_EVENT  128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors, 
+	     int (*MainProc)(ClientPtr c1), 
+	     int (*SwappedMainProc)(ClientPtr c2), 
+	     void (*CloseDownProc)(ExtensionEntry *e), 
+	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+    int i;
+    register ExtensionEntry *ext, **newexts;
+
+    if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+        return((ExtensionEntry *) NULL);
+    if ((lastEvent + NumEvents > LAST_EVENT) || 
+	        (unsigned)(lastError + NumErrors > LAST_ERROR))
+        return((ExtensionEntry *) NULL);
+
+    ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+    if (!ext)
+	return((ExtensionEntry *) NULL);
+    ext->name = (char *)xalloc(strlen(name) + 1);
+    ext->num_aliases = 0;
+    ext->aliases = (char **)NULL;
+    if (!ext->name)
+    {
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    strcpy(ext->name,  name);
+    i = NumExtensions;
+    newexts = (ExtensionEntry **) xrealloc(extensions,
+					   (i + 1) * sizeof(ExtensionEntry *));
+    if (!newexts)
+    {
+	xfree(ext->name);
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    NumExtensions++;
+    extensions = newexts;
+    extensions[i] = ext;
+    ext->index = i;
+    ext->base = i + EXTENSION_BASE;
+    ext->CloseDown = CloseDownProc;
+    ext->MinorOpcode = MinorOpcodeProc;
+    ProcVector[i + EXTENSION_BASE] = MainProc;
+    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+    if (NumEvents)
+    {
+        ext->eventBase = lastEvent;
+	ext->eventLast = lastEvent + NumEvents;
+	lastEvent += NumEvents;
+    }
+    else
+    {
+        ext->eventBase = 0;
+        ext->eventLast = 0;
+    }
+    if (NumErrors)
+    {
+        ext->errorBase = lastError;
+	ext->errorLast = lastError + NumErrors;
+	lastError += NumErrors;
+    }
+    else
+    {
+        ext->errorBase = 0;
+        ext->errorLast = 0;
+    }
+#ifdef XCSECURITY
+    ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+    (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+    return(ext);
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+    char *name;
+    char **aliases;
+
+    aliases = (char **)xrealloc(ext->aliases,
+				(ext->num_aliases + 1) * sizeof(char *));
+    if (!aliases)
+	return FALSE;
+    ext->aliases = aliases;
+    name = (char *)xalloc(strlen(alias) + 1);
+    if (!name)
+	return FALSE;
+    strcpy(name,  alias);
+    ext->aliases[ext->num_aliases] = name;
+    ext->num_aliases++;
+#ifdef LBX
+    return LbxAddExtensionAlias(ext->index, alias);
+#else
+    return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+    int i, j;
+
+    for (i=0; i<NumExtensions; i++)
+    {
+	if ((strlen(extensions[i]->name) == len) &&
+	    !strncmp(extname, extensions[i]->name, len))
+	    break;
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	{
+	    if ((strlen(extensions[i]->aliases[j]) == len) &&
+		!strncmp(extname, extensions[i]->aliases[j], len))
+		break;
+	}
+	if (j >= 0) break;
+    }
+    return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name.  Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+    int n;
+
+    n = FindExtension((char*)extname, strlen(extname));
+    if (n != -1)
+	return extensions[n];
+    else
+	return NULL;
+}
+
+void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XCSECURITY
+    int i = FindExtension(extname, strlen(extname));
+    if (i >= 0)
+    {
+	int majorop = extensions[i]->base;
+	extensions[i]->secure = secure;
+	if (secure)
+	{
+	    UntrustedProcVector[majorop] = ProcVector[majorop];
+	    SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+	}
+	else
+	{
+	    UntrustedProcVector[majorop]	= ProcBadRequest;
+	    SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+	}
+    }
+#endif
+#ifdef LBX
+    LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+    return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+    unsigned char major;
+
+    major = ((xReq *)client->requestBuffer)->reqType;
+    if (major < EXTENSION_BASE)
+	return 0;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return 0;
+    return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+    register int i,j;
+
+#ifdef LBX
+    LbxCloseDownExtensions();
+#endif
+
+    for (i = NumExtensions - 1; i >= 0; i--)
+    {
+	(* extensions[i]->CloseDown)(extensions[i]);
+	NumExtensions = i;
+	xfree(extensions[i]->name);
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	    xfree(extensions[i]->aliases[j]);
+	xfree(extensions[i]->aliases);
+	xfree(extensions[i]);
+    }
+    xfree(extensions);
+    extensions = (ExtensionEntry **)NULL;
+    lastEvent = EXTENSION_EVENT_BASE;
+    lastError = FirstExtensionError;
+    for (i=0; i<MAXSCREENS; i++)
+    {
+	register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+	while (spentry->num)
+	{
+	    spentry->num--;
+	    xfree(spentry->procList[spentry->num].name);
+	}
+	xfree(spentry->procList);
+	spentry->procList = (ProcEntryPtr)NULL;
+    }
+}
+
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+    xQueryExtensionReply reply;
+    int i;
+    REQUEST(xQueryExtensionReq);
+
+    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+    
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.major_opcode = 0;
+    reply.sequenceNumber = client->sequence;
+
+    if ( ! NumExtensions )
+        reply.present = xFalse;
+    else
+    {
+	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+        if (i < 0
+
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            || (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    || (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+#endif
+	    )
+            reply.present = xFalse;
+        else
+        {            
+            reply.present = xTrue;
+	    reply.major_opcode = extensions[i]->base;
+	    reply.first_event = extensions[i]->eventBase;
+	    reply.first_error = extensions[i]->errorBase;
+	}
+    }
+    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+    xListExtensionsReply reply;
+    char *bufptr, *buffer;
+    int total_length = 0;
+
+    REQUEST_SIZE_MATCH(xReq);
+
+    reply.type = X_Reply;
+    reply.nExtensions = 0;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    buffer = NULL;
+
+    if ( NumExtensions )
+    {
+        register int i, j;
+
+        for (i=0;  i<NumExtensions; i++)
+	{
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            /*
+             * Hide RENDER if our implementation
+             * is faulty.
+             */
+
+            if (nxagentRenderTrap && strcmp(extensions[i]->name, "RENDER") == 0)
+                continue;
+
+	    total_length += strlen(extensions[i]->name) + 1;
+	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+		total_length += strlen(extensions[i]->aliases[j]) + 1;
+	}
+        reply.length = (total_length + 3) >> 2;
+	buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+	if (!buffer)
+	    return(BadAlloc);
+        for (i=0;  i<NumExtensions; i++)
+        {
+	    int len;
+#ifdef XCSECURITY
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            *bufptr++ = len = strlen(extensions[i]->name);
+	    memmove(bufptr, extensions[i]->name,  len);
+	    bufptr += len;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+	    {
+		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
+		memmove(bufptr, extensions[i]->aliases[j],  len);
+		bufptr += len;
+	    }
+	}
+    }
+    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+    if (reply.length)
+    {
+        WriteToClient(client, total_length, buffer);
+    	DEALLOCATE_LOCAL(buffer);
+    }
+    return(client->noClientException);
+}
+
+
+ExtensionLookupProc 
+LookupProc(char *name, GCPtr pGC)
+{
+    register int i;
+    register ScreenProcEntry *spentry;
+    spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+    if (spentry->num)    
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+                return(spentry->procList[i].proc);
+    }
+    return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+    return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+    register ScreenProcEntry *spentry;
+    register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+    char *newname;
+    int i;
+
+    spentry = &AuxillaryScreenProcs[pScreen->myNum];
+    /* first replace duplicates */
+    if (spentry->num)
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+	    {
+                procEntry = &spentry->procList[i];
+		break;
+	    }
+    }
+    if (procEntry)
+        procEntry->proc = proc;
+    else
+    {
+	newname = (char *)xalloc(strlen(name)+1);
+	if (!newname)
+	    return FALSE;
+	procEntry = (ProcEntryPtr)
+			    xrealloc(spentry->procList,
+				     sizeof(ProcEntryRec) * (spentry->num+1));
+	if (!procEntry)
+	{
+	    xfree(newname);
+	    return FALSE;
+	}
+	spentry->procList = procEntry;
+        procEntry += spentry->num;
+        procEntry->name = newname;
+        strcpy(newname, name);
+        procEntry->proc = proc;
+        spentry->num++;        
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original
new file mode 100644
index 000000000..270d54f9b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.X.original
@@ -0,0 +1,474 @@
+/* $XFree86: xc/programs/Xserver/dix/extension.c,v 3.11 2001/12/14 19:59:31 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: extension.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "dispatch.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#define EXTENSION_BASE  128
+#define EXTENSION_EVENT_BASE  64
+#define LAST_EVENT  128
+#define LAST_ERROR 255
+
+ScreenProcEntry AuxillaryScreenProcs[MAXSCREENS];
+
+static ExtensionEntry **extensions = (ExtensionEntry **)NULL;
+
+int lastEvent = EXTENSION_EVENT_BASE;
+static int lastError = FirstExtensionError;
+static unsigned int NumExtensions = 0;
+
+ExtensionEntry *
+AddExtension(char *name, int NumEvents, int NumErrors, 
+	     int (*MainProc)(ClientPtr c1), 
+	     int (*SwappedMainProc)(ClientPtr c2), 
+	     void (*CloseDownProc)(ExtensionEntry *e), 
+	     unsigned short (*MinorOpcodeProc)(ClientPtr c3))
+{
+    int i;
+    register ExtensionEntry *ext, **newexts;
+
+    if (!MainProc || !SwappedMainProc || !CloseDownProc || !MinorOpcodeProc)
+        return((ExtensionEntry *) NULL);
+    if ((lastEvent + NumEvents > LAST_EVENT) || 
+	        (unsigned)(lastError + NumErrors > LAST_ERROR))
+        return((ExtensionEntry *) NULL);
+
+    ext = (ExtensionEntry *) xalloc(sizeof(ExtensionEntry));
+    if (!ext)
+	return((ExtensionEntry *) NULL);
+    ext->name = (char *)xalloc(strlen(name) + 1);
+    ext->num_aliases = 0;
+    ext->aliases = (char **)NULL;
+    if (!ext->name)
+    {
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    strcpy(ext->name,  name);
+    i = NumExtensions;
+    newexts = (ExtensionEntry **) xrealloc(extensions,
+					   (i + 1) * sizeof(ExtensionEntry *));
+    if (!newexts)
+    {
+	xfree(ext->name);
+	xfree(ext);
+	return((ExtensionEntry *) NULL);
+    }
+    NumExtensions++;
+    extensions = newexts;
+    extensions[i] = ext;
+    ext->index = i;
+    ext->base = i + EXTENSION_BASE;
+    ext->CloseDown = CloseDownProc;
+    ext->MinorOpcode = MinorOpcodeProc;
+    ProcVector[i + EXTENSION_BASE] = MainProc;
+    SwappedProcVector[i + EXTENSION_BASE] = SwappedMainProc;
+    if (NumEvents)
+    {
+        ext->eventBase = lastEvent;
+	ext->eventLast = lastEvent + NumEvents;
+	lastEvent += NumEvents;
+    }
+    else
+    {
+        ext->eventBase = 0;
+        ext->eventLast = 0;
+    }
+    if (NumErrors)
+    {
+        ext->errorBase = lastError;
+	ext->errorLast = lastError + NumErrors;
+	lastError += NumErrors;
+    }
+    else
+    {
+        ext->errorBase = 0;
+        ext->errorLast = 0;
+    }
+#ifdef XCSECURITY
+    ext->secure = FALSE;
+#endif
+
+#ifdef LBX
+    (void) LbxAddExtension(name, ext->base, ext->eventBase, ext->errorBase);
+#endif
+    return(ext);
+}
+
+Bool AddExtensionAlias(char *alias, ExtensionEntry *ext)
+{
+    char *name;
+    char **aliases;
+
+    aliases = (char **)xrealloc(ext->aliases,
+				(ext->num_aliases + 1) * sizeof(char *));
+    if (!aliases)
+	return FALSE;
+    ext->aliases = aliases;
+    name = (char *)xalloc(strlen(alias) + 1);
+    if (!name)
+	return FALSE;
+    strcpy(name,  alias);
+    ext->aliases[ext->num_aliases] = name;
+    ext->num_aliases++;
+#ifdef LBX
+    return LbxAddExtensionAlias(ext->index, alias);
+#else
+    return TRUE;
+#endif
+}
+
+static int
+FindExtension(char *extname, int len)
+{
+    int i, j;
+
+    for (i=0; i<NumExtensions; i++)
+    {
+	if ((strlen(extensions[i]->name) == len) &&
+	    !strncmp(extname, extensions[i]->name, len))
+	    break;
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	{
+	    if ((strlen(extensions[i]->aliases[j]) == len) &&
+		!strncmp(extname, extensions[i]->aliases[j], len))
+		break;
+	}
+	if (j >= 0) break;
+    }
+    return ((i == NumExtensions) ? -1 : i);
+}
+
+/*
+ * CheckExtension returns the extensions[] entry for the requested
+ * extension name.  Maybe this could just return a Bool instead?
+ */
+ExtensionEntry *
+CheckExtension(const char *extname)
+{
+    int n;
+
+    n = FindExtension((char*)extname, strlen(extname));
+    if (n != -1)
+	return extensions[n];
+    else
+	return NULL;
+}
+
+void
+DeclareExtensionSecurity(char *extname, Bool secure)
+{
+#ifdef XCSECURITY
+    int i = FindExtension(extname, strlen(extname));
+    if (i >= 0)
+    {
+	int majorop = extensions[i]->base;
+	extensions[i]->secure = secure;
+	if (secure)
+	{
+	    UntrustedProcVector[majorop] = ProcVector[majorop];
+	    SwappedUntrustedProcVector[majorop] = SwappedProcVector[majorop];
+	}
+	else
+	{
+	    UntrustedProcVector[majorop]	= ProcBadRequest;
+	    SwappedUntrustedProcVector[majorop] = ProcBadRequest;
+	}
+    }
+#endif
+#ifdef LBX
+    LbxDeclareExtensionSecurity(extname, secure);
+#endif
+}
+
+unsigned short
+StandardMinorOpcode(ClientPtr client)
+{
+    return ((xReq *)client->requestBuffer)->data;
+}
+
+unsigned short
+MinorOpcodeOfRequest(ClientPtr client)
+{
+    unsigned char major;
+
+    major = ((xReq *)client->requestBuffer)->reqType;
+    if (major < EXTENSION_BASE)
+	return 0;
+    major -= EXTENSION_BASE;
+    if (major >= NumExtensions)
+	return 0;
+    return (*extensions[major]->MinorOpcode)(client);
+}
+
+void
+CloseDownExtensions()
+{
+    register int i,j;
+
+#ifdef LBX
+    LbxCloseDownExtensions();
+#endif
+
+    for (i = NumExtensions - 1; i >= 0; i--)
+    {
+	(* extensions[i]->CloseDown)(extensions[i]);
+	NumExtensions = i;
+	xfree(extensions[i]->name);
+	for (j = extensions[i]->num_aliases; --j >= 0;)
+	    xfree(extensions[i]->aliases[j]);
+	xfree(extensions[i]->aliases);
+	xfree(extensions[i]);
+    }
+    xfree(extensions);
+    extensions = (ExtensionEntry **)NULL;
+    lastEvent = EXTENSION_EVENT_BASE;
+    lastError = FirstExtensionError;
+    for (i=0; i<MAXSCREENS; i++)
+    {
+	register ScreenProcEntry *spentry = &AuxillaryScreenProcs[i];
+
+	while (spentry->num)
+	{
+	    spentry->num--;
+	    xfree(spentry->procList[spentry->num].name);
+	}
+	xfree(spentry->procList);
+	spentry->procList = (ProcEntryPtr)NULL;
+    }
+}
+
+
+int
+ProcQueryExtension(ClientPtr client)
+{
+    xQueryExtensionReply reply;
+    int i;
+    REQUEST(xQueryExtensionReq);
+
+    REQUEST_FIXED_SIZE(xQueryExtensionReq, stuff->nbytes);
+    
+    reply.type = X_Reply;
+    reply.length = 0;
+    reply.major_opcode = 0;
+    reply.sequenceNumber = client->sequence;
+
+    if ( ! NumExtensions )
+        reply.present = xFalse;
+    else
+    {
+	i = FindExtension((char *)&stuff[1], stuff->nbytes);
+        if (i < 0
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    || (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+#endif
+	    )
+            reply.present = xFalse;
+        else
+        {            
+            reply.present = xTrue;
+	    reply.major_opcode = extensions[i]->base;
+	    reply.first_event = extensions[i]->eventBase;
+	    reply.first_error = extensions[i]->errorBase;
+	}
+    }
+    WriteReplyToClient(client, sizeof(xQueryExtensionReply), &reply);
+    return(client->noClientException);
+}
+
+int
+ProcListExtensions(ClientPtr client)
+{
+    xListExtensionsReply reply;
+    char *bufptr, *buffer;
+    int total_length = 0;
+
+    REQUEST_SIZE_MATCH(xReq);
+
+    reply.type = X_Reply;
+    reply.nExtensions = 0;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    buffer = NULL;
+
+    if ( NumExtensions )
+    {
+        register int i, j;
+
+        for (i=0;  i<NumExtensions; i++)
+	{
+#ifdef XCSECURITY
+	    /* don't show insecure extensions to untrusted clients */
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+	    total_length += strlen(extensions[i]->name) + 1;
+	    reply.nExtensions += 1 + extensions[i]->num_aliases;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+		total_length += strlen(extensions[i]->aliases[j]) + 1;
+	}
+        reply.length = (total_length + 3) >> 2;
+	buffer = bufptr = (char *)ALLOCATE_LOCAL(total_length);
+	if (!buffer)
+	    return(BadAlloc);
+        for (i=0;  i<NumExtensions; i++)
+        {
+	    int len;
+#ifdef XCSECURITY
+	    if (client->trustLevel == XSecurityClientUntrusted &&
+		!extensions[i]->secure)
+		continue;
+#endif
+            *bufptr++ = len = strlen(extensions[i]->name);
+	    memmove(bufptr, extensions[i]->name,  len);
+	    bufptr += len;
+	    for (j = extensions[i]->num_aliases; --j >= 0;)
+	    {
+		*bufptr++ = len = strlen(extensions[i]->aliases[j]);
+		memmove(bufptr, extensions[i]->aliases[j],  len);
+		bufptr += len;
+	    }
+	}
+    }
+    WriteReplyToClient(client, sizeof(xListExtensionsReply), &reply);
+    if (reply.length)
+    {
+        WriteToClient(client, total_length, buffer);
+    	DEALLOCATE_LOCAL(buffer);
+    }
+    return(client->noClientException);
+}
+
+
+ExtensionLookupProc 
+LookupProc(char *name, GCPtr pGC)
+{
+    register int i;
+    register ScreenProcEntry *spentry;
+    spentry  = &AuxillaryScreenProcs[pGC->pScreen->myNum];
+    if (spentry->num)    
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+                return(spentry->procList[i].proc);
+    }
+    return (ExtensionLookupProc)NULL;
+}
+
+Bool
+RegisterProc(char *name, GC *pGC, ExtensionLookupProc proc)
+{
+    return RegisterScreenProc(name, pGC->pScreen, proc);
+}
+
+Bool
+RegisterScreenProc(char *name, ScreenPtr pScreen, ExtensionLookupProc proc)
+{
+    register ScreenProcEntry *spentry;
+    register ProcEntryPtr procEntry = (ProcEntryPtr)NULL;
+    char *newname;
+    int i;
+
+    spentry = &AuxillaryScreenProcs[pScreen->myNum];
+    /* first replace duplicates */
+    if (spentry->num)
+    {
+        for (i = 0; i < spentry->num; i++)
+            if (strcmp(name, spentry->procList[i].name) == 0)
+	    {
+                procEntry = &spentry->procList[i];
+		break;
+	    }
+    }
+    if (procEntry)
+        procEntry->proc = proc;
+    else
+    {
+	newname = (char *)xalloc(strlen(name)+1);
+	if (!newname)
+	    return FALSE;
+	procEntry = (ProcEntryPtr)
+			    xrealloc(spentry->procList,
+				     sizeof(ProcEntryRec) * (spentry->num+1));
+	if (!procEntry)
+	{
+	    xfree(newname);
+	    return FALSE;
+	}
+	spentry->procList = procEntry;
+        procEntry += spentry->num;
+        procEntry->name = newname;
+        strcpy(newname, name);
+        procEntry->proc = proc;
+        spentry->num++;        
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
new file mode 100644
index 000000000..aee27e820
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
@@ -0,0 +1,575 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.9 2003/09/28 20:15:43 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates);
+
+static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+    __glXFlushContextCache();
+    (*__glXExt->resetExtension)();
+    __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+    __GLXclientState *cl = __glXClients[clientIndex];
+
+    if (cl->returnBuf) __glXFree(cl->returnBuf);
+    if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+    if (cl->currentContexts) __glXFree(cl->currentContexts);
+    __glXMemset(cl, 0, sizeof(__GLXclientState));
+    /*
+    ** By default, assume that the client supports
+    ** GLX major version 1 minor version 0 protocol.
+    */
+    cl->GLClientmajorVersion = 1;
+    cl->GLClientminorVersion = 0;
+    if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+    cl->largeCmdBytesSoFar = 0;
+    cl->largeCmdBytesTotal = 0;
+    cl->largeCmdRequestsSoFar = 0;
+    cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called.  In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+    cx->idExists = GL_FALSE;
+    if (!cx->isCurrent) {
+	__glXFreeContext(cx);
+    }
+
+    return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+    __GLXcontext *cx;
+    __GLXclientState *cl = __glXClients[clientIndex];
+    int i;
+
+    if (cl) {
+	/*
+	** Free all the contexts that are current for this client.
+	*/
+	for (i=0; i < cl->numCurrentContexts; i++) {
+	    cx = cl->currentContexts[i];
+	    if (cx) {
+		__glXDeassociateContext(cx);
+		cx->isCurrent = GL_FALSE;
+		if (!cx->idExists) {
+		    __glXFreeContext(cx);
+		}
+	    }
+	}
+	/*
+	** Re-initialize the client state structure.  Don't free it because
+	** we'll probably get another client with this index and use the struct
+	** again.  There is a maximum of MAXCLIENTS of these structures.
+	*/
+	ResetClientState(clientIndex);
+    }
+
+    return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+    PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+    pGlxPixmap->idExists = False;
+    if (!pGlxPixmap->refcnt) {
+	/*
+	** The DestroyPixmap routine should decrement the refcount and free
+	** only if it's zero.
+	*/
+	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+	__glXFree(pGlxPixmap);
+    }
+
+    return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+    if (cx->idExists || cx->isCurrent) return GL_FALSE;
+    
+    if (!cx->isDirect) {
+	if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+	    return GL_FALSE;
+	}
+    }
+    if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+    if (cx->selectBuf) __glXFree(cx->selectBuf);
+    __glXFree(cx);
+    if (cx == __glXLastContext) {
+	__glXFlushContextCache();
+    }
+
+    return GL_TRUE;
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+    if (__glXSwapBarrierFuncs &&
+        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+    }
+    FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+    return True;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error.  Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+    errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+    errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+    return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+    ExtensionEntry *extEntry;
+    int i;
+    
+    __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+
+    /*
+    ** Add extension to server extensions.
+    */
+    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+			    __GLX_NUMBER_ERRORS, __glXDispatch,
+			    __glXSwapDispatch, ResetExtension,
+			    StandardMinorOpcode);
+    if (!extEntry) {
+	FatalError("__glXExtensionInit: AddExtensions failed\n");
+	return;
+    }
+    if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+	ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+	return;
+    }
+
+    __glXBadContext = extEntry->errorBase + GLXBadContext;
+    __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+    __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+    __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+    __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+    __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+    __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+    __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+    __glXUnsupportedPrivateRequest = extEntry->errorBase +
+      			GLXUnsupportedPrivateRequest;
+
+    __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
+    /*
+    ** Initialize table of client state.  There is never a client 0.
+    */
+    for (i=1; i <= MAXCLIENTS; i++) {
+	__glXClients[i] = 0;
+    }
+
+    /*
+    ** Initialize screen specific data.
+    */
+    __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+    return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates)
+{
+    (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+		    int *nvisualp, int *ndepthp,
+		    int *rootDepthp, VisualID *defaultVisp,
+		    unsigned long sizes, int bitsPerRGB,
+		    int preferredVis)
+{
+    Bool ret;
+
+    if (saveInitVisualsProc) {
+        ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+                                  rootDepthp, defaultVisp, sizes, bitsPerRGB,
+                                  preferredVis);
+        if (!ret)
+            return False;
+    }
+    (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+                             defaultVisp, sizes, bitsPerRGB);
+    return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+    saveInitVisualsProc = *initVisProc;
+    *initVisProc = GlxInitVisuals;
+    /* HACK: this shouldn't be done here but it's the earliest time */
+    __glXExt = __glXglDDXExtensionInfo();       /* from GLcore */
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+    __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts).  While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+				int *error)
+{
+    __GLXcontext *cx;
+
+    /*
+    ** See if the context tag is legal; it is managed by the extension,
+    ** so if it's invalid, we have an implementation error.
+    */
+    cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+    if (!cx) {
+	cl->client->errorValue = tag;
+	*error = __glXBadContextTag;
+	return 0;
+    }
+
+    if (!cx->isDirect) {
+	if (cx->drawPriv == NULL) {
+	    /*
+	    ** The drawable has vanished.  It must be a window, because only
+	    ** windows can be destroyed from under us; GLX pixmaps are
+	    ** refcounted and don't go away until no one is using them.
+	    */
+	    *error = __glXBadCurrentWindow;
+	    return 0;
+    	}
+    }
+    
+    if (cx == __glXLastContext) {
+	/* No need to re-bind */
+	return cx;
+    }
+
+    /* Make this context the current one for the GL. */
+    if (!cx->isDirect) {
+	if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+	    /* Bind failed, and set the error code.  Bummer */
+	    cl->client->errorValue = cx->id;
+	    *error = __glXBadContextState;
+	    return 0;
+    	}
+    }
+    __glXLastContext = cx;
+    return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** If we're expecting a glXRenderLarge request, this better be one.
+    */
+    if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+	client->errorValue = stuff->glxCode;
+	return __glXBadLargeRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSwapSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+    return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+    return;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
new file mode 100644
index 000000000..aee27e820
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
@@ -0,0 +1,575 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.9 2003/09/28 20:15:43 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+#include "Trap.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates);
+
+static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+    __glXFlushContextCache();
+    (*__glXExt->resetExtension)();
+    __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+    __GLXclientState *cl = __glXClients[clientIndex];
+
+    if (cl->returnBuf) __glXFree(cl->returnBuf);
+    if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+    if (cl->currentContexts) __glXFree(cl->currentContexts);
+    __glXMemset(cl, 0, sizeof(__GLXclientState));
+    /*
+    ** By default, assume that the client supports
+    ** GLX major version 1 minor version 0 protocol.
+    */
+    cl->GLClientmajorVersion = 1;
+    cl->GLClientminorVersion = 0;
+    if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+    cl->largeCmdBytesSoFar = 0;
+    cl->largeCmdBytesTotal = 0;
+    cl->largeCmdRequestsSoFar = 0;
+    cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called.  In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+    cx->idExists = GL_FALSE;
+    if (!cx->isCurrent) {
+	__glXFreeContext(cx);
+    }
+
+    return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+    __GLXcontext *cx;
+    __GLXclientState *cl = __glXClients[clientIndex];
+    int i;
+
+    if (cl) {
+	/*
+	** Free all the contexts that are current for this client.
+	*/
+	for (i=0; i < cl->numCurrentContexts; i++) {
+	    cx = cl->currentContexts[i];
+	    if (cx) {
+		__glXDeassociateContext(cx);
+		cx->isCurrent = GL_FALSE;
+		if (!cx->idExists) {
+		    __glXFreeContext(cx);
+		}
+	    }
+	}
+	/*
+	** Re-initialize the client state structure.  Don't free it because
+	** we'll probably get another client with this index and use the struct
+	** again.  There is a maximum of MAXCLIENTS of these structures.
+	*/
+	ResetClientState(clientIndex);
+    }
+
+    return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+    PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+    pGlxPixmap->idExists = False;
+    if (!pGlxPixmap->refcnt) {
+	/*
+	** The DestroyPixmap routine should decrement the refcount and free
+	** only if it's zero.
+	*/
+	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+	__glXFree(pGlxPixmap);
+    }
+
+    return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+    if (cx->idExists || cx->isCurrent) return GL_FALSE;
+    
+    if (!cx->isDirect) {
+	if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+	    return GL_FALSE;
+	}
+    }
+    if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+    if (cx->selectBuf) __glXFree(cx->selectBuf);
+    __glXFree(cx);
+    if (cx == __glXLastContext) {
+	__glXFlushContextCache();
+    }
+
+    return GL_TRUE;
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+    if (__glXSwapBarrierFuncs &&
+        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+    }
+    FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+    return True;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error.  Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+    errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+    errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+    return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+    ExtensionEntry *extEntry;
+    int i;
+    
+    __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+
+    /*
+    ** Add extension to server extensions.
+    */
+    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+			    __GLX_NUMBER_ERRORS, __glXDispatch,
+			    __glXSwapDispatch, ResetExtension,
+			    StandardMinorOpcode);
+    if (!extEntry) {
+	FatalError("__glXExtensionInit: AddExtensions failed\n");
+	return;
+    }
+    if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+	ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+	return;
+    }
+
+    __glXBadContext = extEntry->errorBase + GLXBadContext;
+    __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+    __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+    __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+    __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+    __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+    __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+    __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+    __glXUnsupportedPrivateRequest = extEntry->errorBase +
+      			GLXUnsupportedPrivateRequest;
+
+    __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
+    /*
+    ** Initialize table of client state.  There is never a client 0.
+    */
+    for (i=1; i <= MAXCLIENTS; i++) {
+	__glXClients[i] = 0;
+    }
+
+    /*
+    ** Initialize screen specific data.
+    */
+    __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+    return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates)
+{
+    (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+		    int *nvisualp, int *ndepthp,
+		    int *rootDepthp, VisualID *defaultVisp,
+		    unsigned long sizes, int bitsPerRGB,
+		    int preferredVis)
+{
+    Bool ret;
+
+    if (saveInitVisualsProc) {
+        ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+                                  rootDepthp, defaultVisp, sizes, bitsPerRGB,
+                                  preferredVis);
+        if (!ret)
+            return False;
+    }
+    (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+                             defaultVisp, sizes, bitsPerRGB);
+    return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+    saveInitVisualsProc = *initVisProc;
+    *initVisProc = GlxInitVisuals;
+    /* HACK: this shouldn't be done here but it's the earliest time */
+    __glXExt = __glXglDDXExtensionInfo();       /* from GLcore */
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+    __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts).  While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+				int *error)
+{
+    __GLXcontext *cx;
+
+    /*
+    ** See if the context tag is legal; it is managed by the extension,
+    ** so if it's invalid, we have an implementation error.
+    */
+    cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+    if (!cx) {
+	cl->client->errorValue = tag;
+	*error = __glXBadContextTag;
+	return 0;
+    }
+
+    if (!cx->isDirect) {
+	if (cx->drawPriv == NULL) {
+	    /*
+	    ** The drawable has vanished.  It must be a window, because only
+	    ** windows can be destroyed from under us; GLX pixmaps are
+	    ** refcounted and don't go away until no one is using them.
+	    */
+	    *error = __glXBadCurrentWindow;
+	    return 0;
+    	}
+    }
+    
+    if (cx == __glXLastContext) {
+	/* No need to re-bind */
+	return cx;
+    }
+
+    /* Make this context the current one for the GL. */
+    if (!cx->isDirect) {
+	if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+	    /* Bind failed, and set the error code.  Bummer */
+	    cl->client->errorValue = cx->id;
+	    *error = __glXBadContextState;
+	    return 0;
+    	}
+    }
+    __glXLastContext = cx;
+    return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** If we're expecting a glXRenderLarge request, this better be one.
+    */
+    if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+	client->errorValue = stuff->glxCode;
+	return __glXBadLargeRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+    int result;
+
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSwapSingleTable[opcode];
+
+    /*
+     * Report upstream that we are
+     * dispatching a GLX operation.
+     */
+
+    nxagentGlxTrap = 1;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Going to dispatch GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+    
+    result = (*proc)(cl, (GLbyte *) stuff);
+
+    nxagentGlxTrap = 0;
+
+    #ifdef TEST
+    fprintf(stderr, "__glXDispatch: Dispatched GLX operation [%d] for client [%d].\n", 
+                opcode, client -> index);
+    #endif
+
+    return result;
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+    return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+    return;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original
new file mode 100644
index 000000000..fa1382983
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.X.original
@@ -0,0 +1,505 @@
+/* $XFree86: xc/programs/Xserver/GL/glx/glxext.c,v 1.9 2003/09/28 20:15:43 alanh Exp $
+** The contents of this file are subject to the GLX Public License Version 1.0
+** (the "License"). You may not use this file except in compliance with the
+** License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+** attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+** or at http://www.sgi.com/software/opensource/glx/license.html.
+**
+** Software distributed under the License is distributed on an "AS IS"
+** basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+** IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+** PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+** language governing rights and limitations under the License.
+**
+** The Original Software is GLX version 1.2 source code, released February,
+** 1999. The developer of the Original Software is Silicon Graphics, Inc.
+** Those portions of the Subject Software created by Silicon Graphics, Inc.
+** are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+**
+*/
+
+#define NEED_REPLIES
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "unpack.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "micmap.h"
+
+
+void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates);
+
+static __GLXextensionInfo *__glXExt /* = &__glDDXExtensionInfo */;
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+    __glXFlushContextCache();
+    (*__glXExt->resetExtension)();
+    __glXScreenReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+    __GLXclientState *cl = __glXClients[clientIndex];
+
+    if (cl->returnBuf) __glXFree(cl->returnBuf);
+    if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+    if (cl->currentContexts) __glXFree(cl->currentContexts);
+    __glXMemset(cl, 0, sizeof(__GLXclientState));
+    /*
+    ** By default, assume that the client supports
+    ** GLX major version 1 minor version 0 protocol.
+    */
+    cl->GLClientmajorVersion = 1;
+    cl->GLClientminorVersion = 0;
+    if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+}
+
+/*
+** Reset state used to keep track of large (multi-request) commands.
+*/
+void __glXResetLargeCommandStatus(__GLXclientState *cl)
+{
+    cl->largeCmdBytesSoFar = 0;
+    cl->largeCmdBytesTotal = 0;
+    cl->largeCmdRequestsSoFar = 0;
+    cl->largeCmdRequestsTotal = 0;
+}
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called.  In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+    cx->idExists = GL_FALSE;
+    if (!cx->isCurrent) {
+	__glXFreeContext(cx);
+    }
+
+    return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+    __GLXcontext *cx;
+    __GLXclientState *cl = __glXClients[clientIndex];
+    int i;
+
+    if (cl) {
+	/*
+	** Free all the contexts that are current for this client.
+	*/
+	for (i=0; i < cl->numCurrentContexts; i++) {
+	    cx = cl->currentContexts[i];
+	    if (cx) {
+		__glXDeassociateContext(cx);
+		cx->isCurrent = GL_FALSE;
+		if (!cx->idExists) {
+		    __glXFreeContext(cx);
+		}
+	    }
+	}
+	/*
+	** Re-initialize the client state structure.  Don't free it because
+	** we'll probably get another client with this index and use the struct
+	** again.  There is a maximum of MAXCLIENTS of these structures.
+	*/
+	ResetClientState(clientIndex);
+    }
+
+    return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+    PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+    pGlxPixmap->idExists = False;
+    if (!pGlxPixmap->refcnt) {
+	/*
+	** The DestroyPixmap routine should decrement the refcount and free
+	** only if it's zero.
+	*/
+	(*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+	__glXFree(pGlxPixmap);
+    }
+
+    return True;
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+    if (cx->idExists || cx->isCurrent) return GL_FALSE;
+    
+    if (!cx->isDirect) {
+	if ((*cx->gc->exports.destroyContext)((__GLcontext *)cx->gc) == GL_FALSE) {
+	    return GL_FALSE;
+	}
+    }
+    if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+    if (cx->selectBuf) __glXFree(cx->selectBuf);
+    __glXFree(cx);
+    if (cx == __glXLastContext) {
+	__glXFlushContextCache();
+    }
+
+    return GL_TRUE;
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+static int SwapBarrierGone(int screen, XID drawable)
+{
+    if (__glXSwapBarrierFuncs &&
+        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc != NULL) {
+        __glXSwapBarrierFuncs[screen].bindSwapBarrierFunc(screen, drawable, 0);
+    }
+    FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+    return True;
+}
+
+/************************************************************************/
+
+/*
+** These routines can be used to check whether a particular GL command
+** has caused an error.  Specifically, we use them to check whether a
+** given query has caused an error, in which case a zero-length data
+** reply is sent to the client.
+*/
+
+static GLboolean errorOccured = GL_FALSE;
+
+/*
+** The GL was will call this routine if an error occurs.
+*/
+void __glXErrorCallBack(__GLinterface *gc, GLenum code)
+{
+    errorOccured = GL_TRUE;
+}
+
+/*
+** Clear the error flag before calling the GL command.
+*/
+void __glXClearErrorOccured(void)
+{
+    errorOccured = GL_FALSE;
+}
+
+/*
+** Check if the GL command caused an error.
+*/
+GLboolean __glXErrorOccured(void)
+{
+    return errorOccured;
+}
+
+/************************************************************************/
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+    ExtensionEntry *extEntry;
+    int i;
+    
+    __glXContextRes = CreateNewResourceType((DeleteType)ContextGone);
+    __glXClientRes = CreateNewResourceType((DeleteType)ClientGone);
+    __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone);
+
+    /*
+    ** Add extension to server extensions.
+    */
+    extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+			    __GLX_NUMBER_ERRORS, __glXDispatch,
+			    __glXSwapDispatch, ResetExtension,
+			    StandardMinorOpcode);
+    if (!extEntry) {
+	FatalError("__glXExtensionInit: AddExtensions failed\n");
+	return;
+    }
+    if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+	ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+	return;
+    }
+
+    __glXBadContext = extEntry->errorBase + GLXBadContext;
+    __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+    __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+    __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+    __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+    __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+    __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+    __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+    __glXUnsupportedPrivateRequest = extEntry->errorBase +
+      			GLXUnsupportedPrivateRequest;
+
+    __glXSwapBarrierRes = CreateNewResourceType((DeleteType)SwapBarrierGone);
+
+    /*
+    ** Initialize table of client state.  There is never a client 0.
+    */
+    for (i=1; i <= MAXCLIENTS; i++) {
+	__glXClients[i] = 0;
+    }
+
+    /*
+    ** Initialize screen specific data.
+    */
+    __glXScreenInit(screenInfo.numScreens);
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+    return __glXExt->type;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs, 
+                         __GLXvisualConfig *configs, void **privates)
+{
+    (*__glXExt->setVisualConfigs)(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+		    int *nvisualp, int *ndepthp,
+		    int *rootDepthp, VisualID *defaultVisp,
+		    unsigned long sizes, int bitsPerRGB,
+		    int preferredVis)
+{
+    Bool ret;
+
+    if (saveInitVisualsProc) {
+        ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+                                  rootDepthp, defaultVisp, sizes, bitsPerRGB,
+                                  preferredVis);
+        if (!ret)
+            return False;
+    }
+    (*__glXExt->initVisuals)(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+                             defaultVisp, sizes, bitsPerRGB);
+    return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+    saveInitVisualsProc = *initVisProc;
+    *initVisProc = GlxInitVisuals;
+    /* HACK: this shouldn't be done here but it's the earliest time */
+    __glXExt = __glXglDDXExtensionInfo();       /* from GLcore */
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+    __glXLastContext = 0;
+}
+
+/*
+** Make a context the current one for the GL (in this implementation, there
+** is only one instance of the GL, and we use it to serve all GL clients by
+** switching it between different contexts).  While we are at it, look up
+** a context by its tag and return its (__GLXcontext *).
+*/
+__GLXcontext *__glXForceCurrent(__GLXclientState *cl, GLXContextTag tag,
+				int *error)
+{
+    __GLXcontext *cx;
+
+    /*
+    ** See if the context tag is legal; it is managed by the extension,
+    ** so if it's invalid, we have an implementation error.
+    */
+    cx = (__GLXcontext *) __glXLookupContextByTag(cl, tag);
+    if (!cx) {
+	cl->client->errorValue = tag;
+	*error = __glXBadContextTag;
+	return 0;
+    }
+
+    if (!cx->isDirect) {
+	if (cx->drawPriv == NULL) {
+	    /*
+	    ** The drawable has vanished.  It must be a window, because only
+	    ** windows can be destroyed from under us; GLX pixmaps are
+	    ** refcounted and don't go away until no one is using them.
+	    */
+	    *error = __glXBadCurrentWindow;
+	    return 0;
+    	}
+    }
+    
+    if (cx == __glXLastContext) {
+	/* No need to re-bind */
+	return cx;
+    }
+
+    /* Make this context the current one for the GL. */
+    if (!cx->isDirect) {
+	if (!(*cx->gc->exports.forceCurrent)((__GLcontext *)cx->gc)) {
+	    /* Bind failed, and set the error code.  Bummer */
+	    cl->client->errorValue = cx->id;
+	    *error = __glXBadContextState;
+	    return 0;
+    	}
+    }
+    __glXLastContext = cx;
+    return cx;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** If we're expecting a glXRenderLarge request, this better be one.
+    */
+    if ((cl->largeCmdRequestsSoFar != 0) && (opcode != X_GLXRenderLarge)) {
+	client->errorValue = stuff->glxCode;
+	return __glXBadLargeRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSingleTable[opcode];
+    return (*proc)(cl, (GLbyte *) stuff);
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+    REQUEST(xGLXSingleReq);
+    CARD8 opcode;
+    int (*proc)(__GLXclientState *cl, GLbyte *pc);
+    __GLXclientState *cl;
+
+    opcode = stuff->glxCode;
+    cl = __glXClients[client->index];
+    if (!cl) {
+	cl = (__GLXclientState *) __glXMalloc(sizeof(__GLXclientState));
+	 __glXClients[client->index] = cl;
+	if (!cl) {
+	    return BadAlloc;
+	}
+	__glXMemset(cl, 0, sizeof(__GLXclientState));
+    }
+    
+    if (!cl->inUse) {
+	/*
+	** This is first request from this client.  Associate a resource
+	** with the client so we will be notified when the client dies.
+	*/
+	XID xid = FakeClientID(client->index);
+	if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+	    return BadAlloc;
+	}
+	ResetClientState(client->index);
+	cl->inUse = GL_TRUE;
+	cl->client = client;
+    }
+
+    /*
+    ** Check for valid opcode.
+    */
+    if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+	return BadRequest;
+    }
+
+    /*
+    ** Use the opcode to index into the procedure table.
+    */
+    proc = __glXSwapSingleTable[opcode];
+    return (*proc)(cl, (GLbyte *) stuff);
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+    return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+    return;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
new file mode 100644
index 000000000..06dabddaa
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -0,0 +1,566 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.5 2001/01/30 07:01:22 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef  DEBUG
+#undef  TEST
+
+#endif
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime.  These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+    { 32,		43,		41        },
+    { 64,		73,		71        },
+    { 128,		151,		149       },
+    { 256,		283,		281       },
+    { 512,		571,		569       },
+    { 1024,		1153,		1151      },
+    { 2048,		2269,		2267      },
+    { 4096,		4519,		4517      },
+    { 8192,		9013,		9011      },
+    { 16384,		18043,		18041     },
+    { 32768,		36109,		36107     },
+    { 65536,		72091,		72089     },
+    { 131072,		144409,		144407    },
+    { 262144,		288361,		288359    },
+    { 524288,		576883,		576881    },
+    { 1048576,		1153459,	1153457   },
+    { 2097152,		2307163,	2307161   },
+    { 4194304,		4613893,	4613891   },
+    { 8388608,		9227641,	9227639   },
+    { 16777216,		18455029,	18455027  },
+    { 33554432,		36911011,	36911009  },
+    { 67108864,		73819861,	73819859  },
+    { 134217728,	147639589,	147639587 },
+    { 268435456,	295279081,	295279079 },
+    { 536870912,	590559793,	590559791 }
+};
+
+#define NGLYPHHASHSETS	(sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8	glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+    int	i;
+
+    for (i = 0; i < NGLYPHHASHSETS; i++)
+	if (glyphHashSets[i].entries >= filled)
+	    return &glyphHashSets[i];
+    return 0;
+}
+
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+    return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+    _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
+{
+    pointer *new;
+
+    if (n > glyphSet->maxPrivate) {
+	if (glyphSet->devPrivates &&
+	    glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
+	    new = (pointer *) xrealloc (glyphSet->devPrivates,
+					(n + 1) * sizeof (pointer));
+	    if (!new)
+		return FALSE;
+	} else {
+	    new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+	    if (!new)
+		return FALSE;
+	    if (glyphSet->devPrivates)
+		memcpy (new,
+			glyphSet->devPrivates,
+			(glyphSet->maxPrivate + 1) * sizeof (pointer));
+	}
+	glyphSet->devPrivates = new;
+	/* Zero out new, uninitialize privates */
+	while (++glyphSet->maxPrivate < n)
+	    glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
+    }
+    glyphSet->devPrivates[n] = ptr;
+    return TRUE;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+    return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+    CARD32	elt, step, s;
+    GlyphPtr	glyph;
+    GlyphRefPtr	table, gr, del;
+    CARD32	tableSize = hash->hashSet->size;
+
+    table = hash->table;
+    elt = signature % tableSize;
+    step = 0;
+    del = 0;
+    for (;;)
+    {
+	gr = &table[elt];
+	s = gr->signature;
+	glyph = gr->glyph;
+	if (!glyph)
+	{
+	    if (del)
+		gr = del;
+	    break;
+	}
+	if (glyph == DeletedGlyph)
+	{
+	    if (!del)
+		del = gr;
+	    else if (gr == del)
+		break;
+	}
+	else if (s == signature &&
+		 (!match || 
+		  memcmp (&compare->info, &glyph->info, compare->size) == 0))
+	{
+	    break;
+	}
+	if (!step)
+	{
+	    step = signature % hash->hashSet->rehash;
+	    if (!step)
+		step = 1;
+	}
+	elt += step;
+	if (elt >= tableSize)
+	    elt -= tableSize;
+    }
+    return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+    CARD32  *bits = (CARD32 *) &(glyph->info);
+    CARD32  hash;
+    int	    n = glyph->size / sizeof (CARD32);
+
+    hash = 0;
+    while (n--)
+	hash ^= *bits++;
+    return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+    ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+    GlyphPtr	g;
+    int		i, j;
+
+    for (i = 0; i < hash->hashSet->size; i++)
+    {
+	g = hash->table[i].glyph;
+	if (!g || g == DeletedGlyph)
+	    continue;
+	for (j = i + 1; j < hash->hashSet->size; j++)
+	    if (hash->table[j].glyph == g)
+		DuplicateRef (g, where);
+    }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+    CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+    if (--glyph->refcnt == 0)
+    {
+	GlyphRefPtr gr;
+	int	    i;
+	int	    first;
+
+	first = -1;
+	for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+	    if (globalGlyphs[format].table[i].glyph == glyph)
+	    {
+		if (first != -1)
+		    DuplicateRef (glyph, "FreeGlyph check");
+		first = i;
+	    }
+
+	gr = FindGlyphRef (&globalGlyphs[format],
+			   HashGlyph (glyph), TRUE, glyph);
+	if (gr - globalGlyphs[format].table != first)
+	    DuplicateRef (glyph, "Found wrong one");
+	if (gr->glyph && gr->glyph != DeletedGlyph)
+	{
+	    gr->glyph = DeletedGlyph;
+	    gr->signature = 0;
+	    globalGlyphs[format].tableEntries--;
+	}
+	xfree (glyph);
+    }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+    GlyphRefPtr	    gr;
+    CARD32	    hash;
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+    /* Locate existing matching glyph */
+    hash = HashGlyph (glyph);
+    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+    {
+	xfree (glyph);
+	glyph = gr->glyph;
+    }
+    else
+    {
+	gr->glyph = glyph;
+	gr->signature = hash;
+	globalGlyphs[glyphSet->fdepth].tableEntries++;
+    }
+ 
+    /* Insert/replace glyphset value */
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    ++glyph->refcnt;
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+	FreeGlyph (gr->glyph, glyphSet->fdepth);
+    else
+	glyphSet->hash.tableEntries++;
+    gr->glyph = glyph;
+    gr->signature = id;
+
+    #ifdef NXAGENT_SERVER
+
+    gr -> corruptedGlyph = 1;
+
+    #endif
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphRefPtr     gr;
+    GlyphPtr	    glyph;
+
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    glyph = gr->glyph;
+    if (glyph && glyph != DeletedGlyph)
+    {
+	gr->glyph = DeletedGlyph;
+	glyphSet->hash.tableEntries--;
+	FreeGlyph (glyph, glyphSet->fdepth);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+#ifdef NXAGENT_SERVER
+
+GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+  GlyphRefPtr gr;
+  GlyphPtr    glyph;
+
+  gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+  glyph = gr -> glyph;
+
+  if (glyph == DeletedGlyph)
+  {
+    glyph = 0;
+  }
+  else if (gr -> corruptedGlyph == 1)
+  {
+     #ifdef DEBUG
+     fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
+                 (void *) glyph, (void *) glyphSet);
+     #endif
+
+    nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
+                         (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
+  }
+
+  return glyph;
+}
+
+#else
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphPtr        glyph;
+
+    glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+    if (glyph == DeletedGlyph)
+	glyph = 0;
+    return glyph;
+}
+
+#endif
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+    int		size;
+    GlyphPtr	glyph;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+    if (!glyph)
+	return 0;
+    glyph->refcnt = 0;
+    glyph->size = size + sizeof (xGlyphInfo);
+    glyph->info = *gi;
+    return glyph;
+}
+    
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+    hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+    if (!hash->table)
+	return FALSE;
+    memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+    hash->hashSet = hashSet;
+    hash->tableEntries = 0;
+    return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+    CARD32	    tableEntries;
+    GlyphHashSetPtr hashSet;
+    GlyphHashRec    newHash;
+    GlyphRefPtr	    gr;
+    GlyphPtr	    glyph;
+    int		    i;
+    int		    oldSize;
+    CARD32	    s;
+
+    #ifdef NXAGENT_SERVER
+
+    CARD32          c;
+
+    #endif
+
+    tableEntries = hash->tableEntries + change;
+    hashSet = FindGlyphHashSet (tableEntries);
+    if (hashSet == hash->hashSet)
+	return TRUE;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash top");
+    if (!AllocateGlyphHash (&newHash, hashSet))
+	return FALSE;
+    if (hash->table)
+    {
+	oldSize = hash->hashSet->size;
+	for (i = 0; i < oldSize; i++)
+	{
+	    glyph = hash->table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+	    {
+		s = hash->table[i].signature;
+
+                #ifdef NXAGENT_SERVER
+
+                c = hash->table[i].corruptedGlyph;
+
+                #endif
+
+		gr = FindGlyphRef (&newHash, s, global, glyph);
+		gr->signature = s;
+		gr->glyph = glyph;
+
+                #ifdef NXAGENT_SERVER
+
+                gr -> corruptedGlyph = c;
+
+                #endif
+
+		++newHash.tableEntries;
+	    }
+	}
+	xfree (hash->table);
+    }
+    *hash = newHash;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash bottom");
+    return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+    return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+			    
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+    GlyphSetPtr	glyphSet;
+    int size;
+    
+    if (!globalGlyphs[fdepth].hashSet)
+    {
+	if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+	    return FALSE;
+    }
+
+    size = (sizeof (GlyphSetRec) +
+	    (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
+    glyphSet = xalloc (size);
+    if (!glyphSet)
+	return FALSE;
+    bzero((char *)glyphSet, size);
+    glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+    if (_GlyphSetPrivateAllocateIndex)
+	glyphSet->devPrivates = (pointer)(&glyphSet[1]);
+
+    if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+    {
+	xfree (glyphSet);
+	return FALSE;
+    }
+    glyphSet->refcnt = 1;
+    glyphSet->fdepth = fdepth;
+    glyphSet->format = format;
+    return glyphSet;	
+}
+
+int
+FreeGlyphSet (pointer	value,
+	      XID       gid)
+{
+    GlyphSetPtr	glyphSet = (GlyphSetPtr) value;
+    
+    if (--glyphSet->refcnt == 0)
+    {
+	CARD32	    i, tableSize = glyphSet->hash.hashSet->size;
+	GlyphRefPtr table = glyphSet->hash.table;
+	GlyphPtr    glyph;
+    
+	for (i = 0; i < tableSize; i++)
+	{
+	    glyph = table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+		FreeGlyph (glyph, glyphSet->fdepth);
+	}
+	if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+	{
+	    xfree (globalGlyphs[glyphSet->fdepth].table);
+	    globalGlyphs[glyphSet->fdepth].table = 0;
+	    globalGlyphs[glyphSet->fdepth].hashSet = 0;
+	}
+	else
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+	xfree (table);
+
+	if (glyphSet->devPrivates &&
+	    glyphSet->devPrivates != (pointer)(&glyphSet[1]))
+	    xfree(glyphSet->devPrivates);
+
+	xfree (glyphSet);
+    }
+    return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
new file mode 100644
index 000000000..06dabddaa
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -0,0 +1,566 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.5 2001/01/30 07:01:22 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+#include "Render.h"
+
+#define PANIC
+#define WARNING
+#undef  DEBUG
+#undef  TEST
+
+#endif
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime.  These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+    { 32,		43,		41        },
+    { 64,		73,		71        },
+    { 128,		151,		149       },
+    { 256,		283,		281       },
+    { 512,		571,		569       },
+    { 1024,		1153,		1151      },
+    { 2048,		2269,		2267      },
+    { 4096,		4519,		4517      },
+    { 8192,		9013,		9011      },
+    { 16384,		18043,		18041     },
+    { 32768,		36109,		36107     },
+    { 65536,		72091,		72089     },
+    { 131072,		144409,		144407    },
+    { 262144,		288361,		288359    },
+    { 524288,		576883,		576881    },
+    { 1048576,		1153459,	1153457   },
+    { 2097152,		2307163,	2307161   },
+    { 4194304,		4613893,	4613891   },
+    { 8388608,		9227641,	9227639   },
+    { 16777216,		18455029,	18455027  },
+    { 33554432,		36911011,	36911009  },
+    { 67108864,		73819861,	73819859  },
+    { 134217728,	147639589,	147639587 },
+    { 268435456,	295279081,	295279079 },
+    { 536870912,	590559793,	590559791 }
+};
+
+#define NGLYPHHASHSETS	(sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8	glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+    int	i;
+
+    for (i = 0; i < NGLYPHHASHSETS; i++)
+	if (glyphHashSets[i].entries >= filled)
+	    return &glyphHashSets[i];
+    return 0;
+}
+
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+    return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+    _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
+{
+    pointer *new;
+
+    if (n > glyphSet->maxPrivate) {
+	if (glyphSet->devPrivates &&
+	    glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
+	    new = (pointer *) xrealloc (glyphSet->devPrivates,
+					(n + 1) * sizeof (pointer));
+	    if (!new)
+		return FALSE;
+	} else {
+	    new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+	    if (!new)
+		return FALSE;
+	    if (glyphSet->devPrivates)
+		memcpy (new,
+			glyphSet->devPrivates,
+			(glyphSet->maxPrivate + 1) * sizeof (pointer));
+	}
+	glyphSet->devPrivates = new;
+	/* Zero out new, uninitialize privates */
+	while (++glyphSet->maxPrivate < n)
+	    glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
+    }
+    glyphSet->devPrivates[n] = ptr;
+    return TRUE;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+    return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+    CARD32	elt, step, s;
+    GlyphPtr	glyph;
+    GlyphRefPtr	table, gr, del;
+    CARD32	tableSize = hash->hashSet->size;
+
+    table = hash->table;
+    elt = signature % tableSize;
+    step = 0;
+    del = 0;
+    for (;;)
+    {
+	gr = &table[elt];
+	s = gr->signature;
+	glyph = gr->glyph;
+	if (!glyph)
+	{
+	    if (del)
+		gr = del;
+	    break;
+	}
+	if (glyph == DeletedGlyph)
+	{
+	    if (!del)
+		del = gr;
+	    else if (gr == del)
+		break;
+	}
+	else if (s == signature &&
+		 (!match || 
+		  memcmp (&compare->info, &glyph->info, compare->size) == 0))
+	{
+	    break;
+	}
+	if (!step)
+	{
+	    step = signature % hash->hashSet->rehash;
+	    if (!step)
+		step = 1;
+	}
+	elt += step;
+	if (elt >= tableSize)
+	    elt -= tableSize;
+    }
+    return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+    CARD32  *bits = (CARD32 *) &(glyph->info);
+    CARD32  hash;
+    int	    n = glyph->size / sizeof (CARD32);
+
+    hash = 0;
+    while (n--)
+	hash ^= *bits++;
+    return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+    ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+    GlyphPtr	g;
+    int		i, j;
+
+    for (i = 0; i < hash->hashSet->size; i++)
+    {
+	g = hash->table[i].glyph;
+	if (!g || g == DeletedGlyph)
+	    continue;
+	for (j = i + 1; j < hash->hashSet->size; j++)
+	    if (hash->table[j].glyph == g)
+		DuplicateRef (g, where);
+    }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+    CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+    if (--glyph->refcnt == 0)
+    {
+	GlyphRefPtr gr;
+	int	    i;
+	int	    first;
+
+	first = -1;
+	for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+	    if (globalGlyphs[format].table[i].glyph == glyph)
+	    {
+		if (first != -1)
+		    DuplicateRef (glyph, "FreeGlyph check");
+		first = i;
+	    }
+
+	gr = FindGlyphRef (&globalGlyphs[format],
+			   HashGlyph (glyph), TRUE, glyph);
+	if (gr - globalGlyphs[format].table != first)
+	    DuplicateRef (glyph, "Found wrong one");
+	if (gr->glyph && gr->glyph != DeletedGlyph)
+	{
+	    gr->glyph = DeletedGlyph;
+	    gr->signature = 0;
+	    globalGlyphs[format].tableEntries--;
+	}
+	xfree (glyph);
+    }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+    GlyphRefPtr	    gr;
+    CARD32	    hash;
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+    /* Locate existing matching glyph */
+    hash = HashGlyph (glyph);
+    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+    {
+	xfree (glyph);
+	glyph = gr->glyph;
+    }
+    else
+    {
+	gr->glyph = glyph;
+	gr->signature = hash;
+	globalGlyphs[glyphSet->fdepth].tableEntries++;
+    }
+ 
+    /* Insert/replace glyphset value */
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    ++glyph->refcnt;
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+	FreeGlyph (gr->glyph, glyphSet->fdepth);
+    else
+	glyphSet->hash.tableEntries++;
+    gr->glyph = glyph;
+    gr->signature = id;
+
+    #ifdef NXAGENT_SERVER
+
+    gr -> corruptedGlyph = 1;
+
+    #endif
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphRefPtr     gr;
+    GlyphPtr	    glyph;
+
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    glyph = gr->glyph;
+    if (glyph && glyph != DeletedGlyph)
+    {
+	gr->glyph = DeletedGlyph;
+	glyphSet->hash.tableEntries--;
+	FreeGlyph (glyph, glyphSet->fdepth);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+#ifdef NXAGENT_SERVER
+
+GlyphPtr FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+  GlyphRefPtr gr;
+  GlyphPtr    glyph;
+
+  gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+  glyph = gr -> glyph;
+
+  if (glyph == DeletedGlyph)
+  {
+    glyph = 0;
+  }
+  else if (gr -> corruptedGlyph == 1)
+  {
+     #ifdef DEBUG
+     fprintf(stderr, "FindGlyphRef: Going to synchronize the glyph [%p] for glyphset [%p].\n",
+                 (void *) glyph, (void *) glyphSet);
+     #endif
+
+    nxagentAddGlyphs(glyphSet, &id, &(glyph -> info), 1,
+                         (CARD8*)(glyph + 1), glyph -> size - sizeof(xGlyphInfo));
+  }
+
+  return glyph;
+}
+
+#else
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphPtr        glyph;
+
+    glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+    if (glyph == DeletedGlyph)
+	glyph = 0;
+    return glyph;
+}
+
+#endif
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+    int		size;
+    GlyphPtr	glyph;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+    if (!glyph)
+	return 0;
+    glyph->refcnt = 0;
+    glyph->size = size + sizeof (xGlyphInfo);
+    glyph->info = *gi;
+    return glyph;
+}
+    
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+    hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+    if (!hash->table)
+	return FALSE;
+    memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+    hash->hashSet = hashSet;
+    hash->tableEntries = 0;
+    return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+    CARD32	    tableEntries;
+    GlyphHashSetPtr hashSet;
+    GlyphHashRec    newHash;
+    GlyphRefPtr	    gr;
+    GlyphPtr	    glyph;
+    int		    i;
+    int		    oldSize;
+    CARD32	    s;
+
+    #ifdef NXAGENT_SERVER
+
+    CARD32          c;
+
+    #endif
+
+    tableEntries = hash->tableEntries + change;
+    hashSet = FindGlyphHashSet (tableEntries);
+    if (hashSet == hash->hashSet)
+	return TRUE;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash top");
+    if (!AllocateGlyphHash (&newHash, hashSet))
+	return FALSE;
+    if (hash->table)
+    {
+	oldSize = hash->hashSet->size;
+	for (i = 0; i < oldSize; i++)
+	{
+	    glyph = hash->table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+	    {
+		s = hash->table[i].signature;
+
+                #ifdef NXAGENT_SERVER
+
+                c = hash->table[i].corruptedGlyph;
+
+                #endif
+
+		gr = FindGlyphRef (&newHash, s, global, glyph);
+		gr->signature = s;
+		gr->glyph = glyph;
+
+                #ifdef NXAGENT_SERVER
+
+                gr -> corruptedGlyph = c;
+
+                #endif
+
+		++newHash.tableEntries;
+	    }
+	}
+	xfree (hash->table);
+    }
+    *hash = newHash;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash bottom");
+    return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+    return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+			    
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+    GlyphSetPtr	glyphSet;
+    int size;
+    
+    if (!globalGlyphs[fdepth].hashSet)
+    {
+	if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+	    return FALSE;
+    }
+
+    size = (sizeof (GlyphSetRec) +
+	    (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
+    glyphSet = xalloc (size);
+    if (!glyphSet)
+	return FALSE;
+    bzero((char *)glyphSet, size);
+    glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+    if (_GlyphSetPrivateAllocateIndex)
+	glyphSet->devPrivates = (pointer)(&glyphSet[1]);
+
+    if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+    {
+	xfree (glyphSet);
+	return FALSE;
+    }
+    glyphSet->refcnt = 1;
+    glyphSet->fdepth = fdepth;
+    glyphSet->format = format;
+    return glyphSet;	
+}
+
+int
+FreeGlyphSet (pointer	value,
+	      XID       gid)
+{
+    GlyphSetPtr	glyphSet = (GlyphSetPtr) value;
+    
+    if (--glyphSet->refcnt == 0)
+    {
+	CARD32	    i, tableSize = glyphSet->hash.hashSet->size;
+	GlyphRefPtr table = glyphSet->hash.table;
+	GlyphPtr    glyph;
+    
+	for (i = 0; i < tableSize; i++)
+	{
+	    glyph = table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+		FreeGlyph (glyph, glyphSet->fdepth);
+	}
+	if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+	{
+	    xfree (globalGlyphs[glyphSet->fdepth].table);
+	    globalGlyphs[glyphSet->fdepth].table = 0;
+	    globalGlyphs[glyphSet->fdepth].hashSet = 0;
+	}
+	else
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+	xfree (table);
+
+	if (glyphSet->devPrivates &&
+	    glyphSet->devPrivates != (pointer)(&glyphSet[1]))
+	    xfree(glyphSet->devPrivates);
+
+	xfree (glyphSet);
+    }
+    return Success;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
new file mode 100644
index 000000000..45c5dd975
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
@@ -0,0 +1,478 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyph.c,v 1.5 2001/01/30 07:01:22 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+
+/*
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime.  These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static GlyphHashSetRec glyphHashSets[] = {
+    { 32,		43,		41        },
+    { 64,		73,		71        },
+    { 128,		151,		149       },
+    { 256,		283,		281       },
+    { 512,		571,		569       },
+    { 1024,		1153,		1151      },
+    { 2048,		2269,		2267      },
+    { 4096,		4519,		4517      },
+    { 8192,		9013,		9011      },
+    { 16384,		18043,		18041     },
+    { 32768,		36109,		36107     },
+    { 65536,		72091,		72089     },
+    { 131072,		144409,		144407    },
+    { 262144,		288361,		288359    },
+    { 524288,		576883,		576881    },
+    { 1048576,		1153459,	1153457   },
+    { 2097152,		2307163,	2307161   },
+    { 4194304,		4613893,	4613891   },
+    { 8388608,		9227641,	9227639   },
+    { 16777216,		18455029,	18455027  },
+    { 33554432,		36911011,	36911009  },
+    { 67108864,		73819861,	73819859  },
+    { 134217728,	147639589,	147639587 },
+    { 268435456,	295279081,	295279079 },
+    { 536870912,	590559793,	590559791 }
+};
+
+#define NGLYPHHASHSETS	(sizeof(glyphHashSets)/sizeof(glyphHashSets[0]))
+
+const CARD8	glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 };
+
+GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled)
+{
+    int	i;
+
+    for (i = 0; i < NGLYPHHASHSETS; i++)
+	if (glyphHashSets[i].entries >= filled)
+	    return &glyphHashSets[i];
+    return 0;
+}
+
+static int _GlyphSetPrivateAllocateIndex = 0;
+
+int
+AllocateGlyphSetPrivateIndex (void)
+{
+    return _GlyphSetPrivateAllocateIndex++;
+}
+
+void
+ResetGlyphSetPrivateIndex (void)
+{
+    _GlyphSetPrivateAllocateIndex = 0;
+}
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
+{
+    pointer *new;
+
+    if (n > glyphSet->maxPrivate) {
+	if (glyphSet->devPrivates &&
+	    glyphSet->devPrivates != (pointer)(&glyphSet[1])) {
+	    new = (pointer *) xrealloc (glyphSet->devPrivates,
+					(n + 1) * sizeof (pointer));
+	    if (!new)
+		return FALSE;
+	} else {
+	    new = (pointer *) xalloc ((n + 1) * sizeof (pointer));
+	    if (!new)
+		return FALSE;
+	    if (glyphSet->devPrivates)
+		memcpy (new,
+			glyphSet->devPrivates,
+			(glyphSet->maxPrivate + 1) * sizeof (pointer));
+	}
+	glyphSet->devPrivates = new;
+	/* Zero out new, uninitialize privates */
+	while (++glyphSet->maxPrivate < n)
+	    glyphSet->devPrivates[glyphSet->maxPrivate] = (pointer)0;
+    }
+    glyphSet->devPrivates[n] = ptr;
+    return TRUE;
+}
+
+Bool
+GlyphInit (ScreenPtr pScreen)
+{
+    return TRUE;
+}
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
+{
+    CARD32	elt, step, s;
+    GlyphPtr	glyph;
+    GlyphRefPtr	table, gr, del;
+    CARD32	tableSize = hash->hashSet->size;
+
+    table = hash->table;
+    elt = signature % tableSize;
+    step = 0;
+    del = 0;
+    for (;;)
+    {
+	gr = &table[elt];
+	s = gr->signature;
+	glyph = gr->glyph;
+	if (!glyph)
+	{
+	    if (del)
+		gr = del;
+	    break;
+	}
+	if (glyph == DeletedGlyph)
+	{
+	    if (!del)
+		del = gr;
+	    else if (gr == del)
+		break;
+	}
+	else if (s == signature &&
+		 (!match || 
+		  memcmp (&compare->info, &glyph->info, compare->size) == 0))
+	{
+	    break;
+	}
+	if (!step)
+	{
+	    step = signature % hash->hashSet->rehash;
+	    if (!step)
+		step = 1;
+	}
+	elt += step;
+	if (elt >= tableSize)
+	    elt -= tableSize;
+    }
+    return gr;
+}
+
+CARD32
+HashGlyph (GlyphPtr glyph)
+{
+    CARD32  *bits = (CARD32 *) &(glyph->info);
+    CARD32  hash;
+    int	    n = glyph->size / sizeof (CARD32);
+
+    hash = 0;
+    while (n--)
+	hash ^= *bits++;
+    return hash;
+}
+
+#ifdef CHECK_DUPLICATES
+void
+DuplicateRef (GlyphPtr glyph, char *where)
+{
+    ErrorF ("Duplicate Glyph 0x%x from %s\n", glyph, where);
+}
+
+void
+CheckDuplicates (GlyphHashPtr hash, char *where)
+{
+    GlyphPtr	g;
+    int		i, j;
+
+    for (i = 0; i < hash->hashSet->size; i++)
+    {
+	g = hash->table[i].glyph;
+	if (!g || g == DeletedGlyph)
+	    continue;
+	for (j = i + 1; j < hash->hashSet->size; j++)
+	    if (hash->table[j].glyph == g)
+		DuplicateRef (g, where);
+    }
+}
+#else
+#define CheckDuplicates(a,b)
+#define DuplicateRef(a,b)
+#endif
+
+void
+FreeGlyph (GlyphPtr glyph, int format)
+{
+    CheckDuplicates (&globalGlyphs[format], "FreeGlyph");
+    if (--glyph->refcnt == 0)
+    {
+	GlyphRefPtr gr;
+	int	    i;
+	int	    first;
+
+	first = -1;
+	for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
+	    if (globalGlyphs[format].table[i].glyph == glyph)
+	    {
+		if (first != -1)
+		    DuplicateRef (glyph, "FreeGlyph check");
+		first = i;
+	    }
+
+	gr = FindGlyphRef (&globalGlyphs[format],
+			   HashGlyph (glyph), TRUE, glyph);
+	if (gr - globalGlyphs[format].table != first)
+	    DuplicateRef (glyph, "Found wrong one");
+	if (gr->glyph && gr->glyph != DeletedGlyph)
+	{
+	    gr->glyph = DeletedGlyph;
+	    gr->signature = 0;
+	    globalGlyphs[format].tableEntries--;
+	}
+	xfree (glyph);
+    }
+}
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
+{
+    GlyphRefPtr	    gr;
+    CARD32	    hash;
+
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
+    /* Locate existing matching glyph */
+    hash = HashGlyph (glyph);
+    gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph);
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+    {
+	xfree (glyph);
+	glyph = gr->glyph;
+    }
+    else
+    {
+	gr->glyph = glyph;
+	gr->signature = hash;
+	globalGlyphs[glyphSet->fdepth].tableEntries++;
+    }
+    
+    /* Insert/replace glyphset value */
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    ++glyph->refcnt;
+    if (gr->glyph && gr->glyph != DeletedGlyph)
+	FreeGlyph (gr->glyph, glyphSet->fdepth);
+    else
+	glyphSet->hash.tableEntries++;
+    gr->glyph = glyph;
+    gr->signature = id;
+    CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph bottom");
+}
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphRefPtr     gr;
+    GlyphPtr	    glyph;
+
+    gr = FindGlyphRef (&glyphSet->hash, id, FALSE, 0);
+    glyph = gr->glyph;
+    if (glyph && glyph != DeletedGlyph)
+    {
+	gr->glyph = DeletedGlyph;
+	glyphSet->hash.tableEntries--;
+	FreeGlyph (glyph, glyphSet->fdepth);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id)
+{
+    GlyphPtr        glyph;
+
+    glyph = FindGlyphRef (&glyphSet->hash, id, FALSE, 0)->glyph;
+    if (glyph == DeletedGlyph)
+	glyph = 0;
+    return glyph;
+}
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int fdepth)
+{
+    int		size;
+    GlyphPtr	glyph;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
+    if (!glyph)
+	return 0;
+    glyph->refcnt = 0;
+    glyph->size = size + sizeof (xGlyphInfo);
+    glyph->info = *gi;
+    return glyph;
+}
+    
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet)
+{
+    hash->table = (GlyphRefPtr) xalloc (hashSet->size * sizeof (GlyphRefRec));
+    if (!hash->table)
+	return FALSE;
+    memset (hash->table, 0, hashSet->size * sizeof (GlyphRefRec));
+    hash->hashSet = hashSet;
+    hash->tableEntries = 0;
+    return TRUE;
+}
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
+{
+    CARD32	    tableEntries;
+    GlyphHashSetPtr hashSet;
+    GlyphHashRec    newHash;
+    GlyphRefPtr	    gr;
+    GlyphPtr	    glyph;
+    int		    i;
+    int		    oldSize;
+    CARD32	    s;
+
+    tableEntries = hash->tableEntries + change;
+    hashSet = FindGlyphHashSet (tableEntries);
+    if (hashSet == hash->hashSet)
+	return TRUE;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash top");
+    if (!AllocateGlyphHash (&newHash, hashSet))
+	return FALSE;
+    if (hash->table)
+    {
+	oldSize = hash->hashSet->size;
+	for (i = 0; i < oldSize; i++)
+	{
+	    glyph = hash->table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+	    {
+		s = hash->table[i].signature;
+		gr = FindGlyphRef (&newHash, s, global, glyph);
+		gr->signature = s;
+		gr->glyph = glyph;
+		++newHash.tableEntries;
+	    }
+	}
+	xfree (hash->table);
+    }
+    *hash = newHash;
+    if (global)
+	CheckDuplicates (hash, "ResizeGlyphHash bottom");
+    return TRUE;
+}
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change)
+{
+    return (ResizeGlyphHash (&glyphSet->hash, change, FALSE) &&
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], change, TRUE));
+}
+			    
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format)
+{
+    GlyphSetPtr	glyphSet;
+    int size;
+    
+    if (!globalGlyphs[fdepth].hashSet)
+    {
+	if (!AllocateGlyphHash (&globalGlyphs[fdepth], &glyphHashSets[0]))
+	    return FALSE;
+    }
+
+    size = (sizeof (GlyphSetRec) +
+	    (sizeof (pointer) * _GlyphSetPrivateAllocateIndex));
+    glyphSet = xalloc (size);
+    if (!glyphSet)
+	return FALSE;
+    bzero((char *)glyphSet, size);
+    glyphSet->maxPrivate = _GlyphSetPrivateAllocateIndex - 1;
+    if (_GlyphSetPrivateAllocateIndex)
+	glyphSet->devPrivates = (pointer)(&glyphSet[1]);
+
+    if (!AllocateGlyphHash (&glyphSet->hash, &glyphHashSets[0]))
+    {
+	xfree (glyphSet);
+	return FALSE;
+    }
+    glyphSet->refcnt = 1;
+    glyphSet->fdepth = fdepth;
+    glyphSet->format = format;
+    return glyphSet;	
+}
+
+int
+FreeGlyphSet (pointer	value,
+	      XID       gid)
+{
+    GlyphSetPtr	glyphSet = (GlyphSetPtr) value;
+    
+    if (--glyphSet->refcnt == 0)
+    {
+	CARD32	    i, tableSize = glyphSet->hash.hashSet->size;
+	GlyphRefPtr table = glyphSet->hash.table;
+	GlyphPtr    glyph;
+    
+	for (i = 0; i < tableSize; i++)
+	{
+	    glyph = table[i].glyph;
+	    if (glyph && glyph != DeletedGlyph)
+		FreeGlyph (glyph, glyphSet->fdepth);
+	}
+	if (!globalGlyphs[glyphSet->fdepth].tableEntries)
+	{
+	    xfree (globalGlyphs[glyphSet->fdepth].table);
+	    globalGlyphs[glyphSet->fdepth].table = 0;
+	    globalGlyphs[glyphSet->fdepth].hashSet = 0;
+	}
+	else
+	    ResizeGlyphHash (&globalGlyphs[glyphSet->fdepth], 0, TRUE);
+	xfree (table);
+
+	if (glyphSet->devPrivates &&
+	    glyphSet->devPrivates != (pointer)(&glyphSet[1]))
+	    xfree(glyphSet->devPrivates);
+
+	xfree (glyphSet);
+    }
+    return Success;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
new file mode 100644
index 000000000..3e105ac64
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
@@ -0,0 +1,241 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/************************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+#include "../../fb/fb.h"
+#include "Pixmaps.h"
+
+#ifndef True
+#define True  1
+#endif
+
+/*
+    get the bits out of the font in a portable way.  to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+    since all screens return the same bitmap format, we'll just use
+the first one we find.
+    the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+    register ScreenPtr pScreen;
+    register GCPtr pGC;
+    xRectangle rect;
+    PixmapPtr ppix;
+    long nby;
+    char *pbits;
+    ChangeGCVal gcval[3];
+    unsigned char char2b[2];
+
+    /* turn glyph index into a protocol-format char2b */
+    char2b[0] = (unsigned char)(ch >> 8);
+    char2b[1] = (unsigned char)(ch & 0xff);
+
+    pScreen = screenInfo.screens[0];
+    nby = BitmapBytePad(cm->width) * (long)cm->height;
+    pbits = (char *)xalloc(nby);
+    if (!pbits)
+	return BadAlloc;
+    /* zeroing the (pad) bits seems to help some ddx cursor handling */
+    bzero(pbits, nby);
+
+    ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1);
+    pGC = GetScratchGC(1, pScreen);
+    if (!ppix || !pGC)
+    {
+	if (ppix)
+	    fbDestroyPixmap(ppix);
+	if (pGC)
+	    FreeScratchGC(pGC);
+	xfree(pbits);
+	return BadAlloc;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
+                (void *) ppix, cm->width, cm->height, 1);
+    #endif
+
+    nxagentPixmapPriv(ppix) -> id = 0;
+    nxagentPixmapPriv(ppix) -> mid = 0;
+    nxagentPixmapPriv(ppix) -> isVirtual = True;
+    nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
+    nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = cm->width;
+    rect.height = cm->height;
+
+    pGC->stateChanges |= GCFunction | GCForeground | GCFont;
+    pGC->alu = GXcopy;
+
+    pGC->fgPixel = 0;
+
+    pfont->refcnt++;
+
+    if (pGC->font)
+      CloseFont(pGC->font, (Font)0);
+
+    pGC->font = pfont;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+
+    /* draw the glyph */
+    gcval[0].val = 1;
+    pGC->fgPixel = 1;
+
+    pGC->stateChanges |= GCForeground;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
+    fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+                         XYPixmap, 1, pbits);
+    *ppbits = (unsigned char *)pbits;
+    FreeScratchGC(pGC);
+    fbDestroyPixmap(ppix);
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
+                (void *) ppix);
+    #endif
+
+    return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+    CharInfoPtr 	pci;
+    unsigned long	nglyphs;
+    CARD8		chs[2];
+    FontEncoding	encoding;
+
+    chs[0] = ch >> 8;
+    chs[1] = ch;
+    encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+    if (encoding == Linear16Bit)
+    {
+	if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+	    return FALSE;
+    }
+    else
+    {
+	if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+	    return FALSE;
+	if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+	    return FALSE;
+    }
+    (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+    if (nglyphs == 0)
+	return FALSE;
+    cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+    cm->height = pci->metrics.descent + pci->metrics.ascent;
+    if (pci->metrics.leftSideBearing > 0)
+    {
+	cm->width += pci->metrics.leftSideBearing;
+	cm->xhot = 0;
+    }
+    else
+    {
+	cm->xhot = -pci->metrics.leftSideBearing;
+	if (pci->metrics.rightSideBearing < 0)
+	    cm->width -= pci->metrics.rightSideBearing;
+    }
+    if (pci->metrics.ascent < 0)
+    {
+	cm->height -= pci->metrics.ascent;
+	cm->yhot = 0;
+    }
+    else
+    {
+	cm->yhot = pci->metrics.ascent;
+	if (pci->metrics.descent < 0)
+	    cm->height -= pci->metrics.descent;
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
new file mode 100644
index 000000000..3e105ac64
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
@@ -0,0 +1,241 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/************************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+#include "../../fb/fb.h"
+#include "Pixmaps.h"
+
+#ifndef True
+#define True  1
+#endif
+
+/*
+    get the bits out of the font in a portable way.  to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+    since all screens return the same bitmap format, we'll just use
+the first one we find.
+    the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+    register ScreenPtr pScreen;
+    register GCPtr pGC;
+    xRectangle rect;
+    PixmapPtr ppix;
+    long nby;
+    char *pbits;
+    ChangeGCVal gcval[3];
+    unsigned char char2b[2];
+
+    /* turn glyph index into a protocol-format char2b */
+    char2b[0] = (unsigned char)(ch >> 8);
+    char2b[1] = (unsigned char)(ch & 0xff);
+
+    pScreen = screenInfo.screens[0];
+    nby = BitmapBytePad(cm->width) * (long)cm->height;
+    pbits = (char *)xalloc(nby);
+    if (!pbits)
+	return BadAlloc;
+    /* zeroing the (pad) bits seems to help some ddx cursor handling */
+    bzero(pbits, nby);
+
+    ppix = fbCreatePixmap(pScreen, cm->width, cm->height, 1);
+    pGC = GetScratchGC(1, pScreen);
+    if (!ppix || !pGC)
+    {
+	if (ppix)
+	    fbDestroyPixmap(ppix);
+	if (pGC)
+	    FreeScratchGC(pGC);
+	xfree(pbits);
+	return BadAlloc;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Created virtual pixmap at [%p] with width [%d] height [%d] depth [%d].\n",
+                (void *) ppix, cm->width, cm->height, 1);
+    #endif
+
+    nxagentPixmapPriv(ppix) -> id = 0;
+    nxagentPixmapPriv(ppix) -> mid = 0;
+    nxagentPixmapPriv(ppix) -> isVirtual = True;
+    nxagentPixmapPriv(ppix) -> pRealPixmap = NULL;
+    nxagentPixmapPriv(ppix) -> pVirtualPixmap = NULL;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = cm->width;
+    rect.height = cm->height;
+
+    pGC->stateChanges |= GCFunction | GCForeground | GCFont;
+    pGC->alu = GXcopy;
+
+    pGC->fgPixel = 0;
+
+    pfont->refcnt++;
+
+    if (pGC->font)
+      CloseFont(pGC->font, (Font)0);
+
+    pGC->font = pfont;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    fbPolyFillRect((DrawablePtr)ppix, pGC, 1, &rect);
+
+    /* draw the glyph */
+    gcval[0].val = 1;
+    pGC->fgPixel = 1;
+
+    pGC->stateChanges |= GCForeground;
+
+    ValidateGC((DrawablePtr)ppix, pGC);
+    miPolyText16((DrawablePtr)ppix, pGC, (int)cm->xhot, (int)cm->yhot, (int)1, (unsigned short*)char2b);
+    fbGetImage((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+                         XYPixmap, 1, pbits);
+    *ppbits = (unsigned char *)pbits;
+    FreeScratchGC(pGC);
+    fbDestroyPixmap(ppix);
+
+    #ifdef TEST
+    fprintf(stderr, "ServerBitsFromGlyph: Destroyed virtual pixmap at [%p].\n",
+                (void *) ppix);
+    #endif
+
+    return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+    CharInfoPtr 	pci;
+    unsigned long	nglyphs;
+    CARD8		chs[2];
+    FontEncoding	encoding;
+
+    chs[0] = ch >> 8;
+    chs[1] = ch;
+    encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+    if (encoding == Linear16Bit)
+    {
+	if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+	    return FALSE;
+    }
+    else
+    {
+	if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+	    return FALSE;
+	if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+	    return FALSE;
+    }
+    (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+    if (nglyphs == 0)
+	return FALSE;
+    cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+    cm->height = pci->metrics.descent + pci->metrics.ascent;
+    if (pci->metrics.leftSideBearing > 0)
+    {
+	cm->width += pci->metrics.leftSideBearing;
+	cm->xhot = 0;
+    }
+    else
+    {
+	cm->xhot = -pci->metrics.leftSideBearing;
+	if (pci->metrics.rightSideBearing < 0)
+	    cm->width -= pci->metrics.rightSideBearing;
+    }
+    if (pci->metrics.ascent < 0)
+    {
+	cm->height -= pci->metrics.ascent;
+	cm->yhot = 0;
+    }
+    else
+    {
+	cm->yhot = pci->metrics.ascent;
+	if (pci->metrics.descent < 0)
+	    cm->height -= pci->metrics.descent;
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original
new file mode 100644
index 000000000..8f8adf5ce
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.X.original
@@ -0,0 +1,194 @@
+/************************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+************************************************************************/
+
+/* $Xorg: glyphcurs.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "resource.h"
+#include "dix.h"
+#include "cursorstr.h"
+#include "opaque.h"
+#include "servermd.h"
+
+
+/*
+    get the bits out of the font in a portable way.  to avoid
+dealing with padding and such-like, we draw the glyph into
+a bitmap, then read the bits out with GetImage, which
+uses server-natural format.
+    since all screens return the same bitmap format, we'll just use
+the first one we find.
+    the character origin lines up with the hotspot in the
+cursor metrics.
+*/
+
+int
+ServerBitsFromGlyph(FontPtr pfont, unsigned ch, register CursorMetricPtr cm, unsigned char **ppbits)
+{
+    register ScreenPtr pScreen;
+    register GCPtr pGC;
+    xRectangle rect;
+    PixmapPtr ppix;
+    long nby;
+    char *pbits;
+    ChangeGCVal gcval[3];
+    unsigned char char2b[2];
+
+    /* turn glyph index into a protocol-format char2b */
+    char2b[0] = (unsigned char)(ch >> 8);
+    char2b[1] = (unsigned char)(ch & 0xff);
+
+    pScreen = screenInfo.screens[0];
+    nby = BitmapBytePad(cm->width) * (long)cm->height;
+    pbits = (char *)xalloc(nby);
+    if (!pbits)
+	return BadAlloc;
+    /* zeroing the (pad) bits seems to help some ddx cursor handling */
+    bzero(pbits, nby);
+
+    ppix = (PixmapPtr)(*pScreen->CreatePixmap)(pScreen, cm->width,
+					       cm->height, 1);
+    pGC = GetScratchGC(1, pScreen);
+    if (!ppix || !pGC)
+    {
+	if (ppix)
+	    (*pScreen->DestroyPixmap)(ppix);
+	if (pGC)
+	    FreeScratchGC(pGC);
+	xfree(pbits);
+	return BadAlloc;
+    }
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = cm->width;
+    rect.height = cm->height;
+
+    /* fill the pixmap with 0 */
+    gcval[0].val = GXcopy;
+    gcval[1].val = 0;
+    gcval[2].ptr = (pointer)pfont;
+    dixChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFont,
+		NULL, gcval);
+    ValidateGC((DrawablePtr)ppix, pGC);
+    (*pGC->ops->PolyFillRect)((DrawablePtr)ppix, pGC, 1, &rect);
+
+    /* draw the glyph */
+    gcval[0].val = 1;
+    dixChangeGC(NullClient, pGC, GCForeground, NULL, gcval);
+    ValidateGC((DrawablePtr)ppix, pGC);
+    (*pGC->ops->PolyText16)((DrawablePtr)ppix, pGC, cm->xhot, cm->yhot,
+			    1, (unsigned short *)char2b);
+    (*pScreen->GetImage)((DrawablePtr)ppix, 0, 0, cm->width, cm->height,
+			 XYPixmap, 1, pbits);
+    *ppbits = (unsigned char *)pbits;
+    FreeScratchGC(pGC);
+    (*pScreen->DestroyPixmap)(ppix);
+    return Success;
+}
+
+
+Bool
+CursorMetricsFromGlyph(register FontPtr pfont, unsigned ch, register CursorMetricPtr cm)
+{
+    CharInfoPtr 	pci;
+    unsigned long	nglyphs;
+    CARD8		chs[2];
+    FontEncoding	encoding;
+
+    chs[0] = ch >> 8;
+    chs[1] = ch;
+    encoding = (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit;
+    if (encoding == Linear16Bit)
+    {
+	if (ch < pfont->info.firstCol || pfont->info.lastCol < ch)
+	    return FALSE;
+    }
+    else
+    {
+	if (chs[0] < pfont->info.firstRow || pfont->info.lastRow < chs[0])
+	    return FALSE;
+	if (chs[1] < pfont->info.firstCol || pfont->info.lastCol < chs[1])
+	    return FALSE;
+    }
+    (*pfont->get_glyphs) (pfont, 1, chs, encoding, &nglyphs, &pci);
+    if (nglyphs == 0)
+	return FALSE;
+    cm->width = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+    cm->height = pci->metrics.descent + pci->metrics.ascent;
+    if (pci->metrics.leftSideBearing > 0)
+    {
+	cm->width += pci->metrics.leftSideBearing;
+	cm->xhot = 0;
+    }
+    else
+    {
+	cm->xhot = -pci->metrics.leftSideBearing;
+	if (pci->metrics.rightSideBearing < 0)
+	    cm->width -= pci->metrics.rightSideBearing;
+    }
+    if (pci->metrics.ascent < 0)
+    {
+	cm->height -= pci->metrics.ascent;
+	cm->yhot = 0;
+    }
+    else
+    {
+	cm->yhot = pci->metrics.ascent;
+	if (pci->metrics.descent < 0)
+	    cm->height -= pci->metrics.descent;
+    }
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
new file mode 100644
index 000000000..0f30843d6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
@@ -0,0 +1,174 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.3 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original glyphstr.h
+ * or symbols  will be redefined. The code here adds a field
+ * to _GlyphSet. This should be done by defining a new type
+ * and casting when appropriate.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include <X11/extensions/renderproto.h>
+#include "../../render/picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1	0
+#define GlyphFormat4	1
+#define GlyphFormat8	2
+#define GlyphFormat16	3
+#define GlyphFormat32	4
+#define GlyphFormatNum	5
+
+typedef struct _Glyph {
+    CARD32	refcnt;
+    CARD32	size;	/* info + bitmap */
+    xGlyphInfo	info;
+    /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+    CARD32	signature;
+    GlyphPtr	glyph;
+    CARD16      corruptedGlyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph	((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+    CARD32	entries;
+    CARD32	size;
+    CARD32	rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+    GlyphRefPtr	    table;
+    GlyphHashSetPtr hashSet;
+    CARD32	    tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+    CARD32	    refcnt;
+    PictFormatPtr   format;
+    int		    fdepth;
+    GlyphHashRec    hash;
+    int             maxPrivate;
+    pointer         *devPrivates;
+    CARD32          remoteID;
+} GlyphSetRec, *GlyphSetPtr;
+
+#define GlyphSetGetPrivate(pGlyphSet,n)					\
+	((n) > (pGlyphSet)->maxPrivate ?				\
+	 (pointer) 0 :							\
+	 (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr)				\
+	((n) > (pGlyphSet)->maxPrivate ?				\
+	 _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) :			\
+	 ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
+typedef struct _GlyphList {
+    INT16	    xOff;
+    INT16	    yOff;
+    CARD8	    len;
+    PictFormatPtr   format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer   value,
+	      XID       gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
new file mode 100644
index 000000000..0f30843d6
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
@@ -0,0 +1,174 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.3 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original glyphstr.h
+ * or symbols  will be redefined. The code here adds a field
+ * to _GlyphSet. This should be done by defining a new type
+ * and casting when appropriate.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include <X11/extensions/renderproto.h>
+#include "../../render/picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1	0
+#define GlyphFormat4	1
+#define GlyphFormat8	2
+#define GlyphFormat16	3
+#define GlyphFormat32	4
+#define GlyphFormatNum	5
+
+typedef struct _Glyph {
+    CARD32	refcnt;
+    CARD32	size;	/* info + bitmap */
+    xGlyphInfo	info;
+    /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+    CARD32	signature;
+    GlyphPtr	glyph;
+    CARD16      corruptedGlyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph	((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+    CARD32	entries;
+    CARD32	size;
+    CARD32	rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+    GlyphRefPtr	    table;
+    GlyphHashSetPtr hashSet;
+    CARD32	    tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+    CARD32	    refcnt;
+    PictFormatPtr   format;
+    int		    fdepth;
+    GlyphHashRec    hash;
+    int             maxPrivate;
+    pointer         *devPrivates;
+    CARD32          remoteID;
+} GlyphSetRec, *GlyphSetPtr;
+
+#define GlyphSetGetPrivate(pGlyphSet,n)					\
+	((n) > (pGlyphSet)->maxPrivate ?				\
+	 (pointer) 0 :							\
+	 (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr)				\
+	((n) > (pGlyphSet)->maxPrivate ?				\
+	 _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) :			\
+	 ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
+typedef struct _GlyphList {
+    INT16	    xOff;
+    INT16	    yOff;
+    CARD8	    len;
+    PictFormatPtr   format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer   value,
+	      XID       gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original
new file mode 100644
index 000000000..f4777a248
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.X.original
@@ -0,0 +1,148 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/glyphstr.h,v 1.3 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _GLYPHSTR_H_
+#define _GLYPHSTR_H_
+
+#include <X11/extensions/renderproto.h>
+#include "picture.h"
+#include "screenint.h"
+
+#define GlyphFormat1	0
+#define GlyphFormat4	1
+#define GlyphFormat8	2
+#define GlyphFormat16	3
+#define GlyphFormat32	4
+#define GlyphFormatNum	5
+
+typedef struct _Glyph {
+    CARD32	refcnt;
+    CARD32	size;	/* info + bitmap */
+    xGlyphInfo	info;
+    /* bits follow */
+} GlyphRec, *GlyphPtr;
+
+typedef struct _GlyphRef {
+    CARD32	signature;
+    GlyphPtr	glyph;
+} GlyphRefRec, *GlyphRefPtr;
+
+#define DeletedGlyph	((GlyphPtr) 1)
+
+typedef struct _GlyphHashSet {
+    CARD32	entries;
+    CARD32	size;
+    CARD32	rehash;
+} GlyphHashSetRec, *GlyphHashSetPtr;
+
+typedef struct _GlyphHash {
+    GlyphRefPtr	    table;
+    GlyphHashSetPtr hashSet;
+    CARD32	    tableEntries;
+} GlyphHashRec, *GlyphHashPtr;
+
+typedef struct _GlyphSet {
+    CARD32	    refcnt;
+    PictFormatPtr   format;
+    int		    fdepth;
+    GlyphHashRec    hash;
+    int             maxPrivate;
+    pointer         *devPrivates;
+} GlyphSetRec, *GlyphSetPtr;
+
+#define GlyphSetGetPrivate(pGlyphSet,n)					\
+	((n) > (pGlyphSet)->maxPrivate ?				\
+	 (pointer) 0 :							\
+	 (pGlyphSet)->devPrivates[n])
+
+#define GlyphSetSetPrivate(pGlyphSet,n,ptr)				\
+	((n) > (pGlyphSet)->maxPrivate ?				\
+	 _GlyphSetSetNewPrivate(pGlyphSet, n, ptr) :			\
+	 ((((pGlyphSet)->devPrivates[n] = (ptr)) != 0) || TRUE))
+
+typedef struct _GlyphList {
+    INT16	    xOff;
+    INT16	    yOff;
+    CARD8	    len;
+    PictFormatPtr   format;
+} GlyphListRec, *GlyphListPtr;
+
+extern GlyphHashRec	globalGlyphs[GlyphFormatNum];
+
+GlyphHashSetPtr
+FindGlyphHashSet (CARD32 filled);
+
+int
+AllocateGlyphSetPrivateIndex (void);
+
+void
+ResetGlyphSetPrivateIndex (void);
+
+Bool
+_GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr);
+
+Bool
+GlyphInit (ScreenPtr pScreen);
+
+GlyphRefPtr
+FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare);
+
+CARD32
+HashGlyph (GlyphPtr glyph);
+
+void
+FreeGlyph (GlyphPtr glyph, int format);
+
+void
+AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id);
+
+Bool
+DeleteGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+FindGlyph (GlyphSetPtr glyphSet, Glyph id);
+
+GlyphPtr
+AllocateGlyph (xGlyphInfo *gi, int format);
+
+Bool
+AllocateGlyphHash (GlyphHashPtr hash, GlyphHashSetPtr hashSet);
+
+Bool
+ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global);
+
+Bool
+ResizeGlyphSet (GlyphSetPtr glyphSet, CARD32 change);
+
+GlyphSetPtr
+AllocateGlyphSet (int fdepth, PictFormatPtr format);
+
+int
+FreeGlyphSet (pointer   value,
+	      XID       gid);
+
+
+
+#endif /* _GLYPHSTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
new file mode 100644
index 000000000..af07fdcc2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
@@ -0,0 +1,979 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/mi/miexpose.c,v 1.6 2005/07/03 08:53:51 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <X11/Xprotostr.h>
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include <X11/Xmd.h>
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+    machine-independent graphics exposure code.  any device that uses
+the region package can call this.
+*/
+
+#ifdef NXAGENT_SERVER
+
+#include "Windows.h"
+
+#endif
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25		/* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures 
+    generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination.  Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+     this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+     added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+		  pGC, srcx, srcy, width, height, dstx, dsty, plane)
+    register DrawablePtr	pSrcDrawable;
+    register DrawablePtr	pDstDrawable;
+    GCPtr 			pGC;
+    int 			srcx, srcy;
+    int 			width, height;
+    int 			dstx, dsty;
+    unsigned long		plane;
+{
+    register ScreenPtr pscr;
+    RegionPtr prgnSrcClip;	/* drawable-relative source clip */
+    RegionRec rgnSrcRec;
+    RegionPtr prgnDstClip;	/* drawable-relative dest clip */
+    RegionRec rgnDstRec;
+    BoxRec srcBox;		/* unclipped source */
+    RegionRec rgnExposed;	/* exposed region, calculated source-
+				   relative, made dst relative to
+				   intersect with visible parts of
+				   dest and send events to client, 
+				   and then screen relative to paint 
+				   the window background
+				*/
+    WindowPtr pSrcWin;
+    BoxRec expBox;
+    Bool extents;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    expBox.x1 = 0;
+    expBox.y1 = 0;
+    expBox.x2 = 0;
+    expBox.y2 = 0;
+
+#endif
+
+    /* This prevents warning about pscr not being used. */
+    pGC->pScreen = pscr = pGC->pScreen;
+
+    /* avoid work if we can */
+    if (!pGC->graphicsExposures &&
+	(pDstDrawable->type == DRAWABLE_PIXMAP) &&
+	((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+	 (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+	return NULL;
+	
+    srcBox.x1 = srcx;
+    srcBox.y1 = srcy;
+    srcBox.x2 = srcx+width;
+    srcBox.y2 = srcy+height;
+
+    if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+    {
+	BoxRec TsrcBox;
+
+	TsrcBox.x1 = srcx + pSrcDrawable->x;
+	TsrcBox.y1 = srcy + pSrcDrawable->y;
+	TsrcBox.x2 = TsrcBox.x1 + width;
+	TsrcBox.y2 = TsrcBox.y1 + height;
+	pSrcWin = (WindowPtr) pSrcDrawable;
+	if (pGC->subWindowMode == IncludeInferiors)
+ 	{
+	    prgnSrcClip = NotClippedByChildren (pSrcWin);
+	    if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+	    {
+		REGION_DESTROY(pscr, prgnSrcClip);
+		return NULL;
+	    }
+	}
+ 	else
+ 	{
+	    if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+		return NULL;
+	    prgnSrcClip = &rgnSrcRec;
+	    REGION_NULL(pscr, prgnSrcClip);
+	    REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnSrcClip,
+				-pSrcDrawable->x, -pSrcDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+	    (srcBox.x2 <= pSrcDrawable->width) &&
+ 	    (srcBox.y2 <= pSrcDrawable->height))
+	    return NULL;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pSrcDrawable->width;
+	box.y2 = pSrcDrawable->height;
+	prgnSrcClip = &rgnSrcRec;
+	REGION_INIT(pscr, prgnSrcClip, &box, 1);
+	pSrcWin = (WindowPtr)NULL;
+    }
+
+    if (pDstDrawable == pSrcDrawable)
+    {
+	prgnDstClip = prgnSrcClip;
+    }
+    else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+    {
+	if (pGC->subWindowMode == IncludeInferiors)
+	{
+	    prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+	}
+	else
+	{
+	    prgnDstClip = &rgnDstRec;
+	    REGION_NULL(pscr, prgnDstClip);
+	    REGION_COPY(pscr, prgnDstClip,
+				&((WindowPtr)pDstDrawable)->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnDstClip,
+				 -pDstDrawable->x, -pDstDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pDstDrawable->width;
+	box.y2 = pDstDrawable->height;
+	prgnDstClip = &rgnDstRec;
+	REGION_INIT(pscr, prgnDstClip, &box, 1);
+    }
+
+    /* drawable-relative source region */
+    REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+    /* now get the hidden parts of the source box*/
+    REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+    if (pSrcWin && pSrcWin->backStorage)
+    {
+	/*
+	 * Copy any areas from the source backing store. Modifies
+	 * rgnExposed.
+	 */
+	(* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+					      pDstDrawable,
+					      pGC,
+					      &rgnExposed,
+					      srcx, srcy,
+					      dstx, dsty,
+					      plane);
+    }
+    
+    /* move them over the destination */
+    REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+    /* intersect with visible areas of dest */
+    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+    /*
+     * If we have LOTS of rectangles, we decide to take the extents
+     * and force an exposure on that.  This should require much less
+     * work overall, on both client and server.  This is cheating, but
+     * isn't prohibited by the protocol ("spontaneous combustion" :-)
+     * for windows.
+     */
+    extents = pGC->graphicsExposures &&
+	      (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+	      (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+    if (pSrcWin)
+    {
+	RegionPtr	region;
+    	if (!(region = wClipShape (pSrcWin)))
+    	    region = wBoundingShape (pSrcWin);
+    	/*
+     	 * If you try to CopyArea the extents of a shaped window, compacting the
+     	 * exposed region will undo all our work!
+     	 */
+    	if (extents && pSrcWin && region &&
+    	    (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+	    	extents = FALSE;
+    }
+#endif
+    if (extents)
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+	REGION_RESET(pscr, &rgnExposed, &expBox);
+	/* need to clear out new areas of backing store */
+	if (pWin->backStorage)
+	    (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					 pWin,
+					 expBox.x1,
+					 expBox.y1,
+					 expBox.x2 - expBox.x1,
+					 expBox.y2 - expBox.y1,
+					 FALSE);
+    }
+    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+	(((WindowPtr)pDstDrawable)->backgroundState != None))
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	/* make the exposed area screen-relative */
+	REGION_TRANSLATE(pscr, &rgnExposed, 
+				 pDstDrawable->x, pDstDrawable->y);
+
+	if (extents)
+	{
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+	}
+	(*pWin->drawable.pScreen->PaintWindowBackground)(
+			(WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+	if (extents)
+	{
+	    REGION_RESET(pscr, &rgnExposed, &expBox);
+	}
+	else
+	    REGION_TRANSLATE(pscr, &rgnExposed,
+				     -pDstDrawable->x, -pDstDrawable->y);
+    }
+    if (prgnDstClip == &rgnDstRec)
+    {
+	REGION_UNINIT(pscr, prgnDstClip);
+    }
+    else if (prgnDstClip != prgnSrcClip)
+    {
+	REGION_DESTROY(pscr, prgnDstClip);
+    }
+
+    if (prgnSrcClip == &rgnSrcRec)
+    {
+	REGION_UNINIT(pscr, prgnSrcClip);
+    }
+    else
+    {
+	REGION_DESTROY(pscr, prgnSrcClip);
+    }
+
+    if (pGC->graphicsExposures)
+    {
+	/* don't look */
+	RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+	*exposed = rgnExposed;
+	return exposed;
+    }
+    else
+    {
+	REGION_UNINIT(pscr, &rgnExposed);
+	return NULL;
+    }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+    ClientPtr	client;
+    RegionPtr	pRgn;
+    XID		drawable;
+    int	major;
+    int	minor;
+{
+    if (pRgn && !REGION_NIL(pRgn))
+    {
+        xEvent *pEvent;
+	register xEvent *pe;
+	register BoxPtr pBox;
+	register int i;
+	int numRects;
+
+	numRects = REGION_NUM_RECTS(pRgn);
+	pBox = REGION_RECTS(pRgn);
+	if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+		return;
+	pe = pEvent;
+
+	for (i=1; i<=numRects; i++, pe++, pBox++)
+	{
+	    pe->u.u.type = GraphicsExpose;
+	    pe->u.graphicsExposure.drawable = drawable;
+	    pe->u.graphicsExposure.x = pBox->x1;
+	    pe->u.graphicsExposure.y = pBox->y1;
+	    pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+	    pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+	    pe->u.graphicsExposure.count = numRects - i;
+	    pe->u.graphicsExposure.majorEvent = major;
+	    pe->u.graphicsExposure.minorEvent = minor;
+	}
+	TryClientEvents(client, pEvent, numRects,
+			    (Mask)0, NoEventMask, NullGrab);
+	DEALLOCATE_LOCAL(pEvent);
+    }
+    else
+    {
+        xEvent event;
+	event.u.u.type = NoExpose;
+	event.u.noExposure.drawable = drawable;
+	event.u.noExposure.majorEvent = major;
+	event.u.noExposure.minorEvent = minor;
+	TryClientEvents(client, &event, 1,
+	    (Mask)0, NoEventMask, NullGrab);
+    }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+    WindowPtr pWin;
+    RegionPtr pRgn;
+    register int dx, dy;
+{
+    register BoxPtr pBox;
+    int numRects;
+    register xEvent *pEvent, *pe;
+    register int i;
+
+    pBox = REGION_RECTS(pRgn);
+    numRects = REGION_NUM_RECTS(pRgn);
+    if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+	return;
+
+    for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+    {
+	pe->u.u.type = Expose;
+	pe->u.expose.window = pWin->drawable.id;
+	pe->u.expose.x = pBox->x1 - dx;
+	pe->u.expose.y = pBox->y1 - dy;
+	pe->u.expose.width = pBox->x2 - pBox->x1;
+	pe->u.expose.height = pBox->y2 - pBox->y1;
+	pe->u.expose.count = i;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	int scrnum = pWin->drawable.pScreen->myNum;
+	int x = 0, y = 0;
+	XID realWin = 0;
+
+	if(!pWin->parent) {
+	    x = panoramiXdataPtr[scrnum].x;
+	    y = panoramiXdataPtr[scrnum].y;
+	    pWin = WindowTable[0];
+	    realWin = pWin->drawable.id;
+	} else if (scrnum) {
+	    PanoramiXRes *win;
+	    win = PanoramiXFindIDByScrnum(XRT_WINDOW, 
+			pWin->drawable.id, scrnum);
+	    if(!win) {
+		DEALLOCATE_LOCAL(pEvent);
+		return;
+	    }
+	    realWin = win->info[0].id;
+	    pWin = LookupIDByType(realWin, RT_WINDOW);
+	}
+	if(x || y || scrnum)
+	  for (i = 0; i < numRects; i++) {
+	      pEvent[i].u.expose.window = realWin;
+	      pEvent[i].u.expose.x += x;
+	      pEvent[i].u.expose.y += y;
+	  }
+    }
+#endif
+
+    DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+    DEALLOCATE_LOCAL(pEvent);
+}
+
+void 
+miWindowExposures(pWin, prgn, other_exposed)
+    WindowPtr pWin;
+    register RegionPtr prgn, other_exposed;
+{
+#ifdef NXAGENT_SERVER
+
+    int total;
+
+#endif
+    RegionPtr   exposures = prgn;
+    if (pWin->backStorage && prgn)
+	/*
+	 * in some cases, backing store will cause a different
+	 * region to be exposed than needs to be repainted
+	 * (like when a window is mapped).  RestoreAreas is
+	 * allowed to return a region other than prgn,
+	 * in which case this routine will free the resultant
+	 * region.  If exposures is null, then no events will
+	 * be sent to the client; if prgn is empty
+	 * no areas will be repainted.
+	 */
+	exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+    if ((prgn && !REGION_NIL(prgn)) || 
+	(exposures && !REGION_NIL(exposures)) || other_exposed)
+    {
+	RegionRec   expRec;
+	int	    clientInterested;
+
+	/*
+	 * Restore from backing-store FIRST.
+	 */
+	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+	if (other_exposed)
+	{
+	    if (exposures)
+	    {
+		REGION_UNION(pWin->drawable.pScreen, other_exposed,
+						  exposures,
+					          other_exposed);
+		if (exposures != prgn)
+		    REGION_DESTROY(pWin->drawable.pScreen, exposures);
+	    }
+	    exposures = other_exposed;
+	}
+#ifdef NXAGENT_SERVER
+
+        /*
+         * If the number of rectangles is greater
+         * than 4, let the function decide.
+         */
+
+        total = REGION_NUM_RECTS(exposures);
+
+        if (clientInterested && exposures && (total > RECTLIMIT ||
+                (total > 4 && nxagentExtentsPredicate(total) == 1)))
+#else
+	if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+#endif
+	{
+	    /*
+	     * If we have LOTS of rectangles, we decide to take the extents
+	     * and force an exposure on that.  This should require much less
+	     * work overall, on both client and server.  This is cheating, but
+	     * isn't prohibited by the protocol ("spontaneous combustion" :-).
+	     */
+	    BoxRec box;
+
+	    box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+	    if (exposures == prgn) {
+		exposures = &expRec;
+		REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+		REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+	    } else {
+		REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+		REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+	    }
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+	    /* need to clear out new areas of backing store, too */
+	    if (pWin->backStorage)
+		(void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					     pWin,
+					     box.x1 - pWin->drawable.x,
+					     box.y1 - pWin->drawable.y,
+					     box.x2 - box.x1,
+					     box.y2 - box.y1,
+					     FALSE);
+	}
+	if (prgn && !REGION_NIL(prgn))
+	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+	if (clientInterested && exposures && !REGION_NIL(exposures))
+	    miSendExposures(pWin, exposures,
+			    pWin->drawable.x, pWin->drawable.y);
+	if (exposures == &expRec)
+	{
+	    REGION_UNINIT( pWin->drawable.pScreen, exposures);
+	}
+	else if (exposures && exposures != prgn && exposures != other_exposed)
+	    REGION_DESTROY( pWin->drawable.pScreen, exposures);
+	if (prgn)
+	    REGION_EMPTY( pWin->drawable.pScreen, prgn);
+    }
+    else if (exposures && exposures != prgn)
+	REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+    this code is highly unlikely.  it is not haile selassie.
+
+    there is some hair here.  we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used.  it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr	screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+    pointer value,
+    XID id)
+{
+    GCPtr pGC = (GCPtr)value;
+    screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+    FreeGC (pGC, id);
+    numGCs--;
+    if (!numGCs)
+	ResType = 0;
+
+    return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+    int	status;
+
+    Bool usingScratchGC = FALSE;
+    WindowPtr pRoot;
+	
+#define FUNCTION	0
+#define FOREGROUND	1
+#define TILE		2
+#define FILLSTYLE	3
+#define ABSX		4
+#define ABSY		5
+#define CLIPMASK	6
+#define SUBWINDOW	7
+#define COUNT_BITS	8
+
+    ChangeGCVal gcval[7];
+    ChangeGCVal newValues [COUNT_BITS];
+
+    BITS32 gcmask, index, mask;
+    RegionRec prgnWin;
+    DDXPointRec oldCorner;
+    BoxRec box;
+    WindowPtr	pBgWin;
+    GCPtr pGC;
+    register int i;
+    register BoxPtr pbox;
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    register xRectangle *prect;
+    int numRects;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    prgnWin.extents.x1 = 0;
+    prgnWin.extents.y1 = 0;
+    prgnWin.extents.x2 = 0;
+    prgnWin.extents.y2 = 0;
+
+    prgnWin.data = NULL;
+
+    oldCorner.x = 0;
+    oldCorner.y = 0;
+
+#endif
+
+    gcmask = 0;
+
+    if (what == PW_BACKGROUND)
+    {
+	switch (pWin->backgroundState) {
+	case None:
+	    return;
+	case ParentRelative:
+	    (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+	    return;
+	case BackgroundPixel:
+	    newValues[FOREGROUND].val = pWin->background.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	    break;
+	case BackgroundPixmap:
+	    newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	    break;
+	}
+    }
+    else
+    {
+	if (pWin->borderIsPixel)
+	{
+	    newValues[FOREGROUND].val = pWin->border.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	}
+	else
+	{
+	    newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	}
+    }
+
+    prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+					 sizeof(xRectangle));
+    if (!prect)
+	return;
+
+    newValues[FUNCTION].val = GXcopy;
+    gcmask |= GCFunction | GCClipMask;
+
+    i = pScreen->myNum;
+    pRoot = WindowTable[i];
+
+    pBgWin = pWin;
+    if (what == PW_BORDER)
+    {
+	while (pBgWin->backgroundState == ParentRelative)
+	    pBgWin = pBgWin->parent;
+    }
+
+    if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+	(pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+    {
+	usingScratchGC = TRUE;
+	pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+	if (!pGC)
+	{
+	    DEALLOCATE_LOCAL(prect);
+	    return;
+	}
+	/*
+	 * mash the clip list so we can paint the border by
+	 * mangling the window in place, pretending it
+	 * spans the entire screen
+	 */
+	if (what == PW_BORDER)
+	{
+	    prgnWin = pWin->clipList;
+	    oldCorner.x = pWin->drawable.x;
+	    oldCorner.y = pWin->drawable.y;
+	    pWin->drawable.x = pWin->drawable.y = 0;
+	    box.x1 = 0;
+	    box.y1 = 0;
+	    box.x2 = pScreen->width;
+	    box.y2 = pScreen->height;
+	    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    newValues[ABSX].val = pBgWin->drawable.x;
+	    newValues[ABSY].val = pBgWin->drawable.y;
+	}
+	else
+	{
+	    newValues[ABSX].val = 0;
+	    newValues[ABSY].val = 0;
+	}
+    } else {
+	/*
+	 * draw the background to the root window
+	 */
+	if (screenContext[i] == (GCPtr)NULL)
+	{
+	    if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+		return;
+	    screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+					(XID *)NULL, &status);
+	    if (!screenContext[i])
+		return;
+	    numGCs++;
+	    if (!AddResource(FakeClientID(0), ResType,
+			     (pointer)screenContext[i]))
+	        return;
+	}
+	pGC = screenContext[i];
+	newValues[SUBWINDOW].val = IncludeInferiors;
+	newValues[ABSX].val = pBgWin->drawable.x;
+	newValues[ABSY].val = pBgWin->drawable.y;
+	gcmask |= GCSubwindowMode;
+	pWin = pRoot;
+    }
+    
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+    mask = gcmask;
+    gcmask = 0;
+    i = 0;
+    while (mask) {
+    	index = lowbit (mask);
+	mask &= ~index;
+	switch (index) {
+	case GCFunction:
+	    if (pGC->alu != newValues[FUNCTION].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FUNCTION].val;
+	    }
+	    break;
+	case GCTileStipXOrigin:
+	    if ( pGC->patOrg.x != newValues[ABSX].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSX].val;
+	    }
+	    break;
+	case GCTileStipYOrigin:
+	    if ( pGC->patOrg.y != newValues[ABSY].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSY].val;
+	    }
+	    break;
+	case GCClipMask:
+	    if ( pGC->clientClipType != CT_NONE) {
+		gcmask |= index;
+		gcval[i++].val = CT_NONE;
+	    }
+	    break;
+	case GCSubwindowMode:
+	    if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[SUBWINDOW].val;
+	    }
+	    break;
+	case GCTile:
+	    if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ 	    {
+		gcmask |= index;
+		gcval[i++].ptr = newValues[TILE].ptr;
+	    }
+	    break;
+	case GCFillStyle:
+	    if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FILLSTYLE].val;
+	    }
+	    break;
+	case GCForeground:
+	    if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FOREGROUND].val;
+	    }
+	    break;
+	}
+    }
+
+    if (gcmask)
+        dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+    if (pWin->drawable.serialNumber != pGC->serialNumber)
+	ValidateGC((DrawablePtr)pWin, pGC);
+
+    numRects = REGION_NUM_RECTS(prgn);
+    pbox = REGION_RECTS(prgn);
+    for (i= numRects; --i >= 0; pbox++, prect++)
+    {
+	prect->x = pbox->x1 - pWin->drawable.x;
+	prect->y = pbox->y1 - pWin->drawable.y;
+	prect->width = pbox->x2 - pbox->x1;
+	prect->height = pbox->y2 - pbox->y1;
+    }
+    prect -= numRects;
+    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+    DEALLOCATE_LOCAL(prect);
+
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+    if (usingScratchGC)
+    {
+	if (what == PW_BORDER)
+	{
+	    REGION_UNINIT(pScreen, &pWin->clipList);
+	    pWin->clipList = prgnWin;
+	    pWin->drawable.x = oldCorner.x;
+	    pWin->drawable.y = oldCorner.y;
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	}
+	FreeScratchGC(pGC);
+    }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC.  Useful when we have a scratch drawable and need to initialize 
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+    DrawablePtr	pDraw;
+    GCPtr	pGC;
+{
+    XID fg = pGC->fgPixel;
+    XID bg = pGC->bgPixel;
+    xRectangle rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = pDraw->width;
+    rect.height = pDraw->height;
+    DoChangeGC(pGC, GCForeground, &bg, 0);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+    DoChangeGC(pGC, GCForeground, &fg, 0);
+    ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
new file mode 100644
index 000000000..af07fdcc2
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
@@ -0,0 +1,979 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/mi/miexpose.c,v 1.6 2005/07/03 08:53:51 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <X11/Xprotostr.h>
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include <X11/Xmd.h>
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+    machine-independent graphics exposure code.  any device that uses
+the region package can call this.
+*/
+
+#ifdef NXAGENT_SERVER
+
+#include "Windows.h"
+
+#endif
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25		/* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures 
+    generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination.  Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+     this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+     added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+		  pGC, srcx, srcy, width, height, dstx, dsty, plane)
+    register DrawablePtr	pSrcDrawable;
+    register DrawablePtr	pDstDrawable;
+    GCPtr 			pGC;
+    int 			srcx, srcy;
+    int 			width, height;
+    int 			dstx, dsty;
+    unsigned long		plane;
+{
+    register ScreenPtr pscr;
+    RegionPtr prgnSrcClip;	/* drawable-relative source clip */
+    RegionRec rgnSrcRec;
+    RegionPtr prgnDstClip;	/* drawable-relative dest clip */
+    RegionRec rgnDstRec;
+    BoxRec srcBox;		/* unclipped source */
+    RegionRec rgnExposed;	/* exposed region, calculated source-
+				   relative, made dst relative to
+				   intersect with visible parts of
+				   dest and send events to client, 
+				   and then screen relative to paint 
+				   the window background
+				*/
+    WindowPtr pSrcWin;
+    BoxRec expBox;
+    Bool extents;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    expBox.x1 = 0;
+    expBox.y1 = 0;
+    expBox.x2 = 0;
+    expBox.y2 = 0;
+
+#endif
+
+    /* This prevents warning about pscr not being used. */
+    pGC->pScreen = pscr = pGC->pScreen;
+
+    /* avoid work if we can */
+    if (!pGC->graphicsExposures &&
+	(pDstDrawable->type == DRAWABLE_PIXMAP) &&
+	((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+	 (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+	return NULL;
+	
+    srcBox.x1 = srcx;
+    srcBox.y1 = srcy;
+    srcBox.x2 = srcx+width;
+    srcBox.y2 = srcy+height;
+
+    if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+    {
+	BoxRec TsrcBox;
+
+	TsrcBox.x1 = srcx + pSrcDrawable->x;
+	TsrcBox.y1 = srcy + pSrcDrawable->y;
+	TsrcBox.x2 = TsrcBox.x1 + width;
+	TsrcBox.y2 = TsrcBox.y1 + height;
+	pSrcWin = (WindowPtr) pSrcDrawable;
+	if (pGC->subWindowMode == IncludeInferiors)
+ 	{
+	    prgnSrcClip = NotClippedByChildren (pSrcWin);
+	    if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+	    {
+		REGION_DESTROY(pscr, prgnSrcClip);
+		return NULL;
+	    }
+	}
+ 	else
+ 	{
+	    if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+		return NULL;
+	    prgnSrcClip = &rgnSrcRec;
+	    REGION_NULL(pscr, prgnSrcClip);
+	    REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnSrcClip,
+				-pSrcDrawable->x, -pSrcDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+	    (srcBox.x2 <= pSrcDrawable->width) &&
+ 	    (srcBox.y2 <= pSrcDrawable->height))
+	    return NULL;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pSrcDrawable->width;
+	box.y2 = pSrcDrawable->height;
+	prgnSrcClip = &rgnSrcRec;
+	REGION_INIT(pscr, prgnSrcClip, &box, 1);
+	pSrcWin = (WindowPtr)NULL;
+    }
+
+    if (pDstDrawable == pSrcDrawable)
+    {
+	prgnDstClip = prgnSrcClip;
+    }
+    else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+    {
+	if (pGC->subWindowMode == IncludeInferiors)
+	{
+	    prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+	}
+	else
+	{
+	    prgnDstClip = &rgnDstRec;
+	    REGION_NULL(pscr, prgnDstClip);
+	    REGION_COPY(pscr, prgnDstClip,
+				&((WindowPtr)pDstDrawable)->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnDstClip,
+				 -pDstDrawable->x, -pDstDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pDstDrawable->width;
+	box.y2 = pDstDrawable->height;
+	prgnDstClip = &rgnDstRec;
+	REGION_INIT(pscr, prgnDstClip, &box, 1);
+    }
+
+    /* drawable-relative source region */
+    REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+    /* now get the hidden parts of the source box*/
+    REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+    if (pSrcWin && pSrcWin->backStorage)
+    {
+	/*
+	 * Copy any areas from the source backing store. Modifies
+	 * rgnExposed.
+	 */
+	(* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+					      pDstDrawable,
+					      pGC,
+					      &rgnExposed,
+					      srcx, srcy,
+					      dstx, dsty,
+					      plane);
+    }
+    
+    /* move them over the destination */
+    REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+    /* intersect with visible areas of dest */
+    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+    /*
+     * If we have LOTS of rectangles, we decide to take the extents
+     * and force an exposure on that.  This should require much less
+     * work overall, on both client and server.  This is cheating, but
+     * isn't prohibited by the protocol ("spontaneous combustion" :-)
+     * for windows.
+     */
+    extents = pGC->graphicsExposures &&
+	      (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+	      (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+    if (pSrcWin)
+    {
+	RegionPtr	region;
+    	if (!(region = wClipShape (pSrcWin)))
+    	    region = wBoundingShape (pSrcWin);
+    	/*
+     	 * If you try to CopyArea the extents of a shaped window, compacting the
+     	 * exposed region will undo all our work!
+     	 */
+    	if (extents && pSrcWin && region &&
+    	    (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+	    	extents = FALSE;
+    }
+#endif
+    if (extents)
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+	REGION_RESET(pscr, &rgnExposed, &expBox);
+	/* need to clear out new areas of backing store */
+	if (pWin->backStorage)
+	    (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					 pWin,
+					 expBox.x1,
+					 expBox.y1,
+					 expBox.x2 - expBox.x1,
+					 expBox.y2 - expBox.y1,
+					 FALSE);
+    }
+    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+	(((WindowPtr)pDstDrawable)->backgroundState != None))
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	/* make the exposed area screen-relative */
+	REGION_TRANSLATE(pscr, &rgnExposed, 
+				 pDstDrawable->x, pDstDrawable->y);
+
+	if (extents)
+	{
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+	}
+	(*pWin->drawable.pScreen->PaintWindowBackground)(
+			(WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+	if (extents)
+	{
+	    REGION_RESET(pscr, &rgnExposed, &expBox);
+	}
+	else
+	    REGION_TRANSLATE(pscr, &rgnExposed,
+				     -pDstDrawable->x, -pDstDrawable->y);
+    }
+    if (prgnDstClip == &rgnDstRec)
+    {
+	REGION_UNINIT(pscr, prgnDstClip);
+    }
+    else if (prgnDstClip != prgnSrcClip)
+    {
+	REGION_DESTROY(pscr, prgnDstClip);
+    }
+
+    if (prgnSrcClip == &rgnSrcRec)
+    {
+	REGION_UNINIT(pscr, prgnSrcClip);
+    }
+    else
+    {
+	REGION_DESTROY(pscr, prgnSrcClip);
+    }
+
+    if (pGC->graphicsExposures)
+    {
+	/* don't look */
+	RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+	*exposed = rgnExposed;
+	return exposed;
+    }
+    else
+    {
+	REGION_UNINIT(pscr, &rgnExposed);
+	return NULL;
+    }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+    ClientPtr	client;
+    RegionPtr	pRgn;
+    XID		drawable;
+    int	major;
+    int	minor;
+{
+    if (pRgn && !REGION_NIL(pRgn))
+    {
+        xEvent *pEvent;
+	register xEvent *pe;
+	register BoxPtr pBox;
+	register int i;
+	int numRects;
+
+	numRects = REGION_NUM_RECTS(pRgn);
+	pBox = REGION_RECTS(pRgn);
+	if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+		return;
+	pe = pEvent;
+
+	for (i=1; i<=numRects; i++, pe++, pBox++)
+	{
+	    pe->u.u.type = GraphicsExpose;
+	    pe->u.graphicsExposure.drawable = drawable;
+	    pe->u.graphicsExposure.x = pBox->x1;
+	    pe->u.graphicsExposure.y = pBox->y1;
+	    pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+	    pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+	    pe->u.graphicsExposure.count = numRects - i;
+	    pe->u.graphicsExposure.majorEvent = major;
+	    pe->u.graphicsExposure.minorEvent = minor;
+	}
+	TryClientEvents(client, pEvent, numRects,
+			    (Mask)0, NoEventMask, NullGrab);
+	DEALLOCATE_LOCAL(pEvent);
+    }
+    else
+    {
+        xEvent event;
+	event.u.u.type = NoExpose;
+	event.u.noExposure.drawable = drawable;
+	event.u.noExposure.majorEvent = major;
+	event.u.noExposure.minorEvent = minor;
+	TryClientEvents(client, &event, 1,
+	    (Mask)0, NoEventMask, NullGrab);
+    }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+    WindowPtr pWin;
+    RegionPtr pRgn;
+    register int dx, dy;
+{
+    register BoxPtr pBox;
+    int numRects;
+    register xEvent *pEvent, *pe;
+    register int i;
+
+    pBox = REGION_RECTS(pRgn);
+    numRects = REGION_NUM_RECTS(pRgn);
+    if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+	return;
+
+    for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+    {
+	pe->u.u.type = Expose;
+	pe->u.expose.window = pWin->drawable.id;
+	pe->u.expose.x = pBox->x1 - dx;
+	pe->u.expose.y = pBox->y1 - dy;
+	pe->u.expose.width = pBox->x2 - pBox->x1;
+	pe->u.expose.height = pBox->y2 - pBox->y1;
+	pe->u.expose.count = i;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	int scrnum = pWin->drawable.pScreen->myNum;
+	int x = 0, y = 0;
+	XID realWin = 0;
+
+	if(!pWin->parent) {
+	    x = panoramiXdataPtr[scrnum].x;
+	    y = panoramiXdataPtr[scrnum].y;
+	    pWin = WindowTable[0];
+	    realWin = pWin->drawable.id;
+	} else if (scrnum) {
+	    PanoramiXRes *win;
+	    win = PanoramiXFindIDByScrnum(XRT_WINDOW, 
+			pWin->drawable.id, scrnum);
+	    if(!win) {
+		DEALLOCATE_LOCAL(pEvent);
+		return;
+	    }
+	    realWin = win->info[0].id;
+	    pWin = LookupIDByType(realWin, RT_WINDOW);
+	}
+	if(x || y || scrnum)
+	  for (i = 0; i < numRects; i++) {
+	      pEvent[i].u.expose.window = realWin;
+	      pEvent[i].u.expose.x += x;
+	      pEvent[i].u.expose.y += y;
+	  }
+    }
+#endif
+
+    DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+    DEALLOCATE_LOCAL(pEvent);
+}
+
+void 
+miWindowExposures(pWin, prgn, other_exposed)
+    WindowPtr pWin;
+    register RegionPtr prgn, other_exposed;
+{
+#ifdef NXAGENT_SERVER
+
+    int total;
+
+#endif
+    RegionPtr   exposures = prgn;
+    if (pWin->backStorage && prgn)
+	/*
+	 * in some cases, backing store will cause a different
+	 * region to be exposed than needs to be repainted
+	 * (like when a window is mapped).  RestoreAreas is
+	 * allowed to return a region other than prgn,
+	 * in which case this routine will free the resultant
+	 * region.  If exposures is null, then no events will
+	 * be sent to the client; if prgn is empty
+	 * no areas will be repainted.
+	 */
+	exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+    if ((prgn && !REGION_NIL(prgn)) || 
+	(exposures && !REGION_NIL(exposures)) || other_exposed)
+    {
+	RegionRec   expRec;
+	int	    clientInterested;
+
+	/*
+	 * Restore from backing-store FIRST.
+	 */
+	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+	if (other_exposed)
+	{
+	    if (exposures)
+	    {
+		REGION_UNION(pWin->drawable.pScreen, other_exposed,
+						  exposures,
+					          other_exposed);
+		if (exposures != prgn)
+		    REGION_DESTROY(pWin->drawable.pScreen, exposures);
+	    }
+	    exposures = other_exposed;
+	}
+#ifdef NXAGENT_SERVER
+
+        /*
+         * If the number of rectangles is greater
+         * than 4, let the function decide.
+         */
+
+        total = REGION_NUM_RECTS(exposures);
+
+        if (clientInterested && exposures && (total > RECTLIMIT ||
+                (total > 4 && nxagentExtentsPredicate(total) == 1)))
+#else
+	if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+#endif
+	{
+	    /*
+	     * If we have LOTS of rectangles, we decide to take the extents
+	     * and force an exposure on that.  This should require much less
+	     * work overall, on both client and server.  This is cheating, but
+	     * isn't prohibited by the protocol ("spontaneous combustion" :-).
+	     */
+	    BoxRec box;
+
+	    box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+	    if (exposures == prgn) {
+		exposures = &expRec;
+		REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+		REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+	    } else {
+		REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+		REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+	    }
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+	    /* need to clear out new areas of backing store, too */
+	    if (pWin->backStorage)
+		(void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					     pWin,
+					     box.x1 - pWin->drawable.x,
+					     box.y1 - pWin->drawable.y,
+					     box.x2 - box.x1,
+					     box.y2 - box.y1,
+					     FALSE);
+	}
+	if (prgn && !REGION_NIL(prgn))
+	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+	if (clientInterested && exposures && !REGION_NIL(exposures))
+	    miSendExposures(pWin, exposures,
+			    pWin->drawable.x, pWin->drawable.y);
+	if (exposures == &expRec)
+	{
+	    REGION_UNINIT( pWin->drawable.pScreen, exposures);
+	}
+	else if (exposures && exposures != prgn && exposures != other_exposed)
+	    REGION_DESTROY( pWin->drawable.pScreen, exposures);
+	if (prgn)
+	    REGION_EMPTY( pWin->drawable.pScreen, prgn);
+    }
+    else if (exposures && exposures != prgn)
+	REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+    this code is highly unlikely.  it is not haile selassie.
+
+    there is some hair here.  we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used.  it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr	screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+    pointer value,
+    XID id)
+{
+    GCPtr pGC = (GCPtr)value;
+    screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+    FreeGC (pGC, id);
+    numGCs--;
+    if (!numGCs)
+	ResType = 0;
+
+    return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+    int	status;
+
+    Bool usingScratchGC = FALSE;
+    WindowPtr pRoot;
+	
+#define FUNCTION	0
+#define FOREGROUND	1
+#define TILE		2
+#define FILLSTYLE	3
+#define ABSX		4
+#define ABSY		5
+#define CLIPMASK	6
+#define SUBWINDOW	7
+#define COUNT_BITS	8
+
+    ChangeGCVal gcval[7];
+    ChangeGCVal newValues [COUNT_BITS];
+
+    BITS32 gcmask, index, mask;
+    RegionRec prgnWin;
+    DDXPointRec oldCorner;
+    BoxRec box;
+    WindowPtr	pBgWin;
+    GCPtr pGC;
+    register int i;
+    register BoxPtr pbox;
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    register xRectangle *prect;
+    int numRects;
+
+#ifdef NXAGENT_SERVER
+
+    /*
+     * Set the elements reported by the compiler
+     * as uninitialized.
+     */
+
+    prgnWin.extents.x1 = 0;
+    prgnWin.extents.y1 = 0;
+    prgnWin.extents.x2 = 0;
+    prgnWin.extents.y2 = 0;
+
+    prgnWin.data = NULL;
+
+    oldCorner.x = 0;
+    oldCorner.y = 0;
+
+#endif
+
+    gcmask = 0;
+
+    if (what == PW_BACKGROUND)
+    {
+	switch (pWin->backgroundState) {
+	case None:
+	    return;
+	case ParentRelative:
+	    (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+	    return;
+	case BackgroundPixel:
+	    newValues[FOREGROUND].val = pWin->background.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	    break;
+	case BackgroundPixmap:
+	    newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	    break;
+	}
+    }
+    else
+    {
+	if (pWin->borderIsPixel)
+	{
+	    newValues[FOREGROUND].val = pWin->border.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	}
+	else
+	{
+	    newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	}
+    }
+
+    prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+					 sizeof(xRectangle));
+    if (!prect)
+	return;
+
+    newValues[FUNCTION].val = GXcopy;
+    gcmask |= GCFunction | GCClipMask;
+
+    i = pScreen->myNum;
+    pRoot = WindowTable[i];
+
+    pBgWin = pWin;
+    if (what == PW_BORDER)
+    {
+	while (pBgWin->backgroundState == ParentRelative)
+	    pBgWin = pBgWin->parent;
+    }
+
+    if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+	(pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+    {
+	usingScratchGC = TRUE;
+	pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+	if (!pGC)
+	{
+	    DEALLOCATE_LOCAL(prect);
+	    return;
+	}
+	/*
+	 * mash the clip list so we can paint the border by
+	 * mangling the window in place, pretending it
+	 * spans the entire screen
+	 */
+	if (what == PW_BORDER)
+	{
+	    prgnWin = pWin->clipList;
+	    oldCorner.x = pWin->drawable.x;
+	    oldCorner.y = pWin->drawable.y;
+	    pWin->drawable.x = pWin->drawable.y = 0;
+	    box.x1 = 0;
+	    box.y1 = 0;
+	    box.x2 = pScreen->width;
+	    box.y2 = pScreen->height;
+	    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    newValues[ABSX].val = pBgWin->drawable.x;
+	    newValues[ABSY].val = pBgWin->drawable.y;
+	}
+	else
+	{
+	    newValues[ABSX].val = 0;
+	    newValues[ABSY].val = 0;
+	}
+    } else {
+	/*
+	 * draw the background to the root window
+	 */
+	if (screenContext[i] == (GCPtr)NULL)
+	{
+	    if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+		return;
+	    screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+					(XID *)NULL, &status);
+	    if (!screenContext[i])
+		return;
+	    numGCs++;
+	    if (!AddResource(FakeClientID(0), ResType,
+			     (pointer)screenContext[i]))
+	        return;
+	}
+	pGC = screenContext[i];
+	newValues[SUBWINDOW].val = IncludeInferiors;
+	newValues[ABSX].val = pBgWin->drawable.x;
+	newValues[ABSY].val = pBgWin->drawable.y;
+	gcmask |= GCSubwindowMode;
+	pWin = pRoot;
+    }
+    
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+    mask = gcmask;
+    gcmask = 0;
+    i = 0;
+    while (mask) {
+    	index = lowbit (mask);
+	mask &= ~index;
+	switch (index) {
+	case GCFunction:
+	    if (pGC->alu != newValues[FUNCTION].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FUNCTION].val;
+	    }
+	    break;
+	case GCTileStipXOrigin:
+	    if ( pGC->patOrg.x != newValues[ABSX].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSX].val;
+	    }
+	    break;
+	case GCTileStipYOrigin:
+	    if ( pGC->patOrg.y != newValues[ABSY].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSY].val;
+	    }
+	    break;
+	case GCClipMask:
+	    if ( pGC->clientClipType != CT_NONE) {
+		gcmask |= index;
+		gcval[i++].val = CT_NONE;
+	    }
+	    break;
+	case GCSubwindowMode:
+	    if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[SUBWINDOW].val;
+	    }
+	    break;
+	case GCTile:
+	    if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ 	    {
+		gcmask |= index;
+		gcval[i++].ptr = newValues[TILE].ptr;
+	    }
+	    break;
+	case GCFillStyle:
+	    if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FILLSTYLE].val;
+	    }
+	    break;
+	case GCForeground:
+	    if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FOREGROUND].val;
+	    }
+	    break;
+	}
+    }
+
+    if (gcmask)
+        dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+    if (pWin->drawable.serialNumber != pGC->serialNumber)
+	ValidateGC((DrawablePtr)pWin, pGC);
+
+    numRects = REGION_NUM_RECTS(prgn);
+    pbox = REGION_RECTS(prgn);
+    for (i= numRects; --i >= 0; pbox++, prect++)
+    {
+	prect->x = pbox->x1 - pWin->drawable.x;
+	prect->y = pbox->y1 - pWin->drawable.y;
+	prect->width = pbox->x2 - pbox->x1;
+	prect->height = pbox->y2 - pbox->y1;
+    }
+    prect -= numRects;
+    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+    DEALLOCATE_LOCAL(prect);
+
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+    if (usingScratchGC)
+    {
+	if (what == PW_BORDER)
+	{
+	    REGION_UNINIT(pScreen, &pWin->clipList);
+	    pWin->clipList = prgnWin;
+	    pWin->drawable.x = oldCorner.x;
+	    pWin->drawable.y = oldCorner.y;
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	}
+	FreeScratchGC(pGC);
+    }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC.  Useful when we have a scratch drawable and need to initialize 
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+    DrawablePtr	pDraw;
+    GCPtr	pGC;
+{
+    XID fg = pGC->fgPixel;
+    XID bg = pGC->bgPixel;
+    xRectangle rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = pDraw->width;
+    rect.height = pDraw->height;
+    DoChangeGC(pGC, GCForeground, &bg, 0);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+    DoChangeGC(pGC, GCForeground, &fg, 0);
+    ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original
new file mode 100644
index 000000000..9a0bd06b5
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.X.original
@@ -0,0 +1,905 @@
+/* $XdotOrg: xc/programs/Xserver/mi/miexpose.c,v 1.6 2005/07/03 08:53:51 daniels Exp $ */
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $Xorg: miexpose.c,v 1.4 2001/02/09 02:05:20 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include <X11/Xprotostr.h>
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include <X11/Xmd.h>
+
+#include "globals.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+/*
+    machine-independent graphics exposure code.  any device that uses
+the region package can call this.
+*/
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25		/* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures 
+    generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination.  Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+     this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+     added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+		  pGC, srcx, srcy, width, height, dstx, dsty, plane)
+    register DrawablePtr	pSrcDrawable;
+    register DrawablePtr	pDstDrawable;
+    GCPtr 			pGC;
+    int 			srcx, srcy;
+    int 			width, height;
+    int 			dstx, dsty;
+    unsigned long		plane;
+{
+    register ScreenPtr pscr;
+    RegionPtr prgnSrcClip;	/* drawable-relative source clip */
+    RegionRec rgnSrcRec;
+    RegionPtr prgnDstClip;	/* drawable-relative dest clip */
+    RegionRec rgnDstRec;
+    BoxRec srcBox;		/* unclipped source */
+    RegionRec rgnExposed;	/* exposed region, calculated source-
+				   relative, made dst relative to
+				   intersect with visible parts of
+				   dest and send events to client, 
+				   and then screen relative to paint 
+				   the window background
+				*/
+    WindowPtr pSrcWin;
+    BoxRec expBox;
+    Bool extents;
+
+    /* This prevents warning about pscr not being used. */
+    pGC->pScreen = pscr = pGC->pScreen;
+
+    /* avoid work if we can */
+    if (!pGC->graphicsExposures &&
+	(pDstDrawable->type == DRAWABLE_PIXMAP) &&
+	((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+	 (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+	return NULL;
+	
+    srcBox.x1 = srcx;
+    srcBox.y1 = srcy;
+    srcBox.x2 = srcx+width;
+    srcBox.y2 = srcy+height;
+
+    if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+    {
+	BoxRec TsrcBox;
+
+	TsrcBox.x1 = srcx + pSrcDrawable->x;
+	TsrcBox.y1 = srcy + pSrcDrawable->y;
+	TsrcBox.x2 = TsrcBox.x1 + width;
+	TsrcBox.y2 = TsrcBox.y1 + height;
+	pSrcWin = (WindowPtr) pSrcDrawable;
+	if (pGC->subWindowMode == IncludeInferiors)
+ 	{
+	    prgnSrcClip = NotClippedByChildren (pSrcWin);
+	    if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+	    {
+		REGION_DESTROY(pscr, prgnSrcClip);
+		return NULL;
+	    }
+	}
+ 	else
+ 	{
+	    if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+		return NULL;
+	    prgnSrcClip = &rgnSrcRec;
+	    REGION_NULL(pscr, prgnSrcClip);
+	    REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnSrcClip,
+				-pSrcDrawable->x, -pSrcDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+	    (srcBox.x2 <= pSrcDrawable->width) &&
+ 	    (srcBox.y2 <= pSrcDrawable->height))
+	    return NULL;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pSrcDrawable->width;
+	box.y2 = pSrcDrawable->height;
+	prgnSrcClip = &rgnSrcRec;
+	REGION_INIT(pscr, prgnSrcClip, &box, 1);
+	pSrcWin = (WindowPtr)NULL;
+    }
+
+    if (pDstDrawable == pSrcDrawable)
+    {
+	prgnDstClip = prgnSrcClip;
+    }
+    else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+    {
+	if (pGC->subWindowMode == IncludeInferiors)
+	{
+	    prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+	}
+	else
+	{
+	    prgnDstClip = &rgnDstRec;
+	    REGION_NULL(pscr, prgnDstClip);
+	    REGION_COPY(pscr, prgnDstClip,
+				&((WindowPtr)pDstDrawable)->clipList);
+	}
+	REGION_TRANSLATE(pscr, prgnDstClip,
+				 -pDstDrawable->x, -pDstDrawable->y);
+    }
+    else
+    {
+	BoxRec	box;
+
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pDstDrawable->width;
+	box.y2 = pDstDrawable->height;
+	prgnDstClip = &rgnDstRec;
+	REGION_INIT(pscr, prgnDstClip, &box, 1);
+    }
+
+    /* drawable-relative source region */
+    REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+    /* now get the hidden parts of the source box*/
+    REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+    if (pSrcWin && pSrcWin->backStorage)
+    {
+	/*
+	 * Copy any areas from the source backing store. Modifies
+	 * rgnExposed.
+	 */
+	(* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+					      pDstDrawable,
+					      pGC,
+					      &rgnExposed,
+					      srcx, srcy,
+					      dstx, dsty,
+					      plane);
+    }
+    
+    /* move them over the destination */
+    REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+    /* intersect with visible areas of dest */
+    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+    /*
+     * If we have LOTS of rectangles, we decide to take the extents
+     * and force an exposure on that.  This should require much less
+     * work overall, on both client and server.  This is cheating, but
+     * isn't prohibited by the protocol ("spontaneous combustion" :-)
+     * for windows.
+     */
+    extents = pGC->graphicsExposures &&
+	      (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+	      (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+    if (pSrcWin)
+    {
+	RegionPtr	region;
+    	if (!(region = wClipShape (pSrcWin)))
+    	    region = wBoundingShape (pSrcWin);
+    	/*
+     	 * If you try to CopyArea the extents of a shaped window, compacting the
+     	 * exposed region will undo all our work!
+     	 */
+    	if (extents && pSrcWin && region &&
+    	    (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+	    	extents = FALSE;
+    }
+#endif
+    if (extents)
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+	REGION_RESET(pscr, &rgnExposed, &expBox);
+	/* need to clear out new areas of backing store */
+	if (pWin->backStorage)
+	    (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					 pWin,
+					 expBox.x1,
+					 expBox.y1,
+					 expBox.x2 - expBox.x1,
+					 expBox.y2 - expBox.y1,
+					 FALSE);
+    }
+    if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+	(((WindowPtr)pDstDrawable)->backgroundState != None))
+    {
+	WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+	/* make the exposed area screen-relative */
+	REGION_TRANSLATE(pscr, &rgnExposed, 
+				 pDstDrawable->x, pDstDrawable->y);
+
+	if (extents)
+	{
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+	}
+	(*pWin->drawable.pScreen->PaintWindowBackground)(
+			(WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+	if (extents)
+	{
+	    REGION_RESET(pscr, &rgnExposed, &expBox);
+	}
+	else
+	    REGION_TRANSLATE(pscr, &rgnExposed,
+				     -pDstDrawable->x, -pDstDrawable->y);
+    }
+    if (prgnDstClip == &rgnDstRec)
+    {
+	REGION_UNINIT(pscr, prgnDstClip);
+    }
+    else if (prgnDstClip != prgnSrcClip)
+    {
+	REGION_DESTROY(pscr, prgnDstClip);
+    }
+
+    if (prgnSrcClip == &rgnSrcRec)
+    {
+	REGION_UNINIT(pscr, prgnSrcClip);
+    }
+    else
+    {
+	REGION_DESTROY(pscr, prgnSrcClip);
+    }
+
+    if (pGC->graphicsExposures)
+    {
+	/* don't look */
+	RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+	*exposed = rgnExposed;
+	return exposed;
+    }
+    else
+    {
+	REGION_UNINIT(pscr, &rgnExposed);
+	return NULL;
+    }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+    ClientPtr	client;
+    RegionPtr	pRgn;
+    XID		drawable;
+    int	major;
+    int	minor;
+{
+    if (pRgn && !REGION_NIL(pRgn))
+    {
+        xEvent *pEvent;
+	register xEvent *pe;
+	register BoxPtr pBox;
+	register int i;
+	int numRects;
+
+	numRects = REGION_NUM_RECTS(pRgn);
+	pBox = REGION_RECTS(pRgn);
+	if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+		return;
+	pe = pEvent;
+
+	for (i=1; i<=numRects; i++, pe++, pBox++)
+	{
+	    pe->u.u.type = GraphicsExpose;
+	    pe->u.graphicsExposure.drawable = drawable;
+	    pe->u.graphicsExposure.x = pBox->x1;
+	    pe->u.graphicsExposure.y = pBox->y1;
+	    pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+	    pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+	    pe->u.graphicsExposure.count = numRects - i;
+	    pe->u.graphicsExposure.majorEvent = major;
+	    pe->u.graphicsExposure.minorEvent = minor;
+	}
+	TryClientEvents(client, pEvent, numRects,
+			    (Mask)0, NoEventMask, NullGrab);
+	DEALLOCATE_LOCAL(pEvent);
+    }
+    else
+    {
+        xEvent event;
+	event.u.u.type = NoExpose;
+	event.u.noExposure.drawable = drawable;
+	event.u.noExposure.majorEvent = major;
+	event.u.noExposure.minorEvent = minor;
+	TryClientEvents(client, &event, 1,
+	    (Mask)0, NoEventMask, NullGrab);
+    }
+}
+
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+    WindowPtr pWin;
+    RegionPtr pRgn;
+    register int dx, dy;
+{
+    register BoxPtr pBox;
+    int numRects;
+    register xEvent *pEvent, *pe;
+    register int i;
+
+    pBox = REGION_RECTS(pRgn);
+    numRects = REGION_NUM_RECTS(pRgn);
+    if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+	return;
+
+    for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+    {
+	pe->u.u.type = Expose;
+	pe->u.expose.window = pWin->drawable.id;
+	pe->u.expose.x = pBox->x1 - dx;
+	pe->u.expose.y = pBox->y1 - dy;
+	pe->u.expose.width = pBox->x2 - pBox->x1;
+	pe->u.expose.height = pBox->y2 - pBox->y1;
+	pe->u.expose.count = i;
+    }
+
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension) {
+	int scrnum = pWin->drawable.pScreen->myNum;
+	int x = 0, y = 0;
+	XID realWin = 0;
+
+	if(!pWin->parent) {
+	    x = panoramiXdataPtr[scrnum].x;
+	    y = panoramiXdataPtr[scrnum].y;
+	    pWin = WindowTable[0];
+	    realWin = pWin->drawable.id;
+	} else if (scrnum) {
+	    PanoramiXRes *win;
+	    win = PanoramiXFindIDByScrnum(XRT_WINDOW, 
+			pWin->drawable.id, scrnum);
+	    if(!win) {
+		DEALLOCATE_LOCAL(pEvent);
+		return;
+	    }
+	    realWin = win->info[0].id;
+	    pWin = LookupIDByType(realWin, RT_WINDOW);
+	}
+	if(x || y || scrnum)
+	  for (i = 0; i < numRects; i++) {
+	      pEvent[i].u.expose.window = realWin;
+	      pEvent[i].u.expose.x += x;
+	      pEvent[i].u.expose.y += y;
+	  }
+    }
+#endif
+
+    DeliverEvents(pWin, pEvent, numRects, NullWindow);
+
+    DEALLOCATE_LOCAL(pEvent);
+}
+
+void 
+miWindowExposures(pWin, prgn, other_exposed)
+    WindowPtr pWin;
+    register RegionPtr prgn, other_exposed;
+{
+    RegionPtr   exposures = prgn;
+    if (pWin->backStorage && prgn)
+	/*
+	 * in some cases, backing store will cause a different
+	 * region to be exposed than needs to be repainted
+	 * (like when a window is mapped).  RestoreAreas is
+	 * allowed to return a region other than prgn,
+	 * in which case this routine will free the resultant
+	 * region.  If exposures is null, then no events will
+	 * be sent to the client; if prgn is empty
+	 * no areas will be repainted.
+	 */
+	exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+    if ((prgn && !REGION_NIL(prgn)) || 
+	(exposures && !REGION_NIL(exposures)) || other_exposed)
+    {
+	RegionRec   expRec;
+	int	    clientInterested;
+
+	/*
+	 * Restore from backing-store FIRST.
+	 */
+	clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+	if (other_exposed)
+	{
+	    if (exposures)
+	    {
+		REGION_UNION(pWin->drawable.pScreen, other_exposed,
+						  exposures,
+					          other_exposed);
+		if (exposures != prgn)
+		    REGION_DESTROY(pWin->drawable.pScreen, exposures);
+	    }
+	    exposures = other_exposed;
+	}
+	if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+	{
+	    /*
+	     * If we have LOTS of rectangles, we decide to take the extents
+	     * and force an exposure on that.  This should require much less
+	     * work overall, on both client and server.  This is cheating, but
+	     * isn't prohibited by the protocol ("spontaneous combustion" :-).
+	     */
+	    BoxRec box;
+
+	    box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+	    if (exposures == prgn) {
+		exposures = &expRec;
+		REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+		REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+	    } else {
+		REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+		REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+	    }
+	    /* PaintWindowBackground doesn't clip, so we have to */
+	    REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+	    /* need to clear out new areas of backing store, too */
+	    if (pWin->backStorage)
+		(void) (* pWin->drawable.pScreen->ClearBackingStore)(
+					     pWin,
+					     box.x1 - pWin->drawable.x,
+					     box.y1 - pWin->drawable.y,
+					     box.x2 - box.x1,
+					     box.y2 - box.y1,
+					     FALSE);
+	}
+	if (prgn && !REGION_NIL(prgn))
+	    (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+	if (clientInterested && exposures && !REGION_NIL(exposures))
+	    miSendExposures(pWin, exposures,
+			    pWin->drawable.x, pWin->drawable.y);
+	if (exposures == &expRec)
+	{
+	    REGION_UNINIT( pWin->drawable.pScreen, exposures);
+	}
+	else if (exposures && exposures != prgn && exposures != other_exposed)
+	    REGION_DESTROY( pWin->drawable.pScreen, exposures);
+	if (prgn)
+	    REGION_EMPTY( pWin->drawable.pScreen, prgn);
+    }
+    else if (exposures && exposures != prgn)
+	REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+    this code is highly unlikely.  it is not haile selassie.
+
+    there is some hair here.  we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used.  it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr	screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (
+    pointer value,
+    XID id)
+{
+    GCPtr pGC = (GCPtr)value;
+    screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+    FreeGC (pGC, id);
+    numGCs--;
+    if (!numGCs)
+	ResType = 0;
+
+    return 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+    int	status;
+
+    Bool usingScratchGC = FALSE;
+    WindowPtr pRoot;
+	
+#define FUNCTION	0
+#define FOREGROUND	1
+#define TILE		2
+#define FILLSTYLE	3
+#define ABSX		4
+#define ABSY		5
+#define CLIPMASK	6
+#define SUBWINDOW	7
+#define COUNT_BITS	8
+
+    ChangeGCVal gcval[7];
+    ChangeGCVal newValues [COUNT_BITS];
+
+    BITS32 gcmask, index, mask;
+    RegionRec prgnWin;
+    DDXPointRec oldCorner;
+    BoxRec box;
+    WindowPtr	pBgWin;
+    GCPtr pGC;
+    register int i;
+    register BoxPtr pbox;
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    register xRectangle *prect;
+    int numRects;
+
+    gcmask = 0;
+
+    if (what == PW_BACKGROUND)
+    {
+	switch (pWin->backgroundState) {
+	case None:
+	    return;
+	case ParentRelative:
+	    (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+	    return;
+	case BackgroundPixel:
+	    newValues[FOREGROUND].val = pWin->background.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	    break;
+	case BackgroundPixmap:
+	    newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	    break;
+	}
+    }
+    else
+    {
+	if (pWin->borderIsPixel)
+	{
+	    newValues[FOREGROUND].val = pWin->border.pixel;
+	    newValues[FILLSTYLE].val  = FillSolid;
+	    gcmask |= GCForeground | GCFillStyle;
+	}
+	else
+	{
+	    newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+	    newValues[FILLSTYLE].val = FillTiled;
+	    gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+	}
+    }
+
+    prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+					 sizeof(xRectangle));
+    if (!prect)
+	return;
+
+    newValues[FUNCTION].val = GXcopy;
+    gcmask |= GCFunction | GCClipMask;
+
+    i = pScreen->myNum;
+    pRoot = WindowTable[i];
+
+    pBgWin = pWin;
+    if (what == PW_BORDER)
+    {
+	while (pBgWin->backgroundState == ParentRelative)
+	    pBgWin = pBgWin->parent;
+    }
+
+    if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+	(pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+    {
+	usingScratchGC = TRUE;
+	pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+	if (!pGC)
+	{
+	    DEALLOCATE_LOCAL(prect);
+	    return;
+	}
+	/*
+	 * mash the clip list so we can paint the border by
+	 * mangling the window in place, pretending it
+	 * spans the entire screen
+	 */
+	if (what == PW_BORDER)
+	{
+	    prgnWin = pWin->clipList;
+	    oldCorner.x = pWin->drawable.x;
+	    oldCorner.y = pWin->drawable.y;
+	    pWin->drawable.x = pWin->drawable.y = 0;
+	    box.x1 = 0;
+	    box.y1 = 0;
+	    box.x2 = pScreen->width;
+	    box.y2 = pScreen->height;
+	    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    newValues[ABSX].val = pBgWin->drawable.x;
+	    newValues[ABSY].val = pBgWin->drawable.y;
+	}
+	else
+	{
+	    newValues[ABSX].val = 0;
+	    newValues[ABSY].val = 0;
+	}
+    } else {
+	/*
+	 * draw the background to the root window
+	 */
+	if (screenContext[i] == (GCPtr)NULL)
+	{
+	    if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+		return;
+	    screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+					(XID *)NULL, &status);
+	    if (!screenContext[i])
+		return;
+	    numGCs++;
+	    if (!AddResource(FakeClientID(0), ResType,
+			     (pointer)screenContext[i]))
+	        return;
+	}
+	pGC = screenContext[i];
+	newValues[SUBWINDOW].val = IncludeInferiors;
+	newValues[ABSX].val = pBgWin->drawable.x;
+	newValues[ABSY].val = pBgWin->drawable.y;
+	gcmask |= GCSubwindowMode;
+	pWin = pRoot;
+    }
+    
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+    mask = gcmask;
+    gcmask = 0;
+    i = 0;
+    while (mask) {
+    	index = lowbit (mask);
+	mask &= ~index;
+	switch (index) {
+	case GCFunction:
+	    if (pGC->alu != newValues[FUNCTION].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FUNCTION].val;
+	    }
+	    break;
+	case GCTileStipXOrigin:
+	    if ( pGC->patOrg.x != newValues[ABSX].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSX].val;
+	    }
+	    break;
+	case GCTileStipYOrigin:
+	    if ( pGC->patOrg.y != newValues[ABSY].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[ABSY].val;
+	    }
+	    break;
+	case GCClipMask:
+	    if ( pGC->clientClipType != CT_NONE) {
+		gcmask |= index;
+		gcval[i++].val = CT_NONE;
+	    }
+	    break;
+	case GCSubwindowMode:
+	    if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[SUBWINDOW].val;
+	    }
+	    break;
+	case GCTile:
+	    if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ 	    {
+		gcmask |= index;
+		gcval[i++].ptr = newValues[TILE].ptr;
+	    }
+	    break;
+	case GCFillStyle:
+	    if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FILLSTYLE].val;
+	    }
+	    break;
+	case GCForeground:
+	    if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+		gcmask |= index;
+		gcval[i++].val = newValues[FOREGROUND].val;
+	    }
+	    break;
+	}
+    }
+
+    if (gcmask)
+        dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+    if (pWin->drawable.serialNumber != pGC->serialNumber)
+	ValidateGC((DrawablePtr)pWin, pGC);
+
+    numRects = REGION_NUM_RECTS(prgn);
+    pbox = REGION_RECTS(prgn);
+    for (i= numRects; --i >= 0; pbox++, prect++)
+    {
+	prect->x = pbox->x1 - pWin->drawable.x;
+	prect->y = pbox->y1 - pWin->drawable.y;
+	prect->width = pbox->x2 - pbox->x1;
+	prect->height = pbox->y2 - pbox->y1;
+    }
+    prect -= numRects;
+    (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+    DEALLOCATE_LOCAL(prect);
+
+    if (pWin->backStorage)
+	(*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+    if (usingScratchGC)
+    {
+	if (what == PW_BORDER)
+	{
+	    REGION_UNINIT(pScreen, &pWin->clipList);
+	    pWin->clipList = prgnWin;
+	    pWin->drawable.x = oldCorner.x;
+	    pWin->drawable.y = oldCorner.y;
+	    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	}
+	FreeScratchGC(pGC);
+    }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC.  Useful when we have a scratch drawable and need to initialize 
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+    DrawablePtr	pDraw;
+    GCPtr	pGC;
+{
+    XID fg = pGC->fgPixel;
+    XID bg = pGC->bgPixel;
+    xRectangle rect;
+
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = pDraw->width;
+    rect.height = pDraw->height;
+    DoChangeGC(pGC, GCForeground, &bg, 0);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+    DoChangeGC(pGC, GCForeground, &fg, 0);
+    ValidateGC(pDraw, pGC);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
new file mode 100644
index 000000000..6ad60223f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
@@ -0,0 +1,318 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.4 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+void
+miGlyphExtents (int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs,
+		BoxPtr		extents)
+{
+    int		x1, x2, y1, y2;
+    int		n;
+    GlyphPtr	glyph;
+    int		x, y;
+ 
+    x = 0;
+    y = 0;
+    extents->x1 = MAXSHORT;
+    extents->x2 = MINSHORT;
+    extents->y1 = MAXSHORT;
+    extents->y2 = MINSHORT;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+	    if (x1 < extents->x1)
+		extents->x1 = x1;
+	    if (x2 > extents->x2)
+		extents->x2 = x2;
+	    if (y1 < extents->y1)
+		extents->y1 = y1;
+	    if (y2 > extents->y2)
+		extents->y2 = y2;
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+    PixmapPtr	pPixmap = 0;
+    PicturePtr	pPicture;
+    PixmapPtr   pMaskPixmap = 0;
+    PicturePtr  pMask;
+    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    int		width = 0, height = 0;
+    int		x, y;
+    int		xDst = list->xOff, yDst = list->yOff;
+    int		n;
+    GlyphPtr	glyph;
+    int		error;
+    BoxRec	extents;
+    CARD32	component_alpha;
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * Get rid of the warning.
+     */
+
+    extents.x1 = 0;
+    extents.y1 = 0;
+
+    #endif
+
+    if (maskFormat)
+    {
+	GCPtr	    pGC;
+	xRectangle  rect;
+
+        #ifdef NXAGENT_SERVER
+
+        if (nxagentGlyphsExtents != NullBox)
+        {
+          memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
+        }
+        else
+        {
+          nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+          miGlyphExtents (nlist, list, glyphs, &extents);
+
+          memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
+        }
+
+        #else
+
+        miGlyphExtents (nlist, list, glyphs, &extents);
+
+        #endif
+
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+	    return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+	pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+
+	if (!pMaskPixmap)
+	    return;
+
+	component_alpha = NeedsComponent(maskFormat->format);
+	pMask = CreatePicture (0, &pMaskPixmap->drawable,
+			       maskFormat, CPComponentAlpha, &component_alpha,
+			       serverClient, &error);
+
+	if (!pMask)
+	{
+	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    return;
+	}
+	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+	ValidateGC (&pMaskPixmap->drawable, pGC);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+	FreeScratchGC (pGC);
+	x = -extents.x1;
+	y = -extents.y1;
+    }
+    else
+    {
+	pMask = pDst;
+	x = 0;
+	y = 0;
+    }
+    pPicture = 0;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    if (!pPicture)
+	    {
+		pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, 
+						  list->format->depth,
+						  list->format->depth, 
+						  0, (pointer) (glyph + 1));
+		if (!pPixmap)
+		    return;
+		component_alpha = NeedsComponent(list->format->format);
+		pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+					  CPComponentAlpha, &component_alpha, 
+					  serverClient, &error);
+		if (!pPicture)
+		{
+		    FreeScratchPixmapHeader (pPixmap);
+		    return;
+		}
+	    }
+	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
+					    glyph->info.width, glyph->info.height,
+					    0, 0, -1, (pointer) (glyph + 1));
+
+            #ifdef NXAGENT_SERVER
+
+            /*
+             * The following line fixes a problem with glyphs that appeared
+             * as clipped. It was a side effect due the validate function
+             * "ValidatePicture" that makes a check on the Drawable serial
+             * number instead of the picture serial number, failing thus
+             * the clip mask update.
+             */
+
+            pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
+
+            #endif
+
+	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    if (maskFormat)
+	    {
+		CompositePicture (PictOpAdd,
+				  pPicture,
+				  None,
+				  pMask,
+				  0, 0,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    else
+	    {
+		CompositePicture (op,
+				  pSrc,
+				  pPicture,
+				  pDst,
+				  xSrc + (x - glyph->info.x) - xDst,
+				  ySrc + (y - glyph->info.y) - yDst,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+
+	list++;
+	if (pPicture)
+	{
+	    FreeScratchPixmapHeader (pPixmap);
+	    FreePicture ((pointer) pPicture, 0);
+	    pPicture = 0;
+	    pPixmap = 0;
+	}
+    }
+    if (maskFormat)
+    {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture (op,
+			  pSrc,
+			  pMask,
+			  pDst,
+			  xSrc + x - xDst,
+			  ySrc + y - yDst,
+			  0, 0,
+			  x, y,
+			  width, height);
+
+	FreePicture ((pointer) pMask, (XID) 0);
+	(*pScreen->DestroyPixmap) (pMaskPixmap);
+    }
+
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
new file mode 100644
index 000000000..6ad60223f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
@@ -0,0 +1,318 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.4 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+void
+miGlyphExtents (int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs,
+		BoxPtr		extents)
+{
+    int		x1, x2, y1, y2;
+    int		n;
+    GlyphPtr	glyph;
+    int		x, y;
+ 
+    x = 0;
+    y = 0;
+    extents->x1 = MAXSHORT;
+    extents->x2 = MINSHORT;
+    extents->y1 = MAXSHORT;
+    extents->y2 = MINSHORT;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+	    if (x1 < extents->x1)
+		extents->x1 = x1;
+	    if (x2 > extents->x2)
+		extents->x2 = x2;
+	    if (y1 < extents->y1)
+		extents->y1 = y1;
+	    if (y2 > extents->y2)
+		extents->y2 = y2;
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+    PixmapPtr	pPixmap = 0;
+    PicturePtr	pPicture;
+    PixmapPtr   pMaskPixmap = 0;
+    PicturePtr  pMask;
+    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    int		width = 0, height = 0;
+    int		x, y;
+    int		xDst = list->xOff, yDst = list->yOff;
+    int		n;
+    GlyphPtr	glyph;
+    int		error;
+    BoxRec	extents;
+    CARD32	component_alpha;
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * Get rid of the warning.
+     */
+
+    extents.x1 = 0;
+    extents.y1 = 0;
+
+    #endif
+
+    if (maskFormat)
+    {
+	GCPtr	    pGC;
+	xRectangle  rect;
+
+        #ifdef NXAGENT_SERVER
+
+        if (nxagentGlyphsExtents != NullBox)
+        {
+          memcpy(&extents, nxagentGlyphsExtents, sizeof(BoxRec));
+        }
+        else
+        {
+          nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+          miGlyphExtents (nlist, list, glyphs, &extents);
+
+          memcpy(nxagentGlyphsExtents, &extents, sizeof(BoxRec));
+        }
+
+        #else
+
+        miGlyphExtents (nlist, list, glyphs, &extents);
+
+        #endif
+
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+	    return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+	pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+
+	if (!pMaskPixmap)
+	    return;
+
+	component_alpha = NeedsComponent(maskFormat->format);
+	pMask = CreatePicture (0, &pMaskPixmap->drawable,
+			       maskFormat, CPComponentAlpha, &component_alpha,
+			       serverClient, &error);
+
+	if (!pMask)
+	{
+	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    return;
+	}
+	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+	ValidateGC (&pMaskPixmap->drawable, pGC);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+	FreeScratchGC (pGC);
+	x = -extents.x1;
+	y = -extents.y1;
+    }
+    else
+    {
+	pMask = pDst;
+	x = 0;
+	y = 0;
+    }
+    pPicture = 0;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    if (!pPicture)
+	    {
+		pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, 
+						  list->format->depth,
+						  list->format->depth, 
+						  0, (pointer) (glyph + 1));
+		if (!pPixmap)
+		    return;
+		component_alpha = NeedsComponent(list->format->format);
+		pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+					  CPComponentAlpha, &component_alpha, 
+					  serverClient, &error);
+		if (!pPicture)
+		{
+		    FreeScratchPixmapHeader (pPixmap);
+		    return;
+		}
+	    }
+	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
+					    glyph->info.width, glyph->info.height,
+					    0, 0, -1, (pointer) (glyph + 1));
+
+            #ifdef NXAGENT_SERVER
+
+            /*
+             * The following line fixes a problem with glyphs that appeared
+             * as clipped. It was a side effect due the validate function
+             * "ValidatePicture" that makes a check on the Drawable serial
+             * number instead of the picture serial number, failing thus
+             * the clip mask update.
+             */
+
+            pPicture->pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
+
+            #endif
+
+	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    if (maskFormat)
+	    {
+		CompositePicture (PictOpAdd,
+				  pPicture,
+				  None,
+				  pMask,
+				  0, 0,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    else
+	    {
+		CompositePicture (op,
+				  pSrc,
+				  pPicture,
+				  pDst,
+				  xSrc + (x - glyph->info.x) - xDst,
+				  ySrc + (y - glyph->info.y) - yDst,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+
+	list++;
+	if (pPicture)
+	{
+	    FreeScratchPixmapHeader (pPixmap);
+	    FreePicture ((pointer) pPicture, 0);
+	    pPicture = 0;
+	    pPixmap = 0;
+	}
+    }
+    if (maskFormat)
+    {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture (op,
+			  pSrc,
+			  pMask,
+			  pDst,
+			  xSrc + x - xDst,
+			  ySrc + y - yDst,
+			  0, 0,
+			  x, y,
+			  width, height);
+
+	FreePicture ((pointer) pMask, (XID) 0);
+	(*pScreen->DestroyPixmap) (pMaskPixmap);
+    }
+
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original
new file mode 100644
index 000000000..237ec13a4
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.X.original
@@ -0,0 +1,243 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/miglyph.c,v 1.4 2000/11/20 07:13:13 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+void
+miGlyphExtents (int		nlist,
+		GlyphListPtr	list,
+		GlyphPtr	*glyphs,
+		BoxPtr		extents)
+{
+    int		x1, x2, y1, y2;
+    int		n;
+    GlyphPtr	glyph;
+    int		x, y;
+    
+    x = 0;
+    y = 0;
+    extents->x1 = MAXSHORT;
+    extents->x2 = MINSHORT;
+    extents->y1 = MAXSHORT;
+    extents->y2 = MINSHORT;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	list++;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    x1 = x - glyph->info.x;
+	    if (x1 < MINSHORT)
+		x1 = MINSHORT;
+	    y1 = y - glyph->info.y;
+	    if (y1 < MINSHORT)
+		y1 = MINSHORT;
+	    x2 = x1 + glyph->info.width;
+	    if (x2 > MAXSHORT)
+		x2 = MAXSHORT;
+	    y2 = y1 + glyph->info.height;
+	    if (y2 > MAXSHORT)
+		y2 = MAXSHORT;
+	    if (x1 < extents->x1)
+		extents->x1 = x1;
+	    if (x2 > extents->x2)
+		extents->x2 = x2;
+	    if (y1 < extents->y1)
+		extents->y1 = y1;
+	    if (y2 > extents->y2)
+		extents->y2 = y2;
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+    }
+}
+
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
+void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+    PixmapPtr	pPixmap = 0;
+    PicturePtr	pPicture;
+    PixmapPtr   pMaskPixmap = 0;
+    PicturePtr  pMask;
+    ScreenPtr   pScreen = pDst->pDrawable->pScreen;
+    int		width = 0, height = 0;
+    int		x, y;
+    int		xDst = list->xOff, yDst = list->yOff;
+    int		n;
+    GlyphPtr	glyph;
+    int		error;
+    BoxRec	extents;
+    CARD32	component_alpha;
+    
+    if (maskFormat)
+    {
+	GCPtr	    pGC;
+	xRectangle  rect;
+	
+	miGlyphExtents (nlist, list, glyphs, &extents);
+	
+	if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+	    return;
+	width = extents.x2 - extents.x1;
+	height = extents.y2 - extents.y1;
+	pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth);
+	if (!pMaskPixmap)
+	    return;
+	component_alpha = NeedsComponent(maskFormat->format);
+	pMask = CreatePicture (0, &pMaskPixmap->drawable,
+			       maskFormat, CPComponentAlpha, &component_alpha,
+			       serverClient, &error);
+	if (!pMask)
+	{
+	    (*pScreen->DestroyPixmap) (pMaskPixmap);
+	    return;
+	}
+	pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen);
+	ValidateGC (&pMaskPixmap->drawable, pGC);
+	rect.x = 0;
+	rect.y = 0;
+	rect.width = width;
+	rect.height = height;
+	(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+	FreeScratchGC (pGC);
+	x = -extents.x1;
+	y = -extents.y1;
+    }
+    else
+    {
+	pMask = pDst;
+	x = 0;
+	y = 0;
+    }
+    pPicture = 0;
+    while (nlist--)
+    {
+	x += list->xOff;
+	y += list->yOff;
+	n = list->len;
+	while (n--)
+	{
+	    glyph = *glyphs++;
+	    if (!pPicture)
+	    {
+		pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, 
+						  list->format->depth,
+						  list->format->depth, 
+						  0, (pointer) (glyph + 1));
+		if (!pPixmap)
+		    return;
+		component_alpha = NeedsComponent(list->format->format);
+		pPicture = CreatePicture (0, &pPixmap->drawable, list->format,
+					  CPComponentAlpha, &component_alpha, 
+					  serverClient, &error);
+		if (!pPicture)
+		{
+		    FreeScratchPixmapHeader (pPixmap);
+		    return;
+		}
+	    }
+	    (*pScreen->ModifyPixmapHeader) (pPixmap, 
+					    glyph->info.width, glyph->info.height,
+					    0, 0, -1, (pointer) (glyph + 1));
+	    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    if (maskFormat)
+	    {
+		CompositePicture (PictOpAdd,
+				  pPicture,
+				  None,
+				  pMask,
+				  0, 0,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    else
+	    {
+		CompositePicture (op,
+				  pSrc,
+				  pPicture,
+				  pDst,
+				  xSrc + (x - glyph->info.x) - xDst,
+				  ySrc + (y - glyph->info.y) - yDst,
+				  0, 0,
+				  x - glyph->info.x,
+				  y - glyph->info.y,
+				  glyph->info.width,
+				  glyph->info.height);
+	    }
+	    x += glyph->info.xOff;
+	    y += glyph->info.yOff;
+	}
+	list++;
+	if (pPicture)
+	{
+	    FreeScratchPixmapHeader (pPixmap);
+	    FreePicture ((pointer) pPicture, 0);
+	    pPicture = 0;
+	    pPixmap = 0;
+	}
+    }
+    if (maskFormat)
+    {
+	x = extents.x1;
+	y = extents.y1;
+	CompositePicture (op,
+			  pSrc,
+			  pMask,
+			  pDst,
+			  xSrc + x - xDst,
+			  ySrc + y - yDst,
+			  0, 0,
+			  x, y,
+			  width, height);
+	FreePicture ((pointer) pMask, (XID) 0);
+	(*pScreen->DestroyPixmap) (pMaskPixmap);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
new file mode 100644
index 000000000..e08f5e45f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
@@ -0,0 +1,233 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.8 2002/09/03 19:28:28 keithp Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr	    pScreen, 
+		      PicturePtr    pDst,
+		      PictFormatPtr pPictFormat,
+		      CARD16	    width,
+		      CARD16	    height)
+{
+    PixmapPtr	    pPixmap;
+    PicturePtr	    pPicture;
+    GCPtr	    pGC;
+    int		    error;
+    xRectangle	    rect;
+
+    if (width > 32767 || height > 32767)
+	return 0;
+
+    if (!pPictFormat)
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	if (!pPictFormat)
+	    return 0;
+    }
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 
+					pPictFormat->depth);
+    if (!pPixmap)
+	return 0;
+    pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+    if (!pGC)
+    {
+	(*pScreen->DestroyPixmap) (pPixmap);
+	return 0;
+    }
+    ValidateGC (&pPixmap->drawable, pGC);
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = width;
+    rect.height = height;
+    (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+    FreeScratchGC (pGC);
+    pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+			      0, 0, serverClient, &error);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+    xFixed	    dx = l->p2.x - l->p1.x;
+    xFixed_32_32    ex = (xFixed_32_32) (y - l->p1.y) * dx;
+    xFixed	    dy = l->p2.y - l->p1.y;
+    if (ceil)
+	ex += (dy - 1);
+    return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+    box->y1 = MAXSHORT;
+    box->y2 = MINSHORT;
+    box->x1 = MAXSHORT;
+    box->x2 = MINSHORT;
+    for (; ntrap; ntrap--, traps++)
+    {
+	INT16 x1, y1, x2, y2;
+
+	if (!xTrapezoidValid(traps))
+	    continue;
+	y1 = xFixedToInt (traps->top);
+	if (y1 < box->y1)
+	    box->y1 = y1;
+	
+	y2 = xFixedToInt (xFixedCeil (traps->bottom));
+	if (y2 > box->y2)
+	    box->y2 = y2;
+	
+	x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+			       miLineFixedX (&traps->left, traps->bottom, FALSE)));
+	if (x1 < box->x1)
+	    box->x1 = x1;
+	
+	x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+					   miLineFixedX (&traps->right, traps->bottom, TRUE))));
+	if (x2 > box->x2)
+	    box->x2 = x2;
+    }
+}
+
+void
+miTrapezoids (CARD8	    op,
+	      PicturePtr    pSrc,
+	      PicturePtr    pDst,
+	      PictFormatPtr maskFormat,
+	      INT16	    xSrc,
+	      INT16	    ySrc,
+	      int	    ntrap,
+	      xTrapezoid    *traps)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    /*
+     * Check for solid alpha add
+     */
+    if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+    {
+	for (; ntrap; ntrap--, traps++)
+	    (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+    } 
+    else if (maskFormat)
+    {
+	PicturePtr	pPicture;
+	BoxRec		bounds;
+	INT16		xDst, yDst;
+	INT16		xRel, yRel;
+	
+	xDst = traps[0].left.p1.x >> 16;
+	yDst = traps[0].left.p1.y >> 16;
+
+        #ifdef NXAGENT_SERVER
+
+        if (nxagentTrapezoidExtents != NullBox)
+        {
+          memcpy(&bounds, nxagentTrapezoidExtents, sizeof(BoxRec));
+        }
+        else
+        {
+          nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+          miTrapezoidBounds (ntrap, traps, &bounds);
+
+          memcpy(nxagentTrapezoidExtents, &bounds, sizeof(BoxRec));
+        }
+
+        #else
+
+        miTrapezoidBounds (ntrap, traps, &bounds);
+
+        #endif
+
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+	    return;
+	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					 bounds.x2 - bounds.x1,
+					 bounds.y2 - bounds.y1);
+	if (!pPicture)
+	    return;
+	for (; ntrap; ntrap--, traps++)
+	    (*ps->RasterizeTrapezoid) (pPicture, traps, 
+				       -bounds.x1, -bounds.y1);
+	xRel = bounds.x1 + xSrc - xDst;
+	yRel = bounds.y1 + ySrc - yDst;
+	CompositePicture (op, pSrc, pPicture, pDst,
+			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			  bounds.x2 - bounds.x1,
+			  bounds.y2 - bounds.y1);
+	FreePicture (pPicture, 0);
+    }
+    else
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	for (; ntrap; ntrap--, traps++)
+	    miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
new file mode 100644
index 000000000..e08f5e45f
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
@@ -0,0 +1,233 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.8 2002/09/03 19:28:28 keithp Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifdef NXAGENT_SERVER
+
+#include "Render.h"
+
+#endif
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr	    pScreen, 
+		      PicturePtr    pDst,
+		      PictFormatPtr pPictFormat,
+		      CARD16	    width,
+		      CARD16	    height)
+{
+    PixmapPtr	    pPixmap;
+    PicturePtr	    pPicture;
+    GCPtr	    pGC;
+    int		    error;
+    xRectangle	    rect;
+
+    if (width > 32767 || height > 32767)
+	return 0;
+
+    if (!pPictFormat)
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	if (!pPictFormat)
+	    return 0;
+    }
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 
+					pPictFormat->depth);
+    if (!pPixmap)
+	return 0;
+    pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+    if (!pGC)
+    {
+	(*pScreen->DestroyPixmap) (pPixmap);
+	return 0;
+    }
+    ValidateGC (&pPixmap->drawable, pGC);
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = width;
+    rect.height = height;
+    (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+    FreeScratchGC (pGC);
+    pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+			      0, 0, serverClient, &error);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+    xFixed	    dx = l->p2.x - l->p1.x;
+    xFixed_32_32    ex = (xFixed_32_32) (y - l->p1.y) * dx;
+    xFixed	    dy = l->p2.y - l->p1.y;
+    if (ceil)
+	ex += (dy - 1);
+    return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+    box->y1 = MAXSHORT;
+    box->y2 = MINSHORT;
+    box->x1 = MAXSHORT;
+    box->x2 = MINSHORT;
+    for (; ntrap; ntrap--, traps++)
+    {
+	INT16 x1, y1, x2, y2;
+
+	if (!xTrapezoidValid(traps))
+	    continue;
+	y1 = xFixedToInt (traps->top);
+	if (y1 < box->y1)
+	    box->y1 = y1;
+	
+	y2 = xFixedToInt (xFixedCeil (traps->bottom));
+	if (y2 > box->y2)
+	    box->y2 = y2;
+	
+	x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+			       miLineFixedX (&traps->left, traps->bottom, FALSE)));
+	if (x1 < box->x1)
+	    box->x1 = x1;
+	
+	x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+					   miLineFixedX (&traps->right, traps->bottom, TRUE))));
+	if (x2 > box->x2)
+	    box->x2 = x2;
+    }
+}
+
+void
+miTrapezoids (CARD8	    op,
+	      PicturePtr    pSrc,
+	      PicturePtr    pDst,
+	      PictFormatPtr maskFormat,
+	      INT16	    xSrc,
+	      INT16	    ySrc,
+	      int	    ntrap,
+	      xTrapezoid    *traps)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    /*
+     * Check for solid alpha add
+     */
+    if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+    {
+	for (; ntrap; ntrap--, traps++)
+	    (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+    } 
+    else if (maskFormat)
+    {
+	PicturePtr	pPicture;
+	BoxRec		bounds;
+	INT16		xDst, yDst;
+	INT16		xRel, yRel;
+	
+	xDst = traps[0].left.p1.x >> 16;
+	yDst = traps[0].left.p1.y >> 16;
+
+        #ifdef NXAGENT_SERVER
+
+        if (nxagentTrapezoidExtents != NullBox)
+        {
+          memcpy(&bounds, nxagentTrapezoidExtents, sizeof(BoxRec));
+        }
+        else
+        {
+          nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+          miTrapezoidBounds (ntrap, traps, &bounds);
+
+          memcpy(nxagentTrapezoidExtents, &bounds, sizeof(BoxRec));
+        }
+
+        #else
+
+        miTrapezoidBounds (ntrap, traps, &bounds);
+
+        #endif
+
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+	    return;
+	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					 bounds.x2 - bounds.x1,
+					 bounds.y2 - bounds.y1);
+	if (!pPicture)
+	    return;
+	for (; ntrap; ntrap--, traps++)
+	    (*ps->RasterizeTrapezoid) (pPicture, traps, 
+				       -bounds.x1, -bounds.y1);
+	xRel = bounds.x1 + xSrc - xDst;
+	yRel = bounds.y1 + ySrc - yDst;
+	CompositePicture (op, pSrc, pPicture, pDst,
+			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			  bounds.x2 - bounds.x1,
+			  bounds.y2 - bounds.y1);
+	FreePicture (pPicture, 0);
+    }
+    else
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	for (; ntrap; ntrap--, traps++)
+	    miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original
new file mode 100644
index 000000000..be1712420
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.X.original
@@ -0,0 +1,190 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/mitrap.c,v 1.8 2002/09/03 19:28:28 keithp Exp $
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+PicturePtr
+miCreateAlphaPicture (ScreenPtr	    pScreen, 
+		      PicturePtr    pDst,
+		      PictFormatPtr pPictFormat,
+		      CARD16	    width,
+		      CARD16	    height)
+{
+    PixmapPtr	    pPixmap;
+    PicturePtr	    pPicture;
+    GCPtr	    pGC;
+    int		    error;
+    xRectangle	    rect;
+
+    if (width > 32767 || height > 32767)
+	return 0;
+
+    if (!pPictFormat)
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	if (!pPictFormat)
+	    return 0;
+    }
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 
+					pPictFormat->depth);
+    if (!pPixmap)
+	return 0;
+    pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+    if (!pGC)
+    {
+	(*pScreen->DestroyPixmap) (pPixmap);
+	return 0;
+    }
+    ValidateGC (&pPixmap->drawable, pGC);
+    rect.x = 0;
+    rect.y = 0;
+    rect.width = width;
+    rect.height = height;
+    (*pGC->ops->PolyFillRect)(&pPixmap->drawable, pGC, 1, &rect);
+    FreeScratchGC (pGC);
+    pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
+			      0, 0, serverClient, &error);
+    (*pScreen->DestroyPixmap) (pPixmap);
+    return pPicture;
+}
+
+static xFixed
+miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
+{
+    xFixed	    dx = l->p2.x - l->p1.x;
+    xFixed_32_32    ex = (xFixed_32_32) (y - l->p1.y) * dx;
+    xFixed	    dy = l->p2.y - l->p1.y;
+    if (ceil)
+	ex += (dy - 1);
+    return l->p1.x + (xFixed) (ex / dy);
+}
+
+void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box)
+{
+    box->y1 = MAXSHORT;
+    box->y2 = MINSHORT;
+    box->x1 = MAXSHORT;
+    box->x2 = MINSHORT;
+    for (; ntrap; ntrap--, traps++)
+    {
+	INT16 x1, y1, x2, y2;
+
+	if (!xTrapezoidValid(traps))
+	    continue;
+	y1 = xFixedToInt (traps->top);
+	if (y1 < box->y1)
+	    box->y1 = y1;
+	
+	y2 = xFixedToInt (xFixedCeil (traps->bottom));
+	if (y2 > box->y2)
+	    box->y2 = y2;
+	
+	x1 = xFixedToInt (min (miLineFixedX (&traps->left, traps->top, FALSE),
+			       miLineFixedX (&traps->left, traps->bottom, FALSE)));
+	if (x1 < box->x1)
+	    box->x1 = x1;
+	
+	x2 = xFixedToInt (xFixedCeil (max (miLineFixedX (&traps->right, traps->top, TRUE),
+					   miLineFixedX (&traps->right, traps->bottom, TRUE))));
+	if (x2 > box->x2)
+	    box->x2 = x2;
+    }
+}
+
+void
+miTrapezoids (CARD8	    op,
+	      PicturePtr    pSrc,
+	      PicturePtr    pDst,
+	      PictFormatPtr maskFormat,
+	      INT16	    xSrc,
+	      INT16	    ySrc,
+	      int	    ntrap,
+	      xTrapezoid    *traps)
+{
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    /*
+     * Check for solid alpha add
+     */
+    if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+    {
+	for (; ntrap; ntrap--, traps++)
+	    (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+    } 
+    else if (maskFormat)
+    {
+	PicturePtr	pPicture;
+	BoxRec		bounds;
+	INT16		xDst, yDst;
+	INT16		xRel, yRel;
+	
+	xDst = traps[0].left.p1.x >> 16;
+	yDst = traps[0].left.p1.y >> 16;
+
+	miTrapezoidBounds (ntrap, traps, &bounds);
+	if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+	    return;
+	pPicture = miCreateAlphaPicture (pScreen, pDst, maskFormat,
+					 bounds.x2 - bounds.x1,
+					 bounds.y2 - bounds.y1);
+	if (!pPicture)
+	    return;
+	for (; ntrap; ntrap--, traps++)
+	    (*ps->RasterizeTrapezoid) (pPicture, traps, 
+				       -bounds.x1, -bounds.y1);
+	xRel = bounds.x1 + xSrc - xDst;
+	yRel = bounds.y1 + ySrc - yDst;
+	CompositePicture (op, pSrc, pPicture, pDst,
+			  xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+			  bounds.x2 - bounds.x1,
+			  bounds.y2 - bounds.y1);
+	FreePicture (pPicture, 0);
+    }
+    else
+    {
+	if (pDst->polyEdge == PolyEdgeSharp)
+	    maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+	else
+	    maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+	for (; ntrap; ntrap--, traps++)
+	    miTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
new file mode 100644
index 000000000..1731e0753
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
@@ -0,0 +1,1222 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "regionstr.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void 
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+    WindowPtr pWin;
+    int x,y;
+    int w,h;
+    Bool generateExposures;
+{
+    BoxRec box;
+    RegionRec	reg;
+    RegionPtr pBSReg = NullRegion;
+    ScreenPtr	pScreen;
+    BoxPtr  extents;
+    int	    x1, y1, x2, y2;
+
+    /* compute everything using ints to avoid overflow */
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;	
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    extents = &pWin->clipList.extents;
+    
+    /* clip the resulting rectangle to the window clipList extents.  This
+     * makes sure that the result will fit in a box, given that the
+     * screen is < 32768 on a side.
+     */
+
+    if (x1 < extents->x1)
+	x1 = extents->x1;
+    if (x2 > extents->x2)
+	x2 = extents->x2;
+    if (y1 < extents->y1)
+	y1 = extents->y1;
+    if (y2 > extents->y2)
+	y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1)
+    {
+	x2 = x1 = 0;
+	y2 = y1 = 0;
+    }
+
+    box.x1 = x1;
+    box.x2 = x2;
+    box.y1 = y1;
+    box.y2 = y2;
+
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &reg, &box, 1);
+    if (pWin->backStorage)
+    {
+	/*
+	 * If the window has backing-store on, call through the
+	 * ClearToBackground vector to handle the special semantics
+	 * (i.e. things backing store is to be cleared out and
+	 * an Expose event is to be generated for those areas in backing
+	 * store if generateExposures is TRUE).
+	 */
+	pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+						 generateExposures);
+    }
+
+    REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+    if (generateExposures)
+	(*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+    else if (pWin->backgroundState != None)
+        (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+    REGION_UNINIT(pScreen, &reg);
+    if (pBSReg)
+	REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ *	Check all the inferiors of a window for coverage by saveUnder
+ *	windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ *	This code is very inefficient.
+ *
+ * Results:
+ *	TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+    register WindowPtr	pParent,	/* Parent to check */
+    WindowPtr		pFirst,		/* first reconfigured window */
+    RegionPtr		pRegion)	/* Initial area obscured by saveUnder */
+{
+    register WindowPtr	pChild;		/* Current child */
+    register ScreenPtr	pScreen;	/* Screen to use */
+    RegionRec		SubRegion;	/* Area of children obscured */
+    Bool		res = FALSE;	/* result */
+    Bool		subInited=FALSE;/* SubRegion initialized */
+
+    pScreen = pParent->drawable.pScreen;
+    if ( (pChild = pParent->firstChild) )
+    {
+	/*
+	 * build region above first changed window
+	 */
+
+	for (; pChild != pFirst; pChild = pChild->nextSib)
+	    if (pChild->viewable && pChild->saveUnder)
+		REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	
+	/*
+	 * check region below and including first changed window
+	 */
+
+	for (; pChild; pChild = pChild->nextSib)
+	{
+	    if (pChild->viewable)
+	    {
+		/*
+		 * don't save under nephew/niece windows;
+		 * use a separate region
+		 */
+
+		if (pChild->firstChild)
+		{
+		    if (!subInited)
+		    {
+			REGION_NULL(pScreen, &SubRegion);
+			subInited = TRUE;
+		    }
+		    REGION_COPY(pScreen, &SubRegion, pRegion);
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     &SubRegion);
+		}
+		else
+		{
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     pRegion);
+		}
+
+		if (pChild->saveUnder)
+		    REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	    }
+	}
+
+	if (subInited)
+	    REGION_UNINIT(pScreen, &SubRegion);
+    }
+
+    /*
+     * Check the state of this window.	DIX save unders are
+     * enabled for viewable windows with some client expressing
+     * exposure interest and which intersect the save under region
+     */
+
+    if (pParent->viewable && 
+	((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+	REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+	RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen, 
+					&pParent->borderSize)) != rgnOUT)
+    {
+	if (!pParent->DIXsaveUnder)
+	{
+	    pParent->DIXsaveUnder = TRUE;
+	    (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+	}
+    }
+    else
+    {
+	if (pParent->DIXsaveUnder)
+	{
+	    res = TRUE;
+	    pParent->DIXsaveUnder = FALSE;
+	}
+    }
+    return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ *	Change the save-under state of a tree of windows. Called when
+ *	a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *	
+ * Results:
+ *	TRUE if any windows need to have backing-store removed (which
+ *	means that PostChangeSaveUnder needs to be called later to 
+ *	finish the job).
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+    register WindowPtr	pWin;
+    WindowPtr		first;		/* First window to check.
+					 * Used when pWin was restacked */
+{
+    RegionRec	rgn;	/* Area obscured by saveUnder windows */
+    register ScreenPtr pScreen;
+    Bool	res;
+
+    if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+	return FALSE;
+    numSaveUndersViewable += deltaSaveUndersViewable;
+    deltaSaveUndersViewable = 0;
+    pScreen = pWin->drawable.pScreen;
+    REGION_NULL(pScreen, &rgn);
+    res = miCheckSubSaveUnder (pWin->parent,
+			       pWin->saveUnder ? first : pWin->nextSib,
+			       &rgn);
+    REGION_UNINIT(pScreen, &rgn);
+    return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ *	Actually turn backing-store off for those windows that no longer
+ *	need to have it on.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ *	windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+    WindowPtr		pWin;
+    WindowPtr		pFirst;
+{
+    register WindowPtr pParent, pChild;
+    ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+    if (!(pParent = pWin->parent))
+	return;
+    ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+    if (!pParent->DIXsaveUnder &&
+	(pParent->backingStore == NotUseful) && pParent->backStorage)
+	(*ChangeWindowAttributes)(pParent, CWBackingStore);
+    if (!(pChild = pFirst))
+	return;
+    while (1)
+    {
+	if (!pChild->DIXsaveUnder &&
+	    (pChild->backingStore == NotUseful) && pChild->backStorage)
+	    (*ChangeWindowAttributes)(pChild, CWBackingStore);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib)
+	{
+	    pChild = pChild->parent;
+	    if (pChild == pParent)
+		return;
+	}
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMarkWindow(pWin)
+    register WindowPtr pWin;
+{
+    register ValidatePtr val;
+
+    if (pWin->valdata)
+	return;
+    val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+    val->before.oldAbsCorner.x = pWin->drawable.x;
+    val->before.oldAbsCorner.y = pWin->drawable.y;
+    val->before.borderVisible = NullRegion;
+    val->before.resized = FALSE;
+    pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+    WindowPtr pWin;
+    WindowPtr pFirst;
+    WindowPtr *ppLayerWin;
+{
+    register BoxPtr box;
+    register WindowPtr pChild, pLast;
+    Bool anyMarked = FALSE;
+    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+    ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+
+    /* single layered systems are easy */
+    if (ppLayerWin) *ppLayerWin = pWin;
+
+    if (pWin == pFirst)
+    {
+	/* Blindly mark pWin and all of its inferiors.	 This is a slight
+	 * overkill if there are mapped windows that outside pWin's border,
+	 * but it's better than wasting time on RectIn checks.
+	 */
+	pChild = pWin;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		(* MarkWindow)(pChild);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pWin))
+		pChild = pChild->parent;
+	    if (pChild == pWin)
+		break;
+	    pChild = pChild->nextSib;
+	}
+	anyMarked = TRUE;
+	pFirst = pFirst->nextSib;
+    }
+    if ( (pChild = pFirst) )
+    {
+	box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+	pLast = pChild->parent->lastChild;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+		{
+		    (* MarkWindow)(pChild);
+		    anyMarked = TRUE;
+		    if (pChild->firstChild)
+		    {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pLast))
+		pChild = pChild->parent;
+	    if (pChild == pLast)
+		break;
+	    pChild = pChild->nextSib;
+	}
+    }
+    if (anyMarked)
+	(* MarkWindow)(pWin->parent);
+    return anyMarked;
+}
+
+/*****
+ *  miHandleValidateExposures(pWin)
+ *    starting at pWin, draw background in any windows that have exposure
+ *    regions, translate the regions, restore any backing store,
+ *    and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+    WindowPtr pWin;
+{
+    register WindowPtr pChild;
+    register ValidatePtr val;
+    ScreenPtr pScreen;
+    WindowExposuresProcPtr WindowExposures;
+
+    pScreen = pWin->drawable.pScreen;
+
+    pChild = pWin;
+    WindowExposures = pChild->drawable.pScreen->WindowExposures;
+    while (1)
+    {
+	if ( (val = pChild->valdata) )
+	{
+	    if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+		(*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+						    &val->after.borderExposed,
+						    PW_BORDER);
+	    REGION_UNINIT(pScreen, &val->after.borderExposed);
+	    (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+	    REGION_UNINIT(pScreen, &val->after.exposed);
+	    xfree(val);
+	    pChild->valdata = (ValidatePtr)NULL;
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+    register WindowPtr pWin;
+    int x,y;
+    WindowPtr pNextSib;
+    VTKind kind;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    short bw;
+    RegionPtr oldRegion = NULL;
+    DDXPointRec oldpt;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+    Bool dosave = FALSE;
+#endif
+    WindowPtr pLayerWin;
+
+    /* if this is a root window, can't be moved */
+    if (!(pParent = pWin->parent))
+       return ;
+    pScreen = pWin->drawable.pScreen;
+    bw = wBorderWidth (pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable)
+    {
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    }
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, windowToValidate, (WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+	    REGION_DESTROY(pScreen, oldRegion);
+	    /* XXX need to retile border if ParentRelative origin */
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+    register WindowPtr	pWin,
+    pointer		value) /* must conform to VisitWindowProcPtr */
+{
+    register ScreenPtr	pScreen;
+    RegionPtr	pValid = (RegionPtr)value;
+
+    if (pWin->valdata)
+    {
+	pScreen = pWin->drawable.pScreen;
+	/*
+	 * compute exposed regions of this window
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+			&pWin->clipList, pValid);
+	/*
+	 * compute exposed regions of the border
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->borderClip, &pWin->winSize);
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->valdata->after.borderExposed, pValid);
+	return WT_WALKCHILDREN;
+    }
+    return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+    register WindowPtr pWin;
+    int x,y;
+    unsigned int w, h;
+    WindowPtr pSib;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    unsigned short width = pWin->drawable.width,
+		   height = pWin->drawable.height;
+    short oldx = pWin->drawable.x,
+	  oldy = pWin->drawable.y;
+    int bw = wBorderWidth (pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr pFirstChange;
+    register WindowPtr pChild;
+    RegionPtr	gravitate[StaticGravity + 1];
+    register unsigned g;
+    int		nx, ny;		/* destination x,y */
+    int		newx, newy;	/* new inner window position */
+    RegionPtr	pRegion = NULL;
+    RegionPtr	destClip;	/* portions of destination already written */
+    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
+    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
+    RegionPtr	bsExposed = NullRegion;	    /* backing store exposures */
+    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
+    Bool	moved = FALSE;	/* window position changed */
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pScreen = pWin->drawable.pScreen;
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable)
+    {
+	anyMarked = FALSE;
+	/*
+	 * save the visible region of the window
+	 */
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+	/*
+	 * categorize child windows into regions to be moved
+	 */
+	for (g = 0; g <= StaticGravity; g++)
+	    gravitate[g] = (RegionPtr) NULL;
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	{
+	    g = pChild->winGravity;
+	    if (g != UnmapGravity)
+	    {
+		if (!gravitate[g])
+		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_UNION(pScreen, gravitate[g],
+				   gravitate[g], &pChild->borderClip);
+	    }
+	    else
+	    {
+		UnmapWindow(pChild, TRUE);
+		anyMarked = TRUE;
+	    }
+	}
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
+						       &pLayerWin);
+
+	oldWinClip = NULL;
+	if (pWin->bitGravity != ForgetGravity)
+	{
+	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+	}
+	/*
+	 * if the window is changing size, borderExposed
+	 * can't be computed correctly without some help.
+	 */
+	if (pWin->drawable.height > h || pWin->drawable.width > w)
+	    shrunk = TRUE;
+
+	if (newx != oldx || newy != oldy)
+	    moved = TRUE;
+
+	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+	    HasBorder (pWin))
+	{
+	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+	    /* for tiled borders, we punt and draw the whole thing */
+	    if (pWin->borderIsPixel || !moved)
+	    {
+		if (shrunk || moved)
+		    REGION_SUBTRACT(pScreen, borderVisible,
+					  &pWin->borderClip,
+					  &pWin->winSize);
+		else
+		    REGION_COPY(pScreen, borderVisible,
+					    &pWin->borderClip);
+	    }
+	}
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    dw = (int)w - (int)width;
+    dh = (int)h - (int)height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	pRegion = REGION_CREATE(pScreen, NullBox, 1);
+	if (pWin->backStorage)
+	    REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						(WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						(WindowPtr *)NULL);
+
+	if (pWin->valdata)
+	{
+	    pWin->valdata->before.resized = TRUE;
+	    pWin->valdata->before.borderVisible = borderVisible;
+	}
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+	/*
+	 * the entire window is trashed unless bitGravity
+	 * recovers portions of it
+	 */
+	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+    }
+
+    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pRegion = &pWin->clipList; /* a convenient empty region */
+	if (pWin->bitGravity == ForgetGravity)
+	    bsExposed = (*pScreen->TranslateBackingStore)
+				(pWin, 0, 0, NullRegion, oldx, oldy);
+	else
+	{
+	    bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+	}
+    }
+
+    if (WasViewable)
+    {
+	/* avoid the border */
+	if (HasBorder (pWin))
+	{
+	    int	offx, offy, dx, dy;
+
+	    /* kruft to avoid double translates for each gravity */
+	    offx = 0;
+	    offy = 0;
+	    for (g = 0; g <= StaticGravity; g++)
+	    {
+		if (!gravitate[g])
+		    continue;
+
+		/* align winSize to gravitate[g].
+		 * winSize is in new coordinates,
+		 * gravitate[g] is still in old coordinates */
+		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+		
+		dx = (oldx - nx) - offx;
+		dy = (oldy - ny) - offy;
+		if (dx || dy)
+		{
+		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+		    offx += dx;
+		    offy += dy;
+		}
+		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+				 &pWin->winSize);
+	    }
+	    /* get winSize back where it belongs */
+	    if (offx || offy)
+		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+	}
+	/*
+	 * add screen bits to the appropriate bucket
+	 */
+
+	if (oldWinClip)
+	{
+	    /*
+	     * clip to new clipList
+	     */
+	    REGION_COPY(pScreen, pRegion, oldWinClip);
+	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+	    /*
+	     * don't step on any gravity bits which will be copied after this
+	     * region.	Note -- this assumes that the regions will be copied
+	     * in gravity order.
+	     */
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+	    {
+		if (gravitate[g])
+		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+					gravitate[g]);
+	    }
+	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate[g])
+		gravitate[g] = oldWinClip;
+	    else
+	    {
+		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+		REGION_DESTROY(pScreen, oldWinClip);
+	    }
+	}
+
+	/*
+	 * move the bits on the screen
+	 */
+
+	destClip = NULL;
+
+	for (g = 0; g <= StaticGravity; g++)
+	{
+	    if (!gravitate[g])
+		continue;
+
+	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+	    oldpt.x = oldx + (x - nx);
+	    oldpt.y = oldy + (y - ny);
+
+	    /* Note that gravitate[g] is *translated* by CopyWindow */
+
+	    /* only copy the remaining useful bits */
+
+	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+	    /* clip to not overwrite already copied areas */
+
+	    if (destClip) {
+		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+	    }
+
+	    /* and move those bits */
+
+	    if (oldpt.x != x || oldpt.y != y
+#ifdef COMPOSITE
+		|| pWin->redirectDraw
+#endif
+		)
+	    {
+		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+	    }
+
+	    /* remove any overwritten bits from the remaining useful bits */
+
+	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+	    /*
+	     * recompute exposed regions of child windows
+	     */
+	
+	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	    {
+		if (pChild->winGravity != g)
+		    continue;
+		REGION_INTERSECT(pScreen, pRegion,
+				       &pChild->borderClip, gravitate[g]);
+		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+	    }
+
+	    /*
+	     * remove the successfully copied regions of the
+	     * window from its exposed region
+	     */
+
+	    if (g == pWin->bitGravity)
+		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+				     &pWin->valdata->after.exposed, gravitate[g]);
+	    if (!destClip)
+		destClip = gravitate[g];
+	    else
+	    {
+		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+		REGION_DESTROY(pScreen, gravitate[g]);
+	    }
+	}
+
+	REGION_DESTROY(pScreen, oldRegion);
+	REGION_DESTROY(pScreen, pRegion);
+	if (destClip)
+	    REGION_DESTROY(pScreen, destClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	{
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+					  VTOther);
+    }
+    else if (bsExposed)
+    {
+	(*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+	REGION_DESTROY(pScreen, bsExposed);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+    WindowPtr pWin;
+{
+    return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ *    The border/window shape has changed.  Recompute winSize/borderSize
+ *    and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+    register WindowPtr	pWin;
+{
+    Bool	WasViewable = (Bool)(pWin->viewable);
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    Bool	anyMarked = FALSE;
+    RegionPtr	pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr   pLayerWin;
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						      &pLayerWin);
+	if (pWin->valdata)
+	{
+	    if (HasBorder (pWin))
+	    {
+		RegionPtr	borderVisible;
+
+		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	    pWin->valdata->before.resized = TRUE;
+	}
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pWin->backStorage)
+	{
+	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+	}
+
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						(WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pOldClip = &pWin->clipList; /* a convenient empty region */
+	bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, 0, 0, pOldClip,
+			      pWin->drawable.x, pWin->drawable.y);
+#ifdef NXAGENT_SERVER
+
+        /*
+         * We got a few, rare, segfaults here after having
+         * started using the backing store. It may be a
+         * different bug but miChangeSaveUnder() calls mi-
+         * CheckSubSaveUnder() that, in turn, can change
+         * the backing store attribute of the window. This
+         * means that we may try to destroy the region
+         * even if it was not created at the beginning of
+         * this function as, at the time, the backing store
+         * was off. miCheckSubSaveUnder() appear to get a
+         * pointer to the parent, so maybe doesn't change
+         * the attribute of the window itself. This is to
+         * be better investigated.
+         */
+
+        if (WasViewable && pOldClip)
+            REGION_DESTROY(pScreen, pOldClip);
+#else
+	if (WasViewable)
+	    REGION_DESTROY(pScreen, pOldClip);
+#endif
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+    
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+    }
+    if (WasViewable)
+    {
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+    CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+    register WindowPtr pWin;
+    unsigned int width;
+{
+    int oldwidth;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    oldwidth = wBorderWidth (pWin);
+    if (oldwidth == width)
+	return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    if (WasViewable && width < oldwidth)
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+    pWin->borderWidth = width;
+    SetBorderSize (pWin);
+
+    if (WasViewable)
+    {
+	if (width > oldwidth)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+	    /*
+	     * save the old border visible region to correctly compute
+	     * borderExposed.
+	     */
+	    if (pWin->valdata && HadBorder)
+	    {
+		RegionPtr   borderVisible;
+		borderVisible = REGION_CREATE(pScreen, NULL, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+					  VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+    WindowPtr pChild;
+    WindowPtr pWin;
+    Bool fromConfigure;
+{
+    if ((pChild != pWin) || fromConfigure)
+    {
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+	if (pChild->drawable.pScreen->ClipNotify)
+	    (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+    }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+    ScreenPtr pScreen;
+    WindowPtr pChild;
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+    {
+	if (pChild->drawable.depth == depth)
+	    REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+	if (pChild->firstChild)
+	    miSegregateChildren(pChild, pReg, depth);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
new file mode 100644
index 000000000..1731e0753
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
@@ -0,0 +1,1222 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "regionstr.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void 
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+    WindowPtr pWin;
+    int x,y;
+    int w,h;
+    Bool generateExposures;
+{
+    BoxRec box;
+    RegionRec	reg;
+    RegionPtr pBSReg = NullRegion;
+    ScreenPtr	pScreen;
+    BoxPtr  extents;
+    int	    x1, y1, x2, y2;
+
+    /* compute everything using ints to avoid overflow */
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;	
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    extents = &pWin->clipList.extents;
+    
+    /* clip the resulting rectangle to the window clipList extents.  This
+     * makes sure that the result will fit in a box, given that the
+     * screen is < 32768 on a side.
+     */
+
+    if (x1 < extents->x1)
+	x1 = extents->x1;
+    if (x2 > extents->x2)
+	x2 = extents->x2;
+    if (y1 < extents->y1)
+	y1 = extents->y1;
+    if (y2 > extents->y2)
+	y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1)
+    {
+	x2 = x1 = 0;
+	y2 = y1 = 0;
+    }
+
+    box.x1 = x1;
+    box.x2 = x2;
+    box.y1 = y1;
+    box.y2 = y2;
+
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &reg, &box, 1);
+    if (pWin->backStorage)
+    {
+	/*
+	 * If the window has backing-store on, call through the
+	 * ClearToBackground vector to handle the special semantics
+	 * (i.e. things backing store is to be cleared out and
+	 * an Expose event is to be generated for those areas in backing
+	 * store if generateExposures is TRUE).
+	 */
+	pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+						 generateExposures);
+    }
+
+    REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+    if (generateExposures)
+	(*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+    else if (pWin->backgroundState != None)
+        (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+    REGION_UNINIT(pScreen, &reg);
+    if (pBSReg)
+	REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ *	Check all the inferiors of a window for coverage by saveUnder
+ *	windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ *	This code is very inefficient.
+ *
+ * Results:
+ *	TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+    register WindowPtr	pParent,	/* Parent to check */
+    WindowPtr		pFirst,		/* first reconfigured window */
+    RegionPtr		pRegion)	/* Initial area obscured by saveUnder */
+{
+    register WindowPtr	pChild;		/* Current child */
+    register ScreenPtr	pScreen;	/* Screen to use */
+    RegionRec		SubRegion;	/* Area of children obscured */
+    Bool		res = FALSE;	/* result */
+    Bool		subInited=FALSE;/* SubRegion initialized */
+
+    pScreen = pParent->drawable.pScreen;
+    if ( (pChild = pParent->firstChild) )
+    {
+	/*
+	 * build region above first changed window
+	 */
+
+	for (; pChild != pFirst; pChild = pChild->nextSib)
+	    if (pChild->viewable && pChild->saveUnder)
+		REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	
+	/*
+	 * check region below and including first changed window
+	 */
+
+	for (; pChild; pChild = pChild->nextSib)
+	{
+	    if (pChild->viewable)
+	    {
+		/*
+		 * don't save under nephew/niece windows;
+		 * use a separate region
+		 */
+
+		if (pChild->firstChild)
+		{
+		    if (!subInited)
+		    {
+			REGION_NULL(pScreen, &SubRegion);
+			subInited = TRUE;
+		    }
+		    REGION_COPY(pScreen, &SubRegion, pRegion);
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     &SubRegion);
+		}
+		else
+		{
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     pRegion);
+		}
+
+		if (pChild->saveUnder)
+		    REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	    }
+	}
+
+	if (subInited)
+	    REGION_UNINIT(pScreen, &SubRegion);
+    }
+
+    /*
+     * Check the state of this window.	DIX save unders are
+     * enabled for viewable windows with some client expressing
+     * exposure interest and which intersect the save under region
+     */
+
+    if (pParent->viewable && 
+	((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+	REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+	RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen, 
+					&pParent->borderSize)) != rgnOUT)
+    {
+	if (!pParent->DIXsaveUnder)
+	{
+	    pParent->DIXsaveUnder = TRUE;
+	    (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+	}
+    }
+    else
+    {
+	if (pParent->DIXsaveUnder)
+	{
+	    res = TRUE;
+	    pParent->DIXsaveUnder = FALSE;
+	}
+    }
+    return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ *	Change the save-under state of a tree of windows. Called when
+ *	a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *	
+ * Results:
+ *	TRUE if any windows need to have backing-store removed (which
+ *	means that PostChangeSaveUnder needs to be called later to 
+ *	finish the job).
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+    register WindowPtr	pWin;
+    WindowPtr		first;		/* First window to check.
+					 * Used when pWin was restacked */
+{
+    RegionRec	rgn;	/* Area obscured by saveUnder windows */
+    register ScreenPtr pScreen;
+    Bool	res;
+
+    if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+	return FALSE;
+    numSaveUndersViewable += deltaSaveUndersViewable;
+    deltaSaveUndersViewable = 0;
+    pScreen = pWin->drawable.pScreen;
+    REGION_NULL(pScreen, &rgn);
+    res = miCheckSubSaveUnder (pWin->parent,
+			       pWin->saveUnder ? first : pWin->nextSib,
+			       &rgn);
+    REGION_UNINIT(pScreen, &rgn);
+    return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ *	Actually turn backing-store off for those windows that no longer
+ *	need to have it on.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ *	windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+    WindowPtr		pWin;
+    WindowPtr		pFirst;
+{
+    register WindowPtr pParent, pChild;
+    ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+    if (!(pParent = pWin->parent))
+	return;
+    ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+    if (!pParent->DIXsaveUnder &&
+	(pParent->backingStore == NotUseful) && pParent->backStorage)
+	(*ChangeWindowAttributes)(pParent, CWBackingStore);
+    if (!(pChild = pFirst))
+	return;
+    while (1)
+    {
+	if (!pChild->DIXsaveUnder &&
+	    (pChild->backingStore == NotUseful) && pChild->backStorage)
+	    (*ChangeWindowAttributes)(pChild, CWBackingStore);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib)
+	{
+	    pChild = pChild->parent;
+	    if (pChild == pParent)
+		return;
+	}
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMarkWindow(pWin)
+    register WindowPtr pWin;
+{
+    register ValidatePtr val;
+
+    if (pWin->valdata)
+	return;
+    val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+    val->before.oldAbsCorner.x = pWin->drawable.x;
+    val->before.oldAbsCorner.y = pWin->drawable.y;
+    val->before.borderVisible = NullRegion;
+    val->before.resized = FALSE;
+    pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+    WindowPtr pWin;
+    WindowPtr pFirst;
+    WindowPtr *ppLayerWin;
+{
+    register BoxPtr box;
+    register WindowPtr pChild, pLast;
+    Bool anyMarked = FALSE;
+    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+    ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+
+    /* single layered systems are easy */
+    if (ppLayerWin) *ppLayerWin = pWin;
+
+    if (pWin == pFirst)
+    {
+	/* Blindly mark pWin and all of its inferiors.	 This is a slight
+	 * overkill if there are mapped windows that outside pWin's border,
+	 * but it's better than wasting time on RectIn checks.
+	 */
+	pChild = pWin;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		(* MarkWindow)(pChild);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pWin))
+		pChild = pChild->parent;
+	    if (pChild == pWin)
+		break;
+	    pChild = pChild->nextSib;
+	}
+	anyMarked = TRUE;
+	pFirst = pFirst->nextSib;
+    }
+    if ( (pChild = pFirst) )
+    {
+	box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+	pLast = pChild->parent->lastChild;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+		{
+		    (* MarkWindow)(pChild);
+		    anyMarked = TRUE;
+		    if (pChild->firstChild)
+		    {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pLast))
+		pChild = pChild->parent;
+	    if (pChild == pLast)
+		break;
+	    pChild = pChild->nextSib;
+	}
+    }
+    if (anyMarked)
+	(* MarkWindow)(pWin->parent);
+    return anyMarked;
+}
+
+/*****
+ *  miHandleValidateExposures(pWin)
+ *    starting at pWin, draw background in any windows that have exposure
+ *    regions, translate the regions, restore any backing store,
+ *    and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+    WindowPtr pWin;
+{
+    register WindowPtr pChild;
+    register ValidatePtr val;
+    ScreenPtr pScreen;
+    WindowExposuresProcPtr WindowExposures;
+
+    pScreen = pWin->drawable.pScreen;
+
+    pChild = pWin;
+    WindowExposures = pChild->drawable.pScreen->WindowExposures;
+    while (1)
+    {
+	if ( (val = pChild->valdata) )
+	{
+	    if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+		(*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+						    &val->after.borderExposed,
+						    PW_BORDER);
+	    REGION_UNINIT(pScreen, &val->after.borderExposed);
+	    (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+	    REGION_UNINIT(pScreen, &val->after.exposed);
+	    xfree(val);
+	    pChild->valdata = (ValidatePtr)NULL;
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+    register WindowPtr pWin;
+    int x,y;
+    WindowPtr pNextSib;
+    VTKind kind;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    short bw;
+    RegionPtr oldRegion = NULL;
+    DDXPointRec oldpt;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+    Bool dosave = FALSE;
+#endif
+    WindowPtr pLayerWin;
+
+    /* if this is a root window, can't be moved */
+    if (!(pParent = pWin->parent))
+       return ;
+    pScreen = pWin->drawable.pScreen;
+    bw = wBorderWidth (pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable)
+    {
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    }
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, windowToValidate, (WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+	    REGION_DESTROY(pScreen, oldRegion);
+	    /* XXX need to retile border if ParentRelative origin */
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+    register WindowPtr	pWin,
+    pointer		value) /* must conform to VisitWindowProcPtr */
+{
+    register ScreenPtr	pScreen;
+    RegionPtr	pValid = (RegionPtr)value;
+
+    if (pWin->valdata)
+    {
+	pScreen = pWin->drawable.pScreen;
+	/*
+	 * compute exposed regions of this window
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+			&pWin->clipList, pValid);
+	/*
+	 * compute exposed regions of the border
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->borderClip, &pWin->winSize);
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->valdata->after.borderExposed, pValid);
+	return WT_WALKCHILDREN;
+    }
+    return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+    register WindowPtr pWin;
+    int x,y;
+    unsigned int w, h;
+    WindowPtr pSib;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    unsigned short width = pWin->drawable.width,
+		   height = pWin->drawable.height;
+    short oldx = pWin->drawable.x,
+	  oldy = pWin->drawable.y;
+    int bw = wBorderWidth (pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr pFirstChange;
+    register WindowPtr pChild;
+    RegionPtr	gravitate[StaticGravity + 1];
+    register unsigned g;
+    int		nx, ny;		/* destination x,y */
+    int		newx, newy;	/* new inner window position */
+    RegionPtr	pRegion = NULL;
+    RegionPtr	destClip;	/* portions of destination already written */
+    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
+    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
+    RegionPtr	bsExposed = NullRegion;	    /* backing store exposures */
+    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
+    Bool	moved = FALSE;	/* window position changed */
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pScreen = pWin->drawable.pScreen;
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable)
+    {
+	anyMarked = FALSE;
+	/*
+	 * save the visible region of the window
+	 */
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+	/*
+	 * categorize child windows into regions to be moved
+	 */
+	for (g = 0; g <= StaticGravity; g++)
+	    gravitate[g] = (RegionPtr) NULL;
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	{
+	    g = pChild->winGravity;
+	    if (g != UnmapGravity)
+	    {
+		if (!gravitate[g])
+		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_UNION(pScreen, gravitate[g],
+				   gravitate[g], &pChild->borderClip);
+	    }
+	    else
+	    {
+		UnmapWindow(pChild, TRUE);
+		anyMarked = TRUE;
+	    }
+	}
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
+						       &pLayerWin);
+
+	oldWinClip = NULL;
+	if (pWin->bitGravity != ForgetGravity)
+	{
+	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+	}
+	/*
+	 * if the window is changing size, borderExposed
+	 * can't be computed correctly without some help.
+	 */
+	if (pWin->drawable.height > h || pWin->drawable.width > w)
+	    shrunk = TRUE;
+
+	if (newx != oldx || newy != oldy)
+	    moved = TRUE;
+
+	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+	    HasBorder (pWin))
+	{
+	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+	    /* for tiled borders, we punt and draw the whole thing */
+	    if (pWin->borderIsPixel || !moved)
+	    {
+		if (shrunk || moved)
+		    REGION_SUBTRACT(pScreen, borderVisible,
+					  &pWin->borderClip,
+					  &pWin->winSize);
+		else
+		    REGION_COPY(pScreen, borderVisible,
+					    &pWin->borderClip);
+	    }
+	}
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    dw = (int)w - (int)width;
+    dh = (int)h - (int)height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	pRegion = REGION_CREATE(pScreen, NullBox, 1);
+	if (pWin->backStorage)
+	    REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						(WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						(WindowPtr *)NULL);
+
+	if (pWin->valdata)
+	{
+	    pWin->valdata->before.resized = TRUE;
+	    pWin->valdata->before.borderVisible = borderVisible;
+	}
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+	/*
+	 * the entire window is trashed unless bitGravity
+	 * recovers portions of it
+	 */
+	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+    }
+
+    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pRegion = &pWin->clipList; /* a convenient empty region */
+	if (pWin->bitGravity == ForgetGravity)
+	    bsExposed = (*pScreen->TranslateBackingStore)
+				(pWin, 0, 0, NullRegion, oldx, oldy);
+	else
+	{
+	    bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+	}
+    }
+
+    if (WasViewable)
+    {
+	/* avoid the border */
+	if (HasBorder (pWin))
+	{
+	    int	offx, offy, dx, dy;
+
+	    /* kruft to avoid double translates for each gravity */
+	    offx = 0;
+	    offy = 0;
+	    for (g = 0; g <= StaticGravity; g++)
+	    {
+		if (!gravitate[g])
+		    continue;
+
+		/* align winSize to gravitate[g].
+		 * winSize is in new coordinates,
+		 * gravitate[g] is still in old coordinates */
+		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+		
+		dx = (oldx - nx) - offx;
+		dy = (oldy - ny) - offy;
+		if (dx || dy)
+		{
+		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+		    offx += dx;
+		    offy += dy;
+		}
+		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+				 &pWin->winSize);
+	    }
+	    /* get winSize back where it belongs */
+	    if (offx || offy)
+		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+	}
+	/*
+	 * add screen bits to the appropriate bucket
+	 */
+
+	if (oldWinClip)
+	{
+	    /*
+	     * clip to new clipList
+	     */
+	    REGION_COPY(pScreen, pRegion, oldWinClip);
+	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+	    /*
+	     * don't step on any gravity bits which will be copied after this
+	     * region.	Note -- this assumes that the regions will be copied
+	     * in gravity order.
+	     */
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+	    {
+		if (gravitate[g])
+		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+					gravitate[g]);
+	    }
+	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate[g])
+		gravitate[g] = oldWinClip;
+	    else
+	    {
+		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+		REGION_DESTROY(pScreen, oldWinClip);
+	    }
+	}
+
+	/*
+	 * move the bits on the screen
+	 */
+
+	destClip = NULL;
+
+	for (g = 0; g <= StaticGravity; g++)
+	{
+	    if (!gravitate[g])
+		continue;
+
+	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+	    oldpt.x = oldx + (x - nx);
+	    oldpt.y = oldy + (y - ny);
+
+	    /* Note that gravitate[g] is *translated* by CopyWindow */
+
+	    /* only copy the remaining useful bits */
+
+	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+	    /* clip to not overwrite already copied areas */
+
+	    if (destClip) {
+		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+	    }
+
+	    /* and move those bits */
+
+	    if (oldpt.x != x || oldpt.y != y
+#ifdef COMPOSITE
+		|| pWin->redirectDraw
+#endif
+		)
+	    {
+		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+	    }
+
+	    /* remove any overwritten bits from the remaining useful bits */
+
+	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+	    /*
+	     * recompute exposed regions of child windows
+	     */
+	
+	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	    {
+		if (pChild->winGravity != g)
+		    continue;
+		REGION_INTERSECT(pScreen, pRegion,
+				       &pChild->borderClip, gravitate[g]);
+		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+	    }
+
+	    /*
+	     * remove the successfully copied regions of the
+	     * window from its exposed region
+	     */
+
+	    if (g == pWin->bitGravity)
+		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+				     &pWin->valdata->after.exposed, gravitate[g]);
+	    if (!destClip)
+		destClip = gravitate[g];
+	    else
+	    {
+		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+		REGION_DESTROY(pScreen, gravitate[g]);
+	    }
+	}
+
+	REGION_DESTROY(pScreen, oldRegion);
+	REGION_DESTROY(pScreen, pRegion);
+	if (destClip)
+	    REGION_DESTROY(pScreen, destClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	{
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+					  VTOther);
+    }
+    else if (bsExposed)
+    {
+	(*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+	REGION_DESTROY(pScreen, bsExposed);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+    WindowPtr pWin;
+{
+    return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ *    The border/window shape has changed.  Recompute winSize/borderSize
+ *    and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+    register WindowPtr	pWin;
+{
+    Bool	WasViewable = (Bool)(pWin->viewable);
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    Bool	anyMarked = FALSE;
+    RegionPtr	pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr   pLayerWin;
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						      &pLayerWin);
+	if (pWin->valdata)
+	{
+	    if (HasBorder (pWin))
+	    {
+		RegionPtr	borderVisible;
+
+		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	    pWin->valdata->before.resized = TRUE;
+	}
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pWin->backStorage)
+	{
+	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+	}
+
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						(WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pOldClip = &pWin->clipList; /* a convenient empty region */
+	bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, 0, 0, pOldClip,
+			      pWin->drawable.x, pWin->drawable.y);
+#ifdef NXAGENT_SERVER
+
+        /*
+         * We got a few, rare, segfaults here after having
+         * started using the backing store. It may be a
+         * different bug but miChangeSaveUnder() calls mi-
+         * CheckSubSaveUnder() that, in turn, can change
+         * the backing store attribute of the window. This
+         * means that we may try to destroy the region
+         * even if it was not created at the beginning of
+         * this function as, at the time, the backing store
+         * was off. miCheckSubSaveUnder() appear to get a
+         * pointer to the parent, so maybe doesn't change
+         * the attribute of the window itself. This is to
+         * be better investigated.
+         */
+
+        if (WasViewable && pOldClip)
+            REGION_DESTROY(pScreen, pOldClip);
+#else
+	if (WasViewable)
+	    REGION_DESTROY(pScreen, pOldClip);
+#endif
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+    
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+    }
+    if (WasViewable)
+    {
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+    CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+    register WindowPtr pWin;
+    unsigned int width;
+{
+    int oldwidth;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    oldwidth = wBorderWidth (pWin);
+    if (oldwidth == width)
+	return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    if (WasViewable && width < oldwidth)
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+    pWin->borderWidth = width;
+    SetBorderSize (pWin);
+
+    if (WasViewable)
+    {
+	if (width > oldwidth)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+	    /*
+	     * save the old border visible region to correctly compute
+	     * borderExposed.
+	     */
+	    if (pWin->valdata && HadBorder)
+	    {
+		RegionPtr   borderVisible;
+		borderVisible = REGION_CREATE(pScreen, NULL, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+					  VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+    WindowPtr pChild;
+    WindowPtr pWin;
+    Bool fromConfigure;
+{
+    if ((pChild != pWin) || fromConfigure)
+    {
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+	if (pChild->drawable.pScreen->ClipNotify)
+	    (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+    }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+    ScreenPtr pScreen;
+    WindowPtr pChild;
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+    {
+	if (pChild->drawable.depth == depth)
+	    REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+	if (pChild->firstChild)
+	    miSegregateChildren(pChild, pReg, depth);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original
new file mode 100644
index 000000000..280d0f8eb
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.X.original
@@ -0,0 +1,1184 @@
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.9tsi Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: miwindow.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "regionstr.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void 
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+    WindowPtr pWin;
+    int x,y;
+    int w,h;
+    Bool generateExposures;
+{
+    BoxRec box;
+    RegionRec	reg;
+    RegionPtr pBSReg = NullRegion;
+    ScreenPtr	pScreen;
+    BoxPtr  extents;
+    int	    x1, y1, x2, y2;
+
+    /* compute everything using ints to avoid overflow */
+
+    x1 = pWin->drawable.x + x;
+    y1 = pWin->drawable.y + y;
+    if (w)
+        x2 = x1 + (int) w;
+    else
+        x2 = x1 + (int) pWin->drawable.width - (int) x;
+    if (h)
+        y2 = y1 + h;	
+    else
+        y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+    extents = &pWin->clipList.extents;
+    
+    /* clip the resulting rectangle to the window clipList extents.  This
+     * makes sure that the result will fit in a box, given that the
+     * screen is < 32768 on a side.
+     */
+
+    if (x1 < extents->x1)
+	x1 = extents->x1;
+    if (x2 > extents->x2)
+	x2 = extents->x2;
+    if (y1 < extents->y1)
+	y1 = extents->y1;
+    if (y2 > extents->y2)
+	y2 = extents->y2;
+
+    if (x2 <= x1 || y2 <= y1)
+    {
+	x2 = x1 = 0;
+	y2 = y1 = 0;
+    }
+
+    box.x1 = x1;
+    box.x2 = x2;
+    box.y1 = y1;
+    box.y2 = y2;
+
+    pScreen = pWin->drawable.pScreen;
+    REGION_INIT(pScreen, &reg, &box, 1);
+    if (pWin->backStorage)
+    {
+	/*
+	 * If the window has backing-store on, call through the
+	 * ClearToBackground vector to handle the special semantics
+	 * (i.e. things backing store is to be cleared out and
+	 * an Expose event is to be generated for those areas in backing
+	 * store if generateExposures is TRUE).
+	 */
+	pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+						 generateExposures);
+    }
+
+    REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+    if (generateExposures)
+	(*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+    else if (pWin->backgroundState != None)
+        (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+    REGION_UNINIT(pScreen, &reg);
+    if (pBSReg)
+	REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ *	Check all the inferiors of a window for coverage by saveUnder
+ *	windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ *	This code is very inefficient.
+ *
+ * Results:
+ *	TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(
+    register WindowPtr	pParent,	/* Parent to check */
+    WindowPtr		pFirst,		/* first reconfigured window */
+    RegionPtr		pRegion)	/* Initial area obscured by saveUnder */
+{
+    register WindowPtr	pChild;		/* Current child */
+    register ScreenPtr	pScreen;	/* Screen to use */
+    RegionRec		SubRegion;	/* Area of children obscured */
+    Bool		res = FALSE;	/* result */
+    Bool		subInited=FALSE;/* SubRegion initialized */
+
+    pScreen = pParent->drawable.pScreen;
+    if ( (pChild = pParent->firstChild) )
+    {
+	/*
+	 * build region above first changed window
+	 */
+
+	for (; pChild != pFirst; pChild = pChild->nextSib)
+	    if (pChild->viewable && pChild->saveUnder)
+		REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	
+	/*
+	 * check region below and including first changed window
+	 */
+
+	for (; pChild; pChild = pChild->nextSib)
+	{
+	    if (pChild->viewable)
+	    {
+		/*
+		 * don't save under nephew/niece windows;
+		 * use a separate region
+		 */
+
+		if (pChild->firstChild)
+		{
+		    if (!subInited)
+		    {
+			REGION_NULL(pScreen, &SubRegion);
+			subInited = TRUE;
+		    }
+		    REGION_COPY(pScreen, &SubRegion, pRegion);
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     &SubRegion);
+		}
+		else
+		{
+		    res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+					     pRegion);
+		}
+
+		if (pChild->saveUnder)
+		    REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+	    }
+	}
+
+	if (subInited)
+	    REGION_UNINIT(pScreen, &SubRegion);
+    }
+
+    /*
+     * Check the state of this window.	DIX save unders are
+     * enabled for viewable windows with some client expressing
+     * exposure interest and which intersect the save under region
+     */
+
+    if (pParent->viewable && 
+	((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+	REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+	RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen, 
+					&pParent->borderSize)) != rgnOUT)
+    {
+	if (!pParent->DIXsaveUnder)
+	{
+	    pParent->DIXsaveUnder = TRUE;
+	    (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+	}
+    }
+    else
+    {
+	if (pParent->DIXsaveUnder)
+	{
+	    res = TRUE;
+	    pParent->DIXsaveUnder = FALSE;
+	}
+    }
+    return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ *	Change the save-under state of a tree of windows. Called when
+ *	a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *	
+ * Results:
+ *	TRUE if any windows need to have backing-store removed (which
+ *	means that PostChangeSaveUnder needs to be called later to 
+ *	finish the job).
+ *
+ * Side Effects:
+ *	Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+    register WindowPtr	pWin;
+    WindowPtr		first;		/* First window to check.
+					 * Used when pWin was restacked */
+{
+    RegionRec	rgn;	/* Area obscured by saveUnder windows */
+    register ScreenPtr pScreen;
+    Bool	res;
+
+    if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+	return FALSE;
+    numSaveUndersViewable += deltaSaveUndersViewable;
+    deltaSaveUndersViewable = 0;
+    pScreen = pWin->drawable.pScreen;
+    REGION_NULL(pScreen, &rgn);
+    res = miCheckSubSaveUnder (pWin->parent,
+			       pWin->saveUnder ? first : pWin->nextSib,
+			       &rgn);
+    REGION_UNINIT(pScreen, &rgn);
+    return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ *	Actually turn backing-store off for those windows that no longer
+ *	need to have it on.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ *	windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+    WindowPtr		pWin;
+    WindowPtr		pFirst;
+{
+    register WindowPtr pParent, pChild;
+    ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+    if (!(pParent = pWin->parent))
+	return;
+    ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+    if (!pParent->DIXsaveUnder &&
+	(pParent->backingStore == NotUseful) && pParent->backStorage)
+	(*ChangeWindowAttributes)(pParent, CWBackingStore);
+    if (!(pChild = pFirst))
+	return;
+    while (1)
+    {
+	if (!pChild->DIXsaveUnder &&
+	    (pChild->backingStore == NotUseful) && pChild->backStorage)
+	    (*ChangeWindowAttributes)(pChild, CWBackingStore);
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib)
+	{
+	    pChild = pChild->parent;
+	    if (pChild == pParent)
+		return;
+	}
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMarkWindow(pWin)
+    register WindowPtr pWin;
+{
+    register ValidatePtr val;
+
+    if (pWin->valdata)
+	return;
+    val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+    val->before.oldAbsCorner.x = pWin->drawable.x;
+    val->before.oldAbsCorner.y = pWin->drawable.y;
+    val->before.borderVisible = NullRegion;
+    val->before.resized = FALSE;
+    pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+    WindowPtr pWin;
+    WindowPtr pFirst;
+    WindowPtr *ppLayerWin;
+{
+    register BoxPtr box;
+    register WindowPtr pChild, pLast;
+    Bool anyMarked = FALSE;
+    MarkWindowProcPtr MarkWindow = pWin->drawable.pScreen->MarkWindow;
+    ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+
+    /* single layered systems are easy */
+    if (ppLayerWin) *ppLayerWin = pWin;
+
+    if (pWin == pFirst)
+    {
+	/* Blindly mark pWin and all of its inferiors.	 This is a slight
+	 * overkill if there are mapped windows that outside pWin's border,
+	 * but it's better than wasting time on RectIn checks.
+	 */
+	pChild = pWin;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		(* MarkWindow)(pChild);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pWin))
+		pChild = pChild->parent;
+	    if (pChild == pWin)
+		break;
+	    pChild = pChild->nextSib;
+	}
+	anyMarked = TRUE;
+	pFirst = pFirst->nextSib;
+    }
+    if ( (pChild = pFirst) )
+    {
+	box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+	pLast = pChild->parent->lastChild;
+	while (1)
+	{
+	    if (pChild->viewable)
+	    {
+		if (REGION_BROKEN (pScreen, &pChild->winSize))
+		    SetWinSize (pChild);
+		if (REGION_BROKEN (pScreen, &pChild->borderSize))
+		    SetBorderSize (pChild);
+		if (RECT_IN_REGION(pScreen, &pChild->borderSize, box))
+		{
+		    (* MarkWindow)(pChild);
+		    anyMarked = TRUE;
+		    if (pChild->firstChild)
+		    {
+			pChild = pChild->firstChild;
+			continue;
+		    }
+		}
+	    }
+	    while (!pChild->nextSib && (pChild != pLast))
+		pChild = pChild->parent;
+	    if (pChild == pLast)
+		break;
+	    pChild = pChild->nextSib;
+	}
+    }
+    if (anyMarked)
+	(* MarkWindow)(pWin->parent);
+    return anyMarked;
+}
+
+/*****
+ *  miHandleValidateExposures(pWin)
+ *    starting at pWin, draw background in any windows that have exposure
+ *    regions, translate the regions, restore any backing store,
+ *    and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+    WindowPtr pWin;
+{
+    register WindowPtr pChild;
+    register ValidatePtr val;
+    ScreenPtr pScreen;
+    WindowExposuresProcPtr WindowExposures;
+
+    pScreen = pWin->drawable.pScreen;
+
+    pChild = pWin;
+    WindowExposures = pChild->drawable.pScreen->WindowExposures;
+    while (1)
+    {
+	if ( (val = pChild->valdata) )
+	{
+	    if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+		(*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+						    &val->after.borderExposed,
+						    PW_BORDER);
+	    REGION_UNINIT(pScreen, &val->after.borderExposed);
+	    (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+	    REGION_UNINIT(pScreen, &val->after.exposed);
+	    xfree(val);
+	    pChild->valdata = (ValidatePtr)NULL;
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+    register WindowPtr pWin;
+    int x,y;
+    WindowPtr pNextSib;
+    VTKind kind;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    short bw;
+    RegionPtr oldRegion = NULL;
+    DDXPointRec oldpt;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+    Bool dosave = FALSE;
+#endif
+    WindowPtr pLayerWin;
+
+    /* if this is a root window, can't be moved */
+    if (!(pParent = pWin->parent))
+       return ;
+    pScreen = pWin->drawable.pScreen;
+    bw = wBorderWidth (pWin);
+
+    oldpt.x = pWin->drawable.x;
+    oldpt.y = pWin->drawable.y;
+    if (WasViewable)
+    {
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    }
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+    ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, windowToValidate, (WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)
+				(pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+	    (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+	    REGION_DESTROY(pScreen, oldRegion);
+	    /* XXX need to retile border if ParentRelative origin */
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (
+    register WindowPtr	pWin,
+    pointer		value) /* must conform to VisitWindowProcPtr */
+{
+    register ScreenPtr	pScreen;
+    RegionPtr	pValid = (RegionPtr)value;
+
+    if (pWin->valdata)
+    {
+	pScreen = pWin->drawable.pScreen;
+	/*
+	 * compute exposed regions of this window
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+			&pWin->clipList, pValid);
+	/*
+	 * compute exposed regions of the border
+	 */
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->borderClip, &pWin->winSize);
+	REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+			     &pWin->valdata->after.borderExposed, pValid);
+	return WT_WALKCHILDREN;
+    }
+    return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+    register WindowPtr pWin;
+    int x,y;
+    unsigned int w, h;
+    WindowPtr pSib;
+{
+    WindowPtr pParent;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    unsigned short width = pWin->drawable.width,
+		   height = pWin->drawable.height;
+    short oldx = pWin->drawable.x,
+	  oldy = pWin->drawable.y;
+    int bw = wBorderWidth (pWin);
+    short dw, dh;
+    DDXPointRec oldpt;
+    RegionPtr oldRegion = NULL;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    WindowPtr pFirstChange;
+    register WindowPtr pChild;
+    RegionPtr	gravitate[StaticGravity + 1];
+    register unsigned g;
+    int		nx, ny;		/* destination x,y */
+    int		newx, newy;	/* new inner window position */
+    RegionPtr	pRegion = NULL;
+    RegionPtr	destClip;	/* portions of destination already written */
+    RegionPtr	oldWinClip = NULL;	/* old clip list for window */
+    RegionPtr	borderVisible = NullRegion; /* visible area of the border */
+    RegionPtr	bsExposed = NullRegion;	    /* backing store exposures */
+    Bool	shrunk = FALSE; /* shrunk in an inner dimension */
+    Bool	moved = FALSE;	/* window position changed */
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    /* if this is a root window, can't be resized */
+    if (!(pParent = pWin->parent))
+	return ;
+
+    pScreen = pWin->drawable.pScreen;
+    newx = pParent->drawable.x + x + bw;
+    newy = pParent->drawable.y + y + bw;
+    if (WasViewable)
+    {
+	anyMarked = FALSE;
+	/*
+	 * save the visible region of the window
+	 */
+	oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+	REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+	/*
+	 * categorize child windows into regions to be moved
+	 */
+	for (g = 0; g <= StaticGravity; g++)
+	    gravitate[g] = (RegionPtr) NULL;
+	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	{
+	    g = pChild->winGravity;
+	    if (g != UnmapGravity)
+	    {
+		if (!gravitate[g])
+		    gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_UNION(pScreen, gravitate[g],
+				   gravitate[g], &pChild->borderClip);
+	    }
+	    else
+	    {
+		UnmapWindow(pChild, TRUE);
+		anyMarked = TRUE;
+	    }
+	}
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin, 
+						       &pLayerWin);
+
+	oldWinClip = NULL;
+	if (pWin->bitGravity != ForgetGravity)
+	{
+	    oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+	}
+	/*
+	 * if the window is changing size, borderExposed
+	 * can't be computed correctly without some help.
+	 */
+	if (pWin->drawable.height > h || pWin->drawable.width > w)
+	    shrunk = TRUE;
+
+	if (newx != oldx || newy != oldy)
+	    moved = TRUE;
+
+	if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+	    HasBorder (pWin))
+	{
+	    borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+	    /* for tiled borders, we punt and draw the whole thing */
+	    if (pWin->borderIsPixel || !moved)
+	    {
+		if (shrunk || moved)
+		    REGION_SUBTRACT(pScreen, borderVisible,
+					  &pWin->borderClip,
+					  &pWin->winSize);
+		else
+		    REGION_COPY(pScreen, borderVisible,
+					    &pWin->borderClip);
+	    }
+	}
+    }
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.height = h;
+    pWin->drawable.width = w;
+
+    x = pWin->drawable.x = newx;
+    y = pWin->drawable.y = newy;
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    dw = (int)w - (int)width;
+    dh = (int)h - (int)height;
+    ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+    /* let the hardware adjust background and border pixmaps, if any */
+    (*pScreen->PositionWindow)(pWin, x, y);
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	pRegion = REGION_CREATE(pScreen, NullBox, 1);
+	if (pWin->backStorage)
+	    REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+	if (pLayerWin == pWin)
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						(WindowPtr *)NULL);
+	else
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						(WindowPtr *)NULL);
+
+	if (pWin->valdata)
+	{
+	    pWin->valdata->before.resized = TRUE;
+	    pWin->valdata->before.borderVisible = borderVisible;
+	}
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+	/*
+	 * the entire window is trashed unless bitGravity
+	 * recovers portions of it
+	 */
+	REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+    }
+
+    GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pRegion = &pWin->clipList; /* a convenient empty region */
+	if (pWin->bitGravity == ForgetGravity)
+	    bsExposed = (*pScreen->TranslateBackingStore)
+				(pWin, 0, 0, NullRegion, oldx, oldy);
+	else
+	{
+	    bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+	}
+    }
+
+    if (WasViewable)
+    {
+	/* avoid the border */
+	if (HasBorder (pWin))
+	{
+	    int	offx, offy, dx, dy;
+
+	    /* kruft to avoid double translates for each gravity */
+	    offx = 0;
+	    offy = 0;
+	    for (g = 0; g <= StaticGravity; g++)
+	    {
+		if (!gravitate[g])
+		    continue;
+
+		/* align winSize to gravitate[g].
+		 * winSize is in new coordinates,
+		 * gravitate[g] is still in old coordinates */
+		GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+		
+		dx = (oldx - nx) - offx;
+		dy = (oldy - ny) - offy;
+		if (dx || dy)
+		{
+		    REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+		    offx += dx;
+		    offy += dy;
+		}
+		REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+				 &pWin->winSize);
+	    }
+	    /* get winSize back where it belongs */
+	    if (offx || offy)
+		REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+	}
+	/*
+	 * add screen bits to the appropriate bucket
+	 */
+
+	if (oldWinClip)
+	{
+	    /*
+	     * clip to new clipList
+	     */
+	    REGION_COPY(pScreen, pRegion, oldWinClip);
+	    REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+	    REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+	    /*
+	     * don't step on any gravity bits which will be copied after this
+	     * region.	Note -- this assumes that the regions will be copied
+	     * in gravity order.
+	     */
+	    for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+	    {
+		if (gravitate[g])
+		    REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+					gravitate[g]);
+	    }
+	    REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+	    g = pWin->bitGravity;
+	    if (!gravitate[g])
+		gravitate[g] = oldWinClip;
+	    else
+	    {
+		REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+		REGION_DESTROY(pScreen, oldWinClip);
+	    }
+	}
+
+	/*
+	 * move the bits on the screen
+	 */
+
+	destClip = NULL;
+
+	for (g = 0; g <= StaticGravity; g++)
+	{
+	    if (!gravitate[g])
+		continue;
+
+	    GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+	    oldpt.x = oldx + (x - nx);
+	    oldpt.y = oldy + (y - ny);
+
+	    /* Note that gravitate[g] is *translated* by CopyWindow */
+
+	    /* only copy the remaining useful bits */
+
+	    REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+	    /* clip to not overwrite already copied areas */
+
+	    if (destClip) {
+		REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+		REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+		REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+	    }
+
+	    /* and move those bits */
+
+	    if (oldpt.x != x || oldpt.y != y
+#ifdef COMPOSITE
+		|| pWin->redirectDraw
+#endif
+		)
+	    {
+		(*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+	    }
+
+	    /* remove any overwritten bits from the remaining useful bits */
+
+	    REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+	    /*
+	     * recompute exposed regions of child windows
+	     */
+	
+	    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+	    {
+		if (pChild->winGravity != g)
+		    continue;
+		REGION_INTERSECT(pScreen, pRegion,
+				       &pChild->borderClip, gravitate[g]);
+		TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+	    }
+
+	    /*
+	     * remove the successfully copied regions of the
+	     * window from its exposed region
+	     */
+
+	    if (g == pWin->bitGravity)
+		REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+				     &pWin->valdata->after.exposed, gravitate[g]);
+	    if (!destClip)
+		destClip = gravitate[g];
+	    else
+	    {
+		REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+		REGION_DESTROY(pScreen, gravitate[g]);
+	    }
+	}
+
+	REGION_DESTROY(pScreen, oldRegion);
+	REGION_DESTROY(pScreen, pRegion);
+	if (destClip)
+	    REGION_DESTROY(pScreen, destClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	{
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+					  VTOther);
+    }
+    else if (bsExposed)
+    {
+	(*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+	REGION_DESTROY(pScreen, bsExposed);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+    WindowPtr pWin;
+{
+    return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ *    The border/window shape has changed.  Recompute winSize/borderSize
+ *    and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+    register WindowPtr	pWin;
+{
+    Bool	WasViewable = (Bool)(pWin->viewable);
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+    Bool	anyMarked = FALSE;
+    RegionPtr	pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr   pLayerWin;
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						      &pLayerWin);
+	if (pWin->valdata)
+	{
+	    if (HasBorder (pWin))
+	    {
+		RegionPtr	borderVisible;
+
+		borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	    pWin->valdata->before.resized = TRUE;
+	}
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+	if (pWin->backStorage)
+	{
+	    pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+	    REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+	}
+
+	anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+						(WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	    (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+
+    if (pWin->backStorage &&
+	((pWin->backingStore == Always) || WasViewable))
+    {
+	if (!WasViewable)
+	    pOldClip = &pWin->clipList; /* a convenient empty region */
+	bsExposed = (*pScreen->TranslateBackingStore)
+			     (pWin, 0, 0, pOldClip,
+			      pWin->drawable.x, pWin->drawable.y);
+	if (WasViewable)
+	    REGION_DESTROY(pScreen, pOldClip);
+	if (bsExposed)
+	{
+	    RegionPtr	valExposed = NullRegion;
+    
+	    if (pWin->valdata)
+		valExposed = &pWin->valdata->after.exposed;
+	    (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+	    if (valExposed)
+		REGION_EMPTY(pScreen, valExposed);
+	    REGION_DESTROY(pScreen, bsExposed);
+	}
+    }
+    if (WasViewable)
+    {
+	if (anyMarked)
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+    CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+    register WindowPtr pWin;
+    unsigned int width;
+{
+    int oldwidth;
+    Bool anyMarked = FALSE;
+    register ScreenPtr pScreen;
+    Bool WasViewable = (Bool)(pWin->viewable);
+    Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    oldwidth = wBorderWidth (pWin);
+    if (oldwidth == width)
+	return;
+    HadBorder = HasBorder(pWin);
+    pScreen = pWin->drawable.pScreen;
+    if (WasViewable && width < oldwidth)
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+    pWin->borderWidth = width;
+    SetBorderSize (pWin);
+
+    if (WasViewable)
+    {
+	if (width > oldwidth)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+	    /*
+	     * save the old border visible region to correctly compute
+	     * borderExposed.
+	     */
+	    if (pWin->valdata && HadBorder)
+	    {
+		RegionPtr   borderVisible;
+		borderVisible = REGION_CREATE(pScreen, NULL, 1);
+		REGION_SUBTRACT(pScreen, borderVisible,
+				      &pWin->borderClip, &pWin->winSize);
+		pWin->valdata->before.borderVisible = borderVisible;
+	    }
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	}
+#endif /* DO_SAVE_UNDERS */
+
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+					  VTOther);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+    WindowPtr pChild;
+    WindowPtr pWin;
+    Bool fromConfigure;
+{
+    if ((pChild != pWin) || fromConfigure)
+    {
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+	if (pChild->drawable.pScreen->ClipNotify)
+	    (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+	REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+    }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+    ScreenPtr pScreen;
+    WindowPtr pChild;
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+    {
+	if (pChild->drawable.depth == depth)
+	    REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+	if (pChild->firstChild)
+	    miSegregateChildren(pChild, pReg, depth);
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
new file mode 100644
index 000000000..5d6f71475
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -0,0 +1,2220 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "NXpicturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
+
+int		PictureScreenPrivateIndex = -1;
+int		PictureWindowPrivateIndex;
+int		PictureGeneration;
+RESTYPE		PictureType;
+RESTYPE		PictFormatType;
+RESTYPE		GlyphSetType;
+int		PictureCmapPolicy = PictureCmapPolicyDefault;
+
+typedef struct _formatInit {
+    CARD32  format;
+    CARD8   depth;
+} FormatInitRec, *FormatInitPtr;
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+    picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+    return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    unsigned int	oldamount;
+
+    /* Round up sizes for proper alignment */
+    amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+    if (index2 >= ps->PicturePrivateLen)
+    {
+	unsigned int *nsizes;
+
+	nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+					  (index2 + 1) * sizeof(unsigned int));
+	if (!nsizes)
+	    return FALSE;
+	while (ps->PicturePrivateLen <= index2)
+	{
+	    nsizes[ps->PicturePrivateLen++] = 0;
+	    ps->totalPictureSize += sizeof(DevUnion);
+	}
+	ps->PicturePrivateSizes = nsizes;
+    }
+    oldamount = ps->PicturePrivateSizes[index2];
+    if (amount > oldamount)
+    {
+	ps->PicturePrivateSizes[index2] = amount;
+	ps->totalPictureSize += (amount - oldamount);
+    }
+
+    return TRUE;
+}
+
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+    ScreenPtr		pScreen = pWindow->drawable.pScreen;
+    PicturePtr		pPicture;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool		ret;
+
+    while ((pPicture = GetPictureWindow(pWindow)))
+    {
+	SetPictureWindow(pWindow, pPicture->pNext);
+	if (pPicture->id)
+	    FreeResource (pPicture->id, PictureType);
+	FreePicture ((pointer) pPicture, pPicture->id);
+    }
+    pScreen->DestroyWindow = ps->DestroyWindow;
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool                ret;
+    int			n;
+
+    pScreen->CloseScreen = ps->CloseScreen;
+    ret = (*pScreen->CloseScreen) (index, pScreen);
+    PictureResetFilters (pScreen);
+    for (n = 0; n < ps->nformats; n++)
+	if (ps->formats[n].type == PictTypeIndexed)
+	    (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+    SetPictureScreen(pScreen, 0);
+    if (ps->PicturePrivateSizes)
+	xfree (ps->PicturePrivateSizes);
+    xfree (ps->formats);
+    xfree (ps);
+    return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+    ScreenPtr		pScreen = pColormap->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    pScreen->StoreColors = ps->StoreColors;
+    (*pScreen->StoreColors) (pColormap, ndef, pdef);
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+    {
+	PictFormatPtr	format = ps->formats;
+	int		nformats = ps->nformats;
+
+	while (nformats--)
+	{
+	    if (format->type == PictTypeIndexed &&
+		format->index.pColormap == pColormap)
+	    {
+		(*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+		break;
+	    }
+	    format++;
+	}
+    }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    int		d, v;
+    DepthPtr	pDepth;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	for (v = 0; v < pDepth->numVids; v++)
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+    }
+    return 0;
+}
+
+static int
+addFormat (FormatInitRec    formats[256],
+	   int		    nformat,
+	   CARD32	    format,
+	   CARD8	    depth)
+{
+    int	n;
+
+    for (n = 0; n < nformat; n++)
+	if (formats[n].format == format && formats[n].depth == depth)
+	    return nformat;
+    formats[nformat].format = format;
+    formats[nformat].depth = depth;
+
+    #ifdef DEBUG
+    fprintf(stderr, "addFormat: Added format [%lu] depth [%d].\n", format, depth);
+    #endif
+
+    return ++nformat;
+}
+
+#define Mask(n)	((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+    int             nformats, f;
+    PictFormatPtr   pFormats;
+    FormatInitRec   formats[1024];
+    CARD32	    format;
+
+#ifndef NXAGENT_SERVER
+
+    CARD8	    depth;
+    VisualPtr	    pVisual;
+    int		    v;
+    int		    bpp;
+    int		    type;
+    int		    r, g, b;
+    int		    d;
+    DepthPtr	    pDepth;
+
+#endif
+
+    nformats = 0;
+
+#ifdef NXAGENT_SERVER
+
+    nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
+
+#else
+
+    /* formats required by protocol */
+    formats[nformats].format = PICT_a1;
+    formats[nformats].depth = 1;
+    nformats++;
+    formats[nformats].format = PICT_a8;
+    formats[nformats].depth = 8;
+    nformats++;
+    formats[nformats].format = PICT_a4;
+    formats[nformats].depth = 4;
+    nformats++;
+    formats[nformats].format = PICT_a8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+    formats[nformats].format = PICT_x8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+
+    /* now look through the depths and visuals adding other formats */
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = &pScreen->visuals[v];
+	depth = visualDepth (pScreen, pVisual);
+	if (!depth)
+	    continue;
+    	bpp = BitsPerPixel (depth);
+
+	switch (pVisual->class) {
+	case DirectColor:
+	case TrueColor:
+	    r = Ones (pVisual->redMask);
+	    g = Ones (pVisual->greenMask);
+	    b = Ones (pVisual->blueMask);
+	    type = PICT_TYPE_OTHER;
+	    /*
+	     * Current rendering code supports only two direct formats,
+	     * fields must be packed together at the bottom of the pixel
+	     * and must be either RGB or BGR
+	     */
+	    if (pVisual->offsetBlue == 0 &&
+		pVisual->offsetGreen == b &&
+		pVisual->offsetRed == b + g)
+	    {
+		type = PICT_TYPE_ARGB;
+	    }
+	    else if (pVisual->offsetRed == 0 &&
+		     pVisual->offsetGreen == r && 
+		     pVisual->offsetBlue == r + g)
+	    {
+		type = PICT_TYPE_ABGR;
+	    }
+	    if (type != PICT_TYPE_OTHER)
+	    {
+		format = PICT_FORMAT(bpp, type, 0, r, g, b);
+		nformats = addFormat (formats, nformats, format, depth);
+	    }
+	    break;
+	case StaticColor:
+	case PseudoColor:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	case StaticGray:
+	case GrayScale:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	}
+    }
+
+    /*
+     * Walk supported depths and add useful Direct formats
+     */
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	bpp = BitsPerPixel (pDepth->depth);
+	format = 0;
+
+	switch (bpp) {
+	case 16:
+	    /* depth 12 formats */
+	     if (pDepth->depth >= 12)
+	     {
+	        nformats = addFormat (formats, nformats,
+	      		      PICT_x4r4g4b4, pDepth->depth);
+	        nformats = addFormat (formats, nformats,
+	      		      PICT_x4b4g4r4, pDepth->depth);
+	     }
+
+	    /* depth 15 formats */
+	    if (pDepth->depth >= 15)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x1b5g5r5, pDepth->depth);
+	    }
+	    /* depth 16 formats */
+	    if (pDepth->depth >= 16) 
+	    {
+	        nformats = addFormat (formats, nformats,
+	        		      PICT_a1r5g5b5, pDepth->depth);
+	        nformats = addFormat (formats, nformats,
+	       	        	      PICT_a1b5g5r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_r5g6b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b5g6r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4r4g4b4, pDepth->depth);
+	        nformats = addFormat (formats, nformats,
+	        		      PICT_a4b4g4r4, pDepth->depth);
+	    }
+	    break;
+	case 24:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b8g8r8, pDepth->depth);
+	    }
+	    break;
+	case 32:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x8r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x8b8g8r8, pDepth->depth);
+	    }
+	    break;
+	}
+    }
+
+#endif
+
+    pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+    if (!pFormats)
+	return 0;
+    memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+    for (f = 0; f < nformats; f++)
+    {
+        pFormats[f].id = FakeClientID (0);
+        pFormats[f].depth = formats[f].depth;
+        format = formats[f].format;
+        pFormats[f].format = format;
+	switch (PICT_FORMAT_TYPE(format)) {
+	case PICT_TYPE_ARGB:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = (PICT_FORMAT_G(format) + 
+				      PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_B(format);
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = 0;
+	    break;
+
+	case PICT_TYPE_ABGR:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = (PICT_FORMAT_G(format) + 
+				       PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_R(format);
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = 0;
+	    break;
+
+	case PICT_TYPE_A:
+	    pFormats[f].type = PictTypeDirect;
+
+	    pFormats[f].direct.alpha = 0;
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+	    /* remaining fields already set to zero */
+	    break;
+	    
+	case PICT_TYPE_COLOR:
+	case PICT_TYPE_GRAY:
+	    pFormats[f].type = PictTypeIndexed;
+	    pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+	    break;
+	}
+
+#ifdef NXAGENT_SERVER
+        if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+        {
+          #ifdef DEBUG
+          fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+                      "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] matches.\n",
+                          pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+                              pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+                                  pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+          #endif
+        }
+        else
+        {
+          #ifdef DEBUG
+          fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+                      "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] doesn't match.\n",
+                          pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+                              pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+                                  pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+          #endif
+        } 
+#endif
+    }
+    *nformatp = nformats;
+    return pFormats;
+}
+
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+    int         i;
+    VisualPtr   pVisual;
+    for (i = 0, pVisual = pScreen->visuals;
+         i < pScreen->numVisuals;
+         i++, pVisual++)
+    {
+        if (pVisual->vid == visual)
+            return pVisual;
+    }
+    return 0;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return FALSE;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->type == PictTypeIndexed && !format->index.pColormap)
+	{
+	    if (format->index.vid == pScreen->rootVisual)
+		format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+								       RT_COLORMAP);
+	    else
+	    {
+                VisualPtr   pVisual;
+
+                pVisual = PictureFindVisual (pScreen, format->index.vid);
+		if (CreateColormap (FakeClientID (0), pScreen,
+				    pVisual,
+				    &format->index.pColormap, AllocNone,
+				    0) != Success)
+		{
+		    return FALSE;
+		}
+	    }
+	    if (!(*ps->InitIndexed) (pScreen, format))
+		return FALSE;
+	}
+	format++;
+    }
+    return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+    int	    s;
+
+    for (s = 0; s < screenInfo.numScreens; s++)
+    {
+	if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+	    return FALSE;
+	(void) AnimCurInit (screenInfo.screens[s]);
+    }
+
+    return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return FALSE;
+    ps->subpixel = subpixel;
+    return TRUE;
+    
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return SubPixelUnknown;
+    return ps->subpixel;
+}
+    
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+    int			type;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    switch (pVisual->class) {
+    case StaticGray:
+    case GrayScale:
+    case StaticColor:
+    case PseudoColor:
+	type = PictTypeIndexed;
+	break;
+    case TrueColor:
+    case DirectColor:
+	type = PictTypeDirect;
+	break;
+    default:
+	return 0;
+    }
+    while (nformat--)
+    {
+	if (format->depth == depth && format->type == type)
+	{
+	    if (type == PictTypeIndexed)
+	    {
+		if (format->index.vid == pVisual->vid)
+		    return format;
+	    }
+	    else
+	    {
+		if (format->direct.redMask << format->direct.red == 
+		    pVisual->redMask &&
+		    format->direct.greenMask << format->direct.green == 
+		    pVisual->greenMask &&
+		    format->direct.blueMask << format->direct.blue == 
+		    pVisual->blueMask)
+		{
+		    return format;
+		}
+	    }
+	}
+	format++;
+    }
+    return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->depth == depth && format->format == (f & 0xffffff))
+	    return format;
+	format++;
+    }
+    return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+    if ( strcmp (name, "default" ) == 0)
+	return PictureCmapPolicyDefault;
+    else if ( strcmp (name, "mono" ) == 0)
+	return PictureCmapPolicyMono;
+    else if ( strcmp (name, "gray" ) == 0)
+	return PictureCmapPolicyGray;
+    else if ( strcmp (name, "color" ) == 0)
+	return PictureCmapPolicyColor;
+    else if ( strcmp (name, "all" ) == 0)
+	return PictureCmapPolicyAll;
+    else
+	return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+    PictureScreenPtr	ps;
+    int			n;
+    CARD32		type, a, r, g, b;
+    
+    if (PictureGeneration != serverGeneration)
+    {
+	PictureType = CreateNewResourceType (FreePicture);
+	if (!PictureType)
+	    return FALSE;
+	PictFormatType = CreateNewResourceType (FreePictFormat);
+	if (!PictFormatType)
+	    return FALSE;
+	GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+	if (!GlyphSetType)
+	    return FALSE;
+	PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+	if (PictureScreenPrivateIndex < 0)
+	    return FALSE;
+	PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+	PictureGeneration = serverGeneration;
+#ifdef XResExtension
+	RegisterResourceName (PictureType, "PICTURE");
+	RegisterResourceName (PictFormatType, "PICTFORMAT");
+	RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+    }
+    if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+	return FALSE;
+    
+    if (!formats)
+    {
+	formats = PictureCreateDefaultFormats (pScreen, &nformats);
+	if (!formats)
+	    return FALSE;
+    }
+    for (n = 0; n < nformats; n++)
+    {
+	if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+	{
+	    xfree (formats);
+	    return FALSE;
+	}
+	if (formats[n].type == PictTypeIndexed)
+	{
+            VisualPtr   pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+	    if ((pVisual->class | DynamicClass) == PseudoColor)
+		type = PICT_TYPE_COLOR;
+	    else
+		type = PICT_TYPE_GRAY;
+	    a = r = g = b = 0;
+	}
+	else
+	{
+	    if ((formats[n].direct.redMask|
+		 formats[n].direct.blueMask|
+		 formats[n].direct.greenMask) == 0)
+		type = PICT_TYPE_A;
+	    else if (formats[n].direct.red > formats[n].direct.blue)
+		type = PICT_TYPE_ARGB;
+	    else
+		type = PICT_TYPE_ABGR;
+	    a = Ones (formats[n].direct.alphaMask);
+	    r = Ones (formats[n].direct.redMask);
+	    g = Ones (formats[n].direct.greenMask);
+	    b = Ones (formats[n].direct.blueMask);
+	}
+	formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+    }
+    ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+    if (!ps)
+    {
+	xfree (formats);
+	return FALSE;
+    }
+    SetPictureScreen(pScreen, ps);
+    if (!GlyphInit (pScreen))
+    {
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    ps->totalPictureSize = sizeof (PictureRec);
+    ps->PicturePrivateSizes = 0;
+    ps->PicturePrivateLen = 0;
+    
+    ps->formats = formats;
+    ps->fallback = formats;
+    ps->nformats = nformats;
+    
+    ps->filters = 0;
+    ps->nfilters = 0;
+    ps->filterAliases = 0;
+    ps->nfilterAliases = 0;
+
+    ps->subpixel = SubPixelUnknown;
+
+    ps->CloseScreen = pScreen->CloseScreen;
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    pScreen->CloseScreen = PictureCloseScreen;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (!PictureSetDefaultFilters (pScreen))
+    {
+	PictureResetFilters (pScreen);
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr    pPicture)
+{
+    pPicture->refcnt = 1;
+    pPicture->repeat = 0;
+    pPicture->graphicsExposures = FALSE;
+    pPicture->subWindowMode = ClipByChildren;
+    pPicture->polyEdge = PolyEdgeSharp;
+    pPicture->polyMode = PolyModePrecise;
+    pPicture->freeCompClip = FALSE;
+    pPicture->clientClipType = CT_NONE;
+    pPicture->componentAlpha = FALSE;
+    pPicture->repeatType = RepeatNone;
+
+    pPicture->alphaMap = 0;
+    pPicture->alphaOrigin.x = 0;
+    pPicture->alphaOrigin.y = 0;
+
+    pPicture->clipOrigin.x = 0;
+    pPicture->clipOrigin.y = 0;
+    pPicture->clientClip = 0;
+
+    pPicture->transform = 0;
+
+    pPicture->dither = None;
+    pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+    pPicture->filter_params = 0;
+    pPicture->filter_nparams = 0;
+
+    pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+    pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+    pPicture->pSourcePict = 0;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture;
+    char		*ptr;
+    DevUnion		*ppriv;
+    unsigned int    	*sizes;
+    unsigned int    	size;
+    int			i;
+
+    pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+    if (!pPicture)
+	return 0;
+    ppriv = (DevUnion *)(pPicture + 1);
+    pPicture->devPrivates = ppriv;
+    sizes = ps->PicturePrivateSizes;
+    ptr = (char *)(ppriv + ps->PicturePrivateLen);
+    for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return pPicture;
+}
+
+/*
+ * Let picture always point to the virtual pixmap.
+ * For sure this is not the best way to deal with
+ * the virtual frame-buffer.
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		vmask,
+	       XID		*vlist,
+	       ClientPtr	client,
+	       int		*error)
+{
+    PicturePtr		pPicture;
+    PictureScreenPtr	ps = GetPictureScreen(pDrawable->pScreen);
+
+    pPicture = AllocatePicture (pDrawable->pScreen);
+    if (!pPicture)
+    {
+	*error = BadAlloc;
+	return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pDrawable = pDrawable;
+    pPicture->pFormat = pFormat;
+    pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+    if (pDrawable->type == DRAWABLE_PIXMAP)
+    {
+        #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+        pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
+
+        #endif
+
+	++((PixmapPtr)pDrawable)->refcnt;
+	pPicture->pNext = 0;
+    }
+    else
+    {
+	pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+	SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+    }
+
+    SetPictureToDefaults (pPicture);
+    
+    if (vmask)
+	*error = ChangePicture (pPicture, vmask, vlist, 0, client);
+    else
+	*error = Success;
+    if (*error == Success)
+	*error = (*ps->CreatePicture) (pPicture);
+    if (*error != Success)
+    {
+	FreePicture (pPicture, (XID) 0);
+	pPicture = 0;
+    }
+    return pPicture;
+}
+
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+    return
+        (c.alpha >> 8 << 24) |
+        (c.red >> 8 << 16) |
+        (c.green & 0xff00) |
+        (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+    unsigned int a = x >> 24;
+    unsigned int t = (x & 0xff00ff) * a;
+    t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+    t &= 0xff00ff;
+
+    x = ((x >> 8) & 0xff) * a;
+    x = (x + ((x >> 8) & 0xff) + 0x80);
+    x &= 0xff00;
+    x |= t | (a << 24);
+    return x;
+}
+
+static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+                                          unsigned int y, unsigned int b)
+{
+    CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+    t >>= 8;
+    t &= 0xff00ff;
+
+    x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+    x &= 0xff00ff00;
+    x |= t;
+    return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+    int begin_pos, end_pos;
+    xFixed incr, dpos;
+    int pos, current_stop;
+    PictGradientStopPtr stops = pGradient->linear.stops;
+    int nstops = pGradient->linear.nstops;
+
+    /* The position where the gradient begins and ends */
+    begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+    end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+    pos = 0; /* The position in the color table. */
+
+    /* Up to first point */
+    while (pos <= begin_pos) {
+        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+        ++pos;
+    }
+
+    incr =  (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
+    dpos = incr * pos; /* The position in terms of 0-1. */
+
+    current_stop = 0; /* We always interpolate between current and current + 1. */
+
+    /* Gradient area */
+    while (pos < end_pos) {
+        unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+        unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+        int dist = (int)(256*(dpos - stops[current_stop].x)
+                         / (stops[current_stop+1].x - stops[current_stop].x));
+        int idist = 256 - dist;
+
+        pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+        ++pos;
+        dpos += incr;
+
+        if (dpos > stops[current_stop + 1].x)
+            ++current_stop;
+    }
+
+    /* After last point */
+    while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+        ++pos;
+    }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+                         xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+    int i;
+    xFixed dpos;
+
+    if (stopCount <= 0) {
+        *error = BadValue;
+        return;
+    }
+
+    dpos = -1;
+    for (i = 0; i < stopCount; ++i) {
+        if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+            *error = BadValue;
+            return;
+        }
+        dpos = stopPoints[i];
+    }
+
+    pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
+    if (!pGradient->linear.stops) {
+        *error = BadAlloc;
+        return;
+    }
+
+    pGradient->linear.nstops = stopCount;
+
+    for (i = 0; i < stopCount; ++i) {
+        pGradient->linear.stops[i].x = stopPoints[i];
+        pGradient->linear.stops[i].color = stopColors[i];
+    }
+    initGradientColorTable(pGradient, error);
+}
+
+static PicturePtr createSourcePicture(void)
+{
+    PicturePtr pPicture;
+    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+    pPicture->pDrawable = 0;
+    pPicture->pFormat = 0;
+    pPicture->pNext = 0;
+
+    SetPictureToDefaults(pPicture);
+    return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+    PicturePtr pPicture;
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+    pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+    pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+    return pPicture;
+}
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+                             int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+    if (p1->x == p2->x && p1->y == p2->y) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+
+    pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+    pPicture->pSourcePict->linear.p1 = *p1;
+    pPicture->pSourcePict->linear.p2 = *p2;
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+                             xFixed innerRadius, xFixed outerRadius,
+                             int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+    PictRadialGradient *radial;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+    {
+        double dx = (double)(inner->x - outer->x);
+        double dy = (double)(inner->y - outer->y);
+        if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+            *error = BadValue;
+            return 0;
+        }
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+    radial = &pPicture->pSourcePict->radial;
+
+    radial->type = SourcePictTypeRadial;
+    {
+        double x = (double)innerRadius / (double)outerRadius;
+        radial->dx = (outer->x - inner->x);
+        radial->dy = (outer->y - inner->y);
+        radial->fx = (inner->x) - x*radial->dx;
+        radial->fy = (inner->y) - x*radial->dy;
+        radial->m = 1./(1+x);
+        radial->b = -x*radial->m;
+        radial->dx /= 65536.;
+        radial->dy /= 65536.;
+        radial->fx /= 65536.;
+        radial->fy /= 65536.;
+        x = outerRadius/65536.;
+        radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+    }
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+                              int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+
+    pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+    pPicture->pSourcePict->conical.center = *center;
+    pPicture->pSourcePict->conical.angle = angle;
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client)
+{
+    ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+    PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
+    BITS32		index2;
+    int			error = 0;
+    BITS32		maskQ;
+    
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    maskQ = vmask;
+    while (vmask && !error)
+    {
+	index2 = (BITS32) lowbit (vmask);
+	vmask &= ~index2;
+	pPicture->stateChanges |= index2;
+	switch (index2)
+	{
+	case CPRepeat:
+	    {
+		unsigned int	newr;
+		newr = NEXT_VAL(unsigned int);
+		if (newr <= RepeatReflect)
+		{
+		    pPicture->repeat = (newr != RepeatNone);
+		    pPicture->repeatType = newr;
+		}
+		else
+		{
+		    client->errorValue = newr;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPAlphaMap:
+	    {
+		PicturePtr  pAlpha;
+		
+		if (vlist)
+		{
+		    Picture	pid = NEXT_VAL(Picture);
+
+		    if (pid == None)
+			pAlpha = 0;
+		    else
+		    {
+			pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+								     pid, 
+								     PictureType, 
+								     SecurityWriteAccess|SecurityReadAccess);
+			if (!pAlpha)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+			if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+			{
+			    client->errorValue = pid;
+			    error = BadMatch;
+			    break;
+			}
+		    }
+		}
+		else
+		    pAlpha = NEXT_PTR(PicturePtr);
+		if (!error)
+		{
+		    if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+			pAlpha->refcnt++;
+		    if (pPicture->alphaMap)
+			FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+		    pPicture->alphaMap = pAlpha;
+		}
+	    }
+	    break;
+	case CPAlphaXOrigin:
+	    pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPAlphaYOrigin:
+	    pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipXOrigin:
+	    pPicture->clipOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPClipYOrigin:
+	    pPicture->clipOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipMask:
+	    {
+		Pixmap	    pid;
+		PixmapPtr   pPixmap;
+		int	    clipType;
+                if (!pScreen)
+                    return BadDrawable;
+
+		if (vlist)
+		{
+		    pid = NEXT_VAL(Pixmap);
+		    if (pid == None)
+		    {
+			clipType = CT_NONE;
+			pPixmap = NullPixmap;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+								    pid, 
+								    RT_PIXMAP,
+								    SecurityReadAccess);
+			if (!pPixmap)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+		    }
+		}
+		else
+		{
+		    pPixmap = NEXT_PTR(PixmapPtr);
+		    if (pPixmap)
+			clipType = CT_PIXMAP;
+		    else
+			clipType = CT_NONE;
+		}
+
+		if (pPixmap)
+		{
+		    if ((pPixmap->drawable.depth != 1) ||
+			(pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			break;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap->refcnt++;
+		    }
+		}
+
+                #ifdef DEBUG
+                fprintf(stderr, "ChangePicture: Going to call ChangePictureClip with clipType [%d] pPixmap [%p].\n",
+                            clipType, (void *) pPixmap);
+                #endif
+
+		error = (*ps->ChangePictureClip)(pPicture, clipType,
+						 (pointer)pPixmap, 0);
+		break;
+	    }
+	case CPGraphicsExposure:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe <= xTrue)
+		    pPicture->graphicsExposures = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPSubwindowMode:
+	    {
+		unsigned int	news;
+		news = NEXT_VAL(unsigned int);
+		if (news == ClipByChildren || news == IncludeInferiors)
+		    pPicture->subWindowMode = news;
+		else
+		{
+		    client->errorValue = news;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyEdge:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+		    pPicture->polyEdge = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyMode:
+	    {
+		unsigned int	newm;
+		newm = NEXT_VAL(unsigned int);
+		if (newm == PolyModePrecise || newm == PolyModeImprecise)
+		    pPicture->polyMode = newm;
+		else
+		{
+		    client->errorValue = newm;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPDither:
+	    pPicture->dither = NEXT_VAL(Atom);
+	    break;
+	case CPComponentAlpha:
+	    {
+		unsigned int	newca;
+
+		newca = NEXT_VAL (unsigned int);
+		if (newca <= xTrue)
+		    pPicture->componentAlpha = newca;
+		else
+		{
+		    client->errorValue = newca;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	default:
+	    client->errorValue = maskQ;
+	    error = BadValue;
+	    break;
+	}
+    }
+    if (ps)
+        (*ps->ChangePicture) (pPicture, maskQ);
+    return error;
+}
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    RegionPtr		clientClip;
+    int			result;
+
+    clientClip = RECTS_TO_REGION(pScreen,
+				 nRect, rects, CT_UNSORTED);
+    if (!clientClip)
+	return BadAlloc;
+    result =(*ps->ChangePictureClip) (pPicture, CT_REGION, 
+				      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+	pPicture->clipOrigin.x = xOrigin;
+	pPicture->clipOrigin.y = yOrigin;
+	pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+	pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+int
+SetPictureClipRegion (PicturePtr    pPicture,
+                      int           xOrigin,
+                      int           yOrigin,
+                      RegionPtr     pRegion)
+{
+    ScreenPtr           pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    RegionPtr           clientClip;
+    int                 result;
+    int                 type;
+
+    if (pRegion)
+    {
+        type = CT_REGION;
+        clientClip = REGION_CREATE (pScreen,
+                                    REGION_EXTENTS(pScreen, pRegion),
+                                    REGION_NUM_RECTS(pRegion));
+        if (!clientClip)
+            return BadAlloc;
+        if (!REGION_COPY (pSCreen, clientClip, pRegion))
+        {
+            REGION_DESTROY (pScreen, clientClip);
+            return BadAlloc;
+        }
+    }
+    else
+    {
+        type = CT_NONE;
+        clientClip = 0;
+    }
+
+    result =(*ps->ChangePictureClip) (pPicture, type,
+                                      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+        pPicture->clipOrigin.x = xOrigin;
+        pPicture->clipOrigin.y = yOrigin;
+        pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+        pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform)
+{
+    static const PictTransform	identity = { {
+	{ xFixed1, 0x00000, 0x00000 },
+	{ 0x00000, xFixed1, 0x00000 },
+	{ 0x00000, 0x00000, xFixed1 },
+    } };
+
+    if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+	transform = 0;
+    
+    if (transform)
+    {
+	if (!pPicture->transform)
+	{
+	    pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+	    if (!pPicture->transform)
+		return BadAlloc;
+	}
+	*pPicture->transform = *transform;
+    }
+    else
+    {
+	if (pPicture->transform)
+	{
+	    xfree (pPicture->transform);
+	    pPicture->transform = 0;
+	}
+    }
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+    return Success;
+}
+
+void
+CopyPicture (PicturePtr	pSrc,
+	     Mask	mask,
+	     PicturePtr	pDst)
+{
+    PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+    Mask origMask = mask;
+
+    pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    pDst->stateChanges |= mask;
+
+    while (mask) {
+	Mask bit = lowbit(mask);
+
+	switch (bit)
+	{
+	case CPRepeat:
+	    pDst->repeat = pSrc->repeat;
+	    pDst->repeatType = pSrc->repeatType;
+	    break;
+	case CPAlphaMap:
+	    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+		pSrc->alphaMap->refcnt++;
+	    if (pDst->alphaMap)
+		FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+	    pDst->alphaMap = pSrc->alphaMap;
+	    break;
+	case CPAlphaXOrigin:
+	    pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+	    break;
+	case CPAlphaYOrigin:
+	    pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+	    break;
+	case CPClipXOrigin:
+	    pDst->clipOrigin.x = pSrc->clipOrigin.x;
+	    break;
+	case CPClipYOrigin:
+	    pDst->clipOrigin.y = pSrc->clipOrigin.y;
+	    break;
+	case CPClipMask:
+	    switch (pSrc->clientClipType) {
+	    case CT_NONE:
+		(*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+		break;
+	    case CT_REGION:
+		if (!pSrc->clientClip) {
+		    (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+		} else {
+		    RegionPtr clientClip;
+		    RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+		    clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+			REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+			REGION_NUM_RECTS(srcClientClip));
+		    (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+		}
+		break;
+	    default:
+		/* XXX: CT_PIXMAP unimplemented */
+		break;
+	    }
+	    break;
+	case CPGraphicsExposure:
+	    pDst->graphicsExposures = pSrc->graphicsExposures;
+	    break;
+	case CPPolyEdge:
+	    pDst->polyEdge = pSrc->polyEdge;
+	    break;
+	case CPPolyMode:
+	    pDst->polyMode = pSrc->polyMode;
+	    break;
+	case CPDither:
+	    pDst->dither = pSrc->dither;
+	    break;
+	case CPComponentAlpha:
+	    pDst->componentAlpha = pSrc->componentAlpha;
+	    break;
+	}
+	mask &= ~bit;
+    }
+
+    (*ps->ChangePicture)(pDst, origMask);
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+    if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+    {
+	PictureScreenPtr    ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+	(*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+	pPicture->stateChanges = 0;
+	pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+    }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+    ValidateOnePicture (pPicture);
+    if (pPicture->alphaMap)
+	ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer	value,
+	     XID	pid)
+{
+    PicturePtr	pPicture = (PicturePtr) value;
+
+    if (--pPicture->refcnt == 0)
+    {
+	if (pPicture->transform)
+	    xfree (pPicture->transform);
+        if (!pPicture->pDrawable) {
+            if (pPicture->pSourcePict) {
+                if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+                    xfree(pPicture->pSourcePict->linear.stops);
+                xfree(pPicture->pSourcePict);
+            }
+        } else {
+            ScreenPtr	    pScreen = pPicture->pDrawable->pScreen;
+            PictureScreenPtr    ps = GetPictureScreen(pScreen);
+	
+            if (pPicture->alphaMap)
+                FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+            (*ps->DestroyPicture) (pPicture);
+            (*ps->DestroyPictureClip) (pPicture);
+            if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+            {
+                WindowPtr	pWindow = (WindowPtr) pPicture->pDrawable;
+                PicturePtr	*pPrev;
+
+                for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+                     *pPrev;
+                     pPrev = &(*pPrev)->pNext)
+                {
+                    if (*pPrev == pPicture)
+                    {
+                        *pPrev = pPicture->pNext;
+                        break;
+                    }
+                }
+            }
+            else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+            {
+                (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+            }
+        }
+	xfree (pPicture);
+    }
+    return Success;
+}
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid)
+{
+    return Success;
+}
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    if (pMask)
+	ValidatePicture (pMask);
+    ValidatePicture (pDst);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+}
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+
+    #ifdef TEST
+    fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with "
+		"source at [%p] and destination at [%p].\n",
+		    (void *) pSrc, (void *) pDst);
+    #endif
+
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pDst);
+    (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+AddTraps (PicturePtr	pPicture,
+	  INT16		xOff,
+	  INT16		yOff,
+	  int		ntrap,
+	  xTrap		*traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+    
+    ValidatePicture (pPicture);
+    (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
+
+#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+                         PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] *
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    *vector = result;
+    return TRUE;
+}
+
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] * 
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    for (j = 0; j < 2; j++)
+    {
+	partial = (xFixed_48_16) result.vector[j] << 16;
+	v = partial / result.vector[2];
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	vector->vector[j] = (xFixed) v;
+    }
+    vector->vector[2] = xFixed1;
+    return TRUE;
+}
+
+#ifndef True
+# define True 1
+#endif
+
+#ifndef False
+# define False 0
+#endif
+
+void nxagentReconnectPictFormat(void*, XID, void*);
+
+Bool nxagentReconnectAllPictFormat(void *p)
+{
+  PictFormatPtr formats_old, formats;
+  int nformats, nformats_old;
+  VisualPtr pVisual;
+  Bool success = True;
+  Bool matched;
+  int i, n;
+  CARD32 type, a, r, g, b;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+  fprintf(stderr, "nxagentReconnectAllPictFormat\n");
+  #endif
+
+  formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
+  nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
+
+  /*
+   * TODO: We could copy PictureCreateDefaultFormats,
+   *       in order not to waste ID with FakeClientID().
+   */
+  formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
+
+  if (!formats)
+    return False;
+
+  for (n = 0; n < nformats; n++)
+  {
+    if (formats[n].type == PictTypeIndexed)
+    {
+      pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid);
+
+      if ((pVisual->class | DynamicClass) == PseudoColor)
+        type = PICT_TYPE_COLOR;
+      else
+        type = PICT_TYPE_GRAY;
+      a = r = g = b = 0;
+    }
+    else
+    {
+      if ((formats[n].direct.redMask|
+           formats[n].direct.blueMask|
+           formats[n].direct.greenMask) == 0)
+        type = PICT_TYPE_A;
+      else if (formats[n].direct.red > formats[n].direct.blue)
+        type = PICT_TYPE_ARGB;
+      else
+        type = PICT_TYPE_ABGR;
+      a = Ones (formats[n].direct.alphaMask);
+      r = Ones (formats[n].direct.redMask);
+      g = Ones (formats[n].direct.greenMask);
+      b = Ones (formats[n].direct.blueMask);
+    }
+    formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+  }
+
+  for (n = 0; n < nformats_old; n++)
+  {
+    for (i = 0, matched = False; (!matched) && (i < nformats); i++)
+    {
+      if (formats_old[n].format == formats[i].format &&
+          formats_old[n].type == formats[i].type &&
+          formats_old[n].direct.red == formats[i].direct.red &&
+          formats_old[n].direct.green == formats[i].direct.green &&
+          formats_old[n].direct.blue == formats[i].direct.blue &&
+          formats_old[n].direct.redMask == formats[i].direct.redMask &&
+          formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
+          formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
+          formats_old[n].direct.alpha == formats[i].direct.alpha &&
+          formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
+      {
+       /*
+        * Regard depth 16 and 15 as were the same, if all other values match.
+        */
+
+        if ((formats_old[n].depth == formats[i].depth) ||
+               ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
+                    (formats[i].depth == 15 || formats[i].depth == 16)))
+        {
+          matched = True;
+        }
+      }
+    }
+
+    if (!matched)
+    {
+      return False;
+    }
+  }
+
+  xfree(formats);
+
+  /* TODO: Perhaps do i have to do PictureFinishInit ?. */
+  /* TODO: We have to check for new Render protocol version. */
+
+  for (i = 0; (i < MAXCLIENTS) && (success); i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
+    }
+  }
+
+  return success;
+}
+
+/*
+ * It seem we don't have nothing
+ * to do for reconnect PictureFormat.
+ */
+
+void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
+{
+  PictFormatPtr pFormat;
+  Bool *pBool;
+
+  pFormat = (PictFormatPtr)p0;
+  pBool = (Bool*)p2;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+  fprintf(stderr, "nxagentReconnectPictFormat.\n");
+  #endif
+}
+
+/*
+ * The set of picture formats may change considerably
+ * between different X servers. This poses a problem
+ * while migrating NX sessions, because a requisite to
+ * successfully reconnect the session is that all pic-
+ * ture formats have to be available on the new X server.
+ * To reduce such problems, we use a limited set of
+ * pictures available on the most X servers.
+ */
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats)
+{
+  DepthPtr  pDepth;
+  VisualPtr pVisual;
+
+  CARD32 format;
+  CARD8 depth;
+
+  int r, g, b;
+  int bpp;
+  int d;
+  int v;
+
+
+  formats[*nformats].format = PICT_a1;
+  formats[*nformats].depth = 1;
+  *nformats += 1;
+  formats[*nformats].format = PICT_a4;
+  formats[*nformats].depth = 4;
+  *nformats += 1;
+  formats[*nformats].format = PICT_a8;
+  formats[*nformats].depth = 8;
+  *nformats += 1;
+  formats[*nformats].format = PICT_a8r8g8b8;
+  formats[*nformats].depth = 32;
+  *nformats += 1;
+
+  /*
+   * This format should be required by the
+   * protocol, but it's not used by Xgl.
+   *
+   * formats[*nformats].format = PICT_x8r8g8b8;
+   * formats[*nformats].depth = 32;
+   * *nformats += 1;
+   */
+
+  /* now look through the depths and visuals adding other formats */
+  for (v = 0; v < pScreen->numVisuals; v++)
+  {
+    pVisual = &pScreen->visuals[v];
+    depth = visualDepth (pScreen, pVisual);
+    if (!depth)
+      continue;
+
+    bpp = BitsPerPixel (depth);
+
+    switch (pVisual->class)
+    {
+      case DirectColor:
+      case TrueColor:
+        r = Ones (pVisual->redMask);
+        g = Ones (pVisual->greenMask);
+        b = Ones (pVisual->blueMask);
+
+        if (pVisual->offsetBlue == 0 &&
+            pVisual->offsetGreen == b &&
+            pVisual->offsetRed == b + g)
+        {
+    	  format = PICT_FORMAT(bpp, PICT_TYPE_ARGB, 0, r, g, b);
+    	  *nformats = addFormat (formats, *nformats, format, depth);
+        }
+        break;
+      case StaticColor:
+      case PseudoColor:
+      case StaticGray:
+      case GrayScale:
+        break;
+    }
+  }
+
+  for (d = 0; d < pScreen -> numDepths; d++)
+  {
+    pDepth = &pScreen -> allowedDepths[d];
+    bpp = BitsPerPixel(pDepth -> depth);
+
+    switch (bpp) {
+    case 16:
+      if (pDepth->depth == 15)
+      {
+        *nformats = addFormat (formats, *nformats,
+    			      PICT_x1r5g5b5, pDepth->depth);
+      }
+
+      if (pDepth->depth == 16) 
+      {
+        *nformats = addFormat (formats, *nformats,
+    	                      PICT_r5g6b5, pDepth->depth);
+      }
+      break;
+    case 24:
+      if (pDepth->depth == 24)
+      {
+        *nformats = addFormat (formats, *nformats,
+    	                      PICT_r8g8b8, pDepth->depth);
+      }
+      break;
+    case 32:
+      if (pDepth->depth == 24)
+      {
+	*nformats = addFormat (formats, *nformats,
+			      PICT_x8r8g8b8, pDepth->depth);
+      }
+      break;
+    }
+  }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
new file mode 100644
index 000000000..5d6f71475
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -0,0 +1,2220 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "NXpicturestr.h"
+
+#include "Screen.h"
+#include "Pixmaps.h"
+#include "Drawable.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+void *nxagentVisualFromID(ScreenPtr pScreen, VisualID visual);
+
+void *nxagentMatchingFormats(PictFormatPtr pForm);
+
+int		PictureScreenPrivateIndex = -1;
+int		PictureWindowPrivateIndex;
+int		PictureGeneration;
+RESTYPE		PictureType;
+RESTYPE		PictFormatType;
+RESTYPE		GlyphSetType;
+int		PictureCmapPolicy = PictureCmapPolicyDefault;
+
+typedef struct _formatInit {
+    CARD32  format;
+    CARD8   depth;
+} FormatInitRec, *FormatInitPtr;
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats);
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+    picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+    return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    unsigned int	oldamount;
+
+    /* Round up sizes for proper alignment */
+    amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+    if (index2 >= ps->PicturePrivateLen)
+    {
+	unsigned int *nsizes;
+
+	nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+					  (index2 + 1) * sizeof(unsigned int));
+	if (!nsizes)
+	    return FALSE;
+	while (ps->PicturePrivateLen <= index2)
+	{
+	    nsizes[ps->PicturePrivateLen++] = 0;
+	    ps->totalPictureSize += sizeof(DevUnion);
+	}
+	ps->PicturePrivateSizes = nsizes;
+    }
+    oldamount = ps->PicturePrivateSizes[index2];
+    if (amount > oldamount)
+    {
+	ps->PicturePrivateSizes[index2] = amount;
+	ps->totalPictureSize += (amount - oldamount);
+    }
+
+    return TRUE;
+}
+
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+    ScreenPtr		pScreen = pWindow->drawable.pScreen;
+    PicturePtr		pPicture;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool		ret;
+
+    while ((pPicture = GetPictureWindow(pWindow)))
+    {
+	SetPictureWindow(pWindow, pPicture->pNext);
+	if (pPicture->id)
+	    FreeResource (pPicture->id, PictureType);
+	FreePicture ((pointer) pPicture, pPicture->id);
+    }
+    pScreen->DestroyWindow = ps->DestroyWindow;
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool                ret;
+    int			n;
+
+    pScreen->CloseScreen = ps->CloseScreen;
+    ret = (*pScreen->CloseScreen) (index, pScreen);
+    PictureResetFilters (pScreen);
+    for (n = 0; n < ps->nformats; n++)
+	if (ps->formats[n].type == PictTypeIndexed)
+	    (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+    SetPictureScreen(pScreen, 0);
+    if (ps->PicturePrivateSizes)
+	xfree (ps->PicturePrivateSizes);
+    xfree (ps->formats);
+    xfree (ps);
+    return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+    ScreenPtr		pScreen = pColormap->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    pScreen->StoreColors = ps->StoreColors;
+    (*pScreen->StoreColors) (pColormap, ndef, pdef);
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+    {
+	PictFormatPtr	format = ps->formats;
+	int		nformats = ps->nformats;
+
+	while (nformats--)
+	{
+	    if (format->type == PictTypeIndexed &&
+		format->index.pColormap == pColormap)
+	    {
+		(*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+		break;
+	    }
+	    format++;
+	}
+    }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    int		d, v;
+    DepthPtr	pDepth;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	for (v = 0; v < pDepth->numVids; v++)
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+    }
+    return 0;
+}
+
+static int
+addFormat (FormatInitRec    formats[256],
+	   int		    nformat,
+	   CARD32	    format,
+	   CARD8	    depth)
+{
+    int	n;
+
+    for (n = 0; n < nformat; n++)
+	if (formats[n].format == format && formats[n].depth == depth)
+	    return nformat;
+    formats[nformat].format = format;
+    formats[nformat].depth = depth;
+
+    #ifdef DEBUG
+    fprintf(stderr, "addFormat: Added format [%lu] depth [%d].\n", format, depth);
+    #endif
+
+    return ++nformat;
+}
+
+#define Mask(n)	((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+    int             nformats, f;
+    PictFormatPtr   pFormats;
+    FormatInitRec   formats[1024];
+    CARD32	    format;
+
+#ifndef NXAGENT_SERVER
+
+    CARD8	    depth;
+    VisualPtr	    pVisual;
+    int		    v;
+    int		    bpp;
+    int		    type;
+    int		    r, g, b;
+    int		    d;
+    DepthPtr	    pDepth;
+
+#endif
+
+    nformats = 0;
+
+#ifdef NXAGENT_SERVER
+
+    nxagentPictureCreateDefaultFormats(pScreen, formats, &nformats);
+
+#else
+
+    /* formats required by protocol */
+    formats[nformats].format = PICT_a1;
+    formats[nformats].depth = 1;
+    nformats++;
+    formats[nformats].format = PICT_a8;
+    formats[nformats].depth = 8;
+    nformats++;
+    formats[nformats].format = PICT_a4;
+    formats[nformats].depth = 4;
+    nformats++;
+    formats[nformats].format = PICT_a8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+    formats[nformats].format = PICT_x8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+
+    /* now look through the depths and visuals adding other formats */
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = &pScreen->visuals[v];
+	depth = visualDepth (pScreen, pVisual);
+	if (!depth)
+	    continue;
+    	bpp = BitsPerPixel (depth);
+
+	switch (pVisual->class) {
+	case DirectColor:
+	case TrueColor:
+	    r = Ones (pVisual->redMask);
+	    g = Ones (pVisual->greenMask);
+	    b = Ones (pVisual->blueMask);
+	    type = PICT_TYPE_OTHER;
+	    /*
+	     * Current rendering code supports only two direct formats,
+	     * fields must be packed together at the bottom of the pixel
+	     * and must be either RGB or BGR
+	     */
+	    if (pVisual->offsetBlue == 0 &&
+		pVisual->offsetGreen == b &&
+		pVisual->offsetRed == b + g)
+	    {
+		type = PICT_TYPE_ARGB;
+	    }
+	    else if (pVisual->offsetRed == 0 &&
+		     pVisual->offsetGreen == r && 
+		     pVisual->offsetBlue == r + g)
+	    {
+		type = PICT_TYPE_ABGR;
+	    }
+	    if (type != PICT_TYPE_OTHER)
+	    {
+		format = PICT_FORMAT(bpp, type, 0, r, g, b);
+		nformats = addFormat (formats, nformats, format, depth);
+	    }
+	    break;
+	case StaticColor:
+	case PseudoColor:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	case StaticGray:
+	case GrayScale:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	}
+    }
+
+    /*
+     * Walk supported depths and add useful Direct formats
+     */
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	bpp = BitsPerPixel (pDepth->depth);
+	format = 0;
+
+	switch (bpp) {
+	case 16:
+	    /* depth 12 formats */
+	     if (pDepth->depth >= 12)
+	     {
+	        nformats = addFormat (formats, nformats,
+	      		      PICT_x4r4g4b4, pDepth->depth);
+	        nformats = addFormat (formats, nformats,
+	      		      PICT_x4b4g4r4, pDepth->depth);
+	     }
+
+	    /* depth 15 formats */
+	    if (pDepth->depth >= 15)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x1b5g5r5, pDepth->depth);
+	    }
+	    /* depth 16 formats */
+	    if (pDepth->depth >= 16) 
+	    {
+	        nformats = addFormat (formats, nformats,
+	        		      PICT_a1r5g5b5, pDepth->depth);
+	        nformats = addFormat (formats, nformats,
+	       	        	      PICT_a1b5g5r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_r5g6b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b5g6r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4r4g4b4, pDepth->depth);
+	        nformats = addFormat (formats, nformats,
+	        		      PICT_a4b4g4r4, pDepth->depth);
+	    }
+	    break;
+	case 24:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b8g8r8, pDepth->depth);
+	    }
+	    break;
+	case 32:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x8r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x8b8g8r8, pDepth->depth);
+	    }
+	    break;
+	}
+    }
+
+#endif
+
+    pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+    if (!pFormats)
+	return 0;
+    memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+    for (f = 0; f < nformats; f++)
+    {
+        pFormats[f].id = FakeClientID (0);
+        pFormats[f].depth = formats[f].depth;
+        format = formats[f].format;
+        pFormats[f].format = format;
+	switch (PICT_FORMAT_TYPE(format)) {
+	case PICT_TYPE_ARGB:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = (PICT_FORMAT_G(format) + 
+				      PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_B(format);
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = 0;
+	    break;
+
+	case PICT_TYPE_ABGR:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = (PICT_FORMAT_G(format) + 
+				       PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_R(format);
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = 0;
+	    break;
+
+	case PICT_TYPE_A:
+	    pFormats[f].type = PictTypeDirect;
+
+	    pFormats[f].direct.alpha = 0;
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+	    /* remaining fields already set to zero */
+	    break;
+	    
+	case PICT_TYPE_COLOR:
+	case PICT_TYPE_GRAY:
+	    pFormats[f].type = PictTypeIndexed;
+	    pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+	    break;
+	}
+
+#ifdef NXAGENT_SERVER
+        if (nxagentMatchingFormats(&pFormats[f]) != NULL)
+        {
+          #ifdef DEBUG
+          fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+                      "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] matches.\n",
+                          pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+                              pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+                                  pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+          #endif
+        }
+        else
+        {
+          #ifdef DEBUG
+          fprintf(stderr, "PictureCreateDefaultFormats: Format with type [%d] depth [%d] rgb [%d,%d,%d] "
+                      "mask rgb [%d,%d,%d] alpha [%d] alpha mask [%d] doesn't match.\n",
+                          pFormats[f].type, pFormats[f].depth, pFormats[f].direct.red, pFormats[f].direct.green,
+                              pFormats[f].direct.blue, pFormats[f].direct.redMask, pFormats[f].direct.greenMask,
+                                  pFormats[f].direct.blueMask, pFormats[f].direct.alpha, pFormats[f].direct.alphaMask);
+          #endif
+        } 
+#endif
+    }
+    *nformatp = nformats;
+    return pFormats;
+}
+
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+    int         i;
+    VisualPtr   pVisual;
+    for (i = 0, pVisual = pScreen->visuals;
+         i < pScreen->numVisuals;
+         i++, pVisual++)
+    {
+        if (pVisual->vid == visual)
+            return pVisual;
+    }
+    return 0;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return FALSE;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->type == PictTypeIndexed && !format->index.pColormap)
+	{
+	    if (format->index.vid == pScreen->rootVisual)
+		format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+								       RT_COLORMAP);
+	    else
+	    {
+                VisualPtr   pVisual;
+
+                pVisual = PictureFindVisual (pScreen, format->index.vid);
+		if (CreateColormap (FakeClientID (0), pScreen,
+				    pVisual,
+				    &format->index.pColormap, AllocNone,
+				    0) != Success)
+		{
+		    return FALSE;
+		}
+	    }
+	    if (!(*ps->InitIndexed) (pScreen, format))
+		return FALSE;
+	}
+	format++;
+    }
+    return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+    int	    s;
+
+    for (s = 0; s < screenInfo.numScreens; s++)
+    {
+	if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+	    return FALSE;
+	(void) AnimCurInit (screenInfo.screens[s]);
+    }
+
+    return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return FALSE;
+    ps->subpixel = subpixel;
+    return TRUE;
+    
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return SubPixelUnknown;
+    return ps->subpixel;
+}
+    
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+    int			type;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    switch (pVisual->class) {
+    case StaticGray:
+    case GrayScale:
+    case StaticColor:
+    case PseudoColor:
+	type = PictTypeIndexed;
+	break;
+    case TrueColor:
+    case DirectColor:
+	type = PictTypeDirect;
+	break;
+    default:
+	return 0;
+    }
+    while (nformat--)
+    {
+	if (format->depth == depth && format->type == type)
+	{
+	    if (type == PictTypeIndexed)
+	    {
+		if (format->index.vid == pVisual->vid)
+		    return format;
+	    }
+	    else
+	    {
+		if (format->direct.redMask << format->direct.red == 
+		    pVisual->redMask &&
+		    format->direct.greenMask << format->direct.green == 
+		    pVisual->greenMask &&
+		    format->direct.blueMask << format->direct.blue == 
+		    pVisual->blueMask)
+		{
+		    return format;
+		}
+	    }
+	}
+	format++;
+    }
+    return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->depth == depth && format->format == (f & 0xffffff))
+	    return format;
+	format++;
+    }
+    return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+    if ( strcmp (name, "default" ) == 0)
+	return PictureCmapPolicyDefault;
+    else if ( strcmp (name, "mono" ) == 0)
+	return PictureCmapPolicyMono;
+    else if ( strcmp (name, "gray" ) == 0)
+	return PictureCmapPolicyGray;
+    else if ( strcmp (name, "color" ) == 0)
+	return PictureCmapPolicyColor;
+    else if ( strcmp (name, "all" ) == 0)
+	return PictureCmapPolicyAll;
+    else
+	return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+    PictureScreenPtr	ps;
+    int			n;
+    CARD32		type, a, r, g, b;
+    
+    if (PictureGeneration != serverGeneration)
+    {
+	PictureType = CreateNewResourceType (FreePicture);
+	if (!PictureType)
+	    return FALSE;
+	PictFormatType = CreateNewResourceType (FreePictFormat);
+	if (!PictFormatType)
+	    return FALSE;
+	GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+	if (!GlyphSetType)
+	    return FALSE;
+	PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+	if (PictureScreenPrivateIndex < 0)
+	    return FALSE;
+	PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+	PictureGeneration = serverGeneration;
+#ifdef XResExtension
+	RegisterResourceName (PictureType, "PICTURE");
+	RegisterResourceName (PictFormatType, "PICTFORMAT");
+	RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+    }
+    if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+	return FALSE;
+    
+    if (!formats)
+    {
+	formats = PictureCreateDefaultFormats (pScreen, &nformats);
+	if (!formats)
+	    return FALSE;
+    }
+    for (n = 0; n < nformats; n++)
+    {
+	if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+	{
+	    xfree (formats);
+	    return FALSE;
+	}
+	if (formats[n].type == PictTypeIndexed)
+	{
+            VisualPtr   pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+	    if ((pVisual->class | DynamicClass) == PseudoColor)
+		type = PICT_TYPE_COLOR;
+	    else
+		type = PICT_TYPE_GRAY;
+	    a = r = g = b = 0;
+	}
+	else
+	{
+	    if ((formats[n].direct.redMask|
+		 formats[n].direct.blueMask|
+		 formats[n].direct.greenMask) == 0)
+		type = PICT_TYPE_A;
+	    else if (formats[n].direct.red > formats[n].direct.blue)
+		type = PICT_TYPE_ARGB;
+	    else
+		type = PICT_TYPE_ABGR;
+	    a = Ones (formats[n].direct.alphaMask);
+	    r = Ones (formats[n].direct.redMask);
+	    g = Ones (formats[n].direct.greenMask);
+	    b = Ones (formats[n].direct.blueMask);
+	}
+	formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+    }
+    ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+    if (!ps)
+    {
+	xfree (formats);
+	return FALSE;
+    }
+    SetPictureScreen(pScreen, ps);
+    if (!GlyphInit (pScreen))
+    {
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    ps->totalPictureSize = sizeof (PictureRec);
+    ps->PicturePrivateSizes = 0;
+    ps->PicturePrivateLen = 0;
+    
+    ps->formats = formats;
+    ps->fallback = formats;
+    ps->nformats = nformats;
+    
+    ps->filters = 0;
+    ps->nfilters = 0;
+    ps->filterAliases = 0;
+    ps->nfilterAliases = 0;
+
+    ps->subpixel = SubPixelUnknown;
+
+    ps->CloseScreen = pScreen->CloseScreen;
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    pScreen->CloseScreen = PictureCloseScreen;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (!PictureSetDefaultFilters (pScreen))
+    {
+	PictureResetFilters (pScreen);
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr    pPicture)
+{
+    pPicture->refcnt = 1;
+    pPicture->repeat = 0;
+    pPicture->graphicsExposures = FALSE;
+    pPicture->subWindowMode = ClipByChildren;
+    pPicture->polyEdge = PolyEdgeSharp;
+    pPicture->polyMode = PolyModePrecise;
+    pPicture->freeCompClip = FALSE;
+    pPicture->clientClipType = CT_NONE;
+    pPicture->componentAlpha = FALSE;
+    pPicture->repeatType = RepeatNone;
+
+    pPicture->alphaMap = 0;
+    pPicture->alphaOrigin.x = 0;
+    pPicture->alphaOrigin.y = 0;
+
+    pPicture->clipOrigin.x = 0;
+    pPicture->clipOrigin.y = 0;
+    pPicture->clientClip = 0;
+
+    pPicture->transform = 0;
+
+    pPicture->dither = None;
+    pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+    pPicture->filter_params = 0;
+    pPicture->filter_nparams = 0;
+
+    pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+    pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+    pPicture->pSourcePict = 0;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture;
+    char		*ptr;
+    DevUnion		*ppriv;
+    unsigned int    	*sizes;
+    unsigned int    	size;
+    int			i;
+
+    pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+    if (!pPicture)
+	return 0;
+    ppriv = (DevUnion *)(pPicture + 1);
+    pPicture->devPrivates = ppriv;
+    sizes = ps->PicturePrivateSizes;
+    ptr = (char *)(ppriv + ps->PicturePrivateLen);
+    for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return pPicture;
+}
+
+/*
+ * Let picture always point to the virtual pixmap.
+ * For sure this is not the best way to deal with
+ * the virtual frame-buffer.
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		vmask,
+	       XID		*vlist,
+	       ClientPtr	client,
+	       int		*error)
+{
+    PicturePtr		pPicture;
+    PictureScreenPtr	ps = GetPictureScreen(pDrawable->pScreen);
+
+    pPicture = AllocatePicture (pDrawable->pScreen);
+    if (!pPicture)
+    {
+	*error = BadAlloc;
+	return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pDrawable = pDrawable;
+    pPicture->pFormat = pFormat;
+    pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+    if (pDrawable->type == DRAWABLE_PIXMAP)
+    {
+        #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+        pPicture->pDrawable = nxagentVirtualDrawable(pDrawable);
+
+        #endif
+
+	++((PixmapPtr)pDrawable)->refcnt;
+	pPicture->pNext = 0;
+    }
+    else
+    {
+	pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+	SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+    }
+
+    SetPictureToDefaults (pPicture);
+    
+    if (vmask)
+	*error = ChangePicture (pPicture, vmask, vlist, 0, client);
+    else
+	*error = Success;
+    if (*error == Success)
+	*error = (*ps->CreatePicture) (pPicture);
+    if (*error != Success)
+    {
+	FreePicture (pPicture, (XID) 0);
+	pPicture = 0;
+    }
+    return pPicture;
+}
+
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+    return
+        (c.alpha >> 8 << 24) |
+        (c.red >> 8 << 16) |
+        (c.green & 0xff00) |
+        (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+    unsigned int a = x >> 24;
+    unsigned int t = (x & 0xff00ff) * a;
+    t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+    t &= 0xff00ff;
+
+    x = ((x >> 8) & 0xff) * a;
+    x = (x + ((x >> 8) & 0xff) + 0x80);
+    x &= 0xff00;
+    x |= t | (a << 24);
+    return x;
+}
+
+static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+                                          unsigned int y, unsigned int b)
+{
+    CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+    t >>= 8;
+    t &= 0xff00ff;
+
+    x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+    x &= 0xff00ff00;
+    x |= t;
+    return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+    int begin_pos, end_pos;
+    xFixed incr, dpos;
+    int pos, current_stop;
+    PictGradientStopPtr stops = pGradient->linear.stops;
+    int nstops = pGradient->linear.nstops;
+
+    /* The position where the gradient begins and ends */
+    begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+    end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+    pos = 0; /* The position in the color table. */
+
+    /* Up to first point */
+    while (pos <= begin_pos) {
+        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+        ++pos;
+    }
+
+    incr =  (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
+    dpos = incr * pos; /* The position in terms of 0-1. */
+
+    current_stop = 0; /* We always interpolate between current and current + 1. */
+
+    /* Gradient area */
+    while (pos < end_pos) {
+        unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+        unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+        int dist = (int)(256*(dpos - stops[current_stop].x)
+                         / (stops[current_stop+1].x - stops[current_stop].x));
+        int idist = 256 - dist;
+
+        pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+        ++pos;
+        dpos += incr;
+
+        if (dpos > stops[current_stop + 1].x)
+            ++current_stop;
+    }
+
+    /* After last point */
+    while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+        ++pos;
+    }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+                         xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+    int i;
+    xFixed dpos;
+
+    if (stopCount <= 0) {
+        *error = BadValue;
+        return;
+    }
+
+    dpos = -1;
+    for (i = 0; i < stopCount; ++i) {
+        if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+            *error = BadValue;
+            return;
+        }
+        dpos = stopPoints[i];
+    }
+
+    pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
+    if (!pGradient->linear.stops) {
+        *error = BadAlloc;
+        return;
+    }
+
+    pGradient->linear.nstops = stopCount;
+
+    for (i = 0; i < stopCount; ++i) {
+        pGradient->linear.stops[i].x = stopPoints[i];
+        pGradient->linear.stops[i].color = stopColors[i];
+    }
+    initGradientColorTable(pGradient, error);
+}
+
+static PicturePtr createSourcePicture(void)
+{
+    PicturePtr pPicture;
+    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+    pPicture->pDrawable = 0;
+    pPicture->pFormat = 0;
+    pPicture->pNext = 0;
+
+    SetPictureToDefaults(pPicture);
+    return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+    PicturePtr pPicture;
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+    pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+    pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+    return pPicture;
+}
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+                             int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+    if (p1->x == p2->x && p1->y == p2->y) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+
+    pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+    pPicture->pSourcePict->linear.p1 = *p1;
+    pPicture->pSourcePict->linear.p2 = *p2;
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+                             xFixed innerRadius, xFixed outerRadius,
+                             int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+    PictRadialGradient *radial;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+    {
+        double dx = (double)(inner->x - outer->x);
+        double dy = (double)(inner->y - outer->y);
+        if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+            *error = BadValue;
+            return 0;
+        }
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+    radial = &pPicture->pSourcePict->radial;
+
+    radial->type = SourcePictTypeRadial;
+    {
+        double x = (double)innerRadius / (double)outerRadius;
+        radial->dx = (outer->x - inner->x);
+        radial->dy = (outer->y - inner->y);
+        radial->fx = (inner->x) - x*radial->dx;
+        radial->fy = (inner->y) - x*radial->dy;
+        radial->m = 1./(1+x);
+        radial->b = -x*radial->m;
+        radial->dx /= 65536.;
+        radial->dy /= 65536.;
+        radial->fx /= 65536.;
+        radial->fy /= 65536.;
+        x = outerRadius/65536.;
+        radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+    }
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+                              int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+
+    pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+    pPicture->pSourcePict->conical.center = *center;
+    pPicture->pSourcePict->conical.angle = angle;
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client)
+{
+    ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+    PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
+    BITS32		index2;
+    int			error = 0;
+    BITS32		maskQ;
+    
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    maskQ = vmask;
+    while (vmask && !error)
+    {
+	index2 = (BITS32) lowbit (vmask);
+	vmask &= ~index2;
+	pPicture->stateChanges |= index2;
+	switch (index2)
+	{
+	case CPRepeat:
+	    {
+		unsigned int	newr;
+		newr = NEXT_VAL(unsigned int);
+		if (newr <= RepeatReflect)
+		{
+		    pPicture->repeat = (newr != RepeatNone);
+		    pPicture->repeatType = newr;
+		}
+		else
+		{
+		    client->errorValue = newr;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPAlphaMap:
+	    {
+		PicturePtr  pAlpha;
+		
+		if (vlist)
+		{
+		    Picture	pid = NEXT_VAL(Picture);
+
+		    if (pid == None)
+			pAlpha = 0;
+		    else
+		    {
+			pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+								     pid, 
+								     PictureType, 
+								     SecurityWriteAccess|SecurityReadAccess);
+			if (!pAlpha)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+			if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+			{
+			    client->errorValue = pid;
+			    error = BadMatch;
+			    break;
+			}
+		    }
+		}
+		else
+		    pAlpha = NEXT_PTR(PicturePtr);
+		if (!error)
+		{
+		    if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+			pAlpha->refcnt++;
+		    if (pPicture->alphaMap)
+			FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+		    pPicture->alphaMap = pAlpha;
+		}
+	    }
+	    break;
+	case CPAlphaXOrigin:
+	    pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPAlphaYOrigin:
+	    pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipXOrigin:
+	    pPicture->clipOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPClipYOrigin:
+	    pPicture->clipOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipMask:
+	    {
+		Pixmap	    pid;
+		PixmapPtr   pPixmap;
+		int	    clipType;
+                if (!pScreen)
+                    return BadDrawable;
+
+		if (vlist)
+		{
+		    pid = NEXT_VAL(Pixmap);
+		    if (pid == None)
+		    {
+			clipType = CT_NONE;
+			pPixmap = NullPixmap;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+								    pid, 
+								    RT_PIXMAP,
+								    SecurityReadAccess);
+			if (!pPixmap)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+		    }
+		}
+		else
+		{
+		    pPixmap = NEXT_PTR(PixmapPtr);
+		    if (pPixmap)
+			clipType = CT_PIXMAP;
+		    else
+			clipType = CT_NONE;
+		}
+
+		if (pPixmap)
+		{
+		    if ((pPixmap->drawable.depth != 1) ||
+			(pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			break;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap->refcnt++;
+		    }
+		}
+
+                #ifdef DEBUG
+                fprintf(stderr, "ChangePicture: Going to call ChangePictureClip with clipType [%d] pPixmap [%p].\n",
+                            clipType, (void *) pPixmap);
+                #endif
+
+		error = (*ps->ChangePictureClip)(pPicture, clipType,
+						 (pointer)pPixmap, 0);
+		break;
+	    }
+	case CPGraphicsExposure:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe <= xTrue)
+		    pPicture->graphicsExposures = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPSubwindowMode:
+	    {
+		unsigned int	news;
+		news = NEXT_VAL(unsigned int);
+		if (news == ClipByChildren || news == IncludeInferiors)
+		    pPicture->subWindowMode = news;
+		else
+		{
+		    client->errorValue = news;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyEdge:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+		    pPicture->polyEdge = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyMode:
+	    {
+		unsigned int	newm;
+		newm = NEXT_VAL(unsigned int);
+		if (newm == PolyModePrecise || newm == PolyModeImprecise)
+		    pPicture->polyMode = newm;
+		else
+		{
+		    client->errorValue = newm;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPDither:
+	    pPicture->dither = NEXT_VAL(Atom);
+	    break;
+	case CPComponentAlpha:
+	    {
+		unsigned int	newca;
+
+		newca = NEXT_VAL (unsigned int);
+		if (newca <= xTrue)
+		    pPicture->componentAlpha = newca;
+		else
+		{
+		    client->errorValue = newca;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	default:
+	    client->errorValue = maskQ;
+	    error = BadValue;
+	    break;
+	}
+    }
+    if (ps)
+        (*ps->ChangePicture) (pPicture, maskQ);
+    return error;
+}
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    RegionPtr		clientClip;
+    int			result;
+
+    clientClip = RECTS_TO_REGION(pScreen,
+				 nRect, rects, CT_UNSORTED);
+    if (!clientClip)
+	return BadAlloc;
+    result =(*ps->ChangePictureClip) (pPicture, CT_REGION, 
+				      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+	pPicture->clipOrigin.x = xOrigin;
+	pPicture->clipOrigin.y = yOrigin;
+	pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+	pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+int
+SetPictureClipRegion (PicturePtr    pPicture,
+                      int           xOrigin,
+                      int           yOrigin,
+                      RegionPtr     pRegion)
+{
+    ScreenPtr           pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    RegionPtr           clientClip;
+    int                 result;
+    int                 type;
+
+    if (pRegion)
+    {
+        type = CT_REGION;
+        clientClip = REGION_CREATE (pScreen,
+                                    REGION_EXTENTS(pScreen, pRegion),
+                                    REGION_NUM_RECTS(pRegion));
+        if (!clientClip)
+            return BadAlloc;
+        if (!REGION_COPY (pSCreen, clientClip, pRegion))
+        {
+            REGION_DESTROY (pScreen, clientClip);
+            return BadAlloc;
+        }
+    }
+    else
+    {
+        type = CT_NONE;
+        clientClip = 0;
+    }
+
+    result =(*ps->ChangePictureClip) (pPicture, type,
+                                      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+        pPicture->clipOrigin.x = xOrigin;
+        pPicture->clipOrigin.y = yOrigin;
+        pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+        pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform)
+{
+    static const PictTransform	identity = { {
+	{ xFixed1, 0x00000, 0x00000 },
+	{ 0x00000, xFixed1, 0x00000 },
+	{ 0x00000, 0x00000, xFixed1 },
+    } };
+
+    if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+	transform = 0;
+    
+    if (transform)
+    {
+	if (!pPicture->transform)
+	{
+	    pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+	    if (!pPicture->transform)
+		return BadAlloc;
+	}
+	*pPicture->transform = *transform;
+    }
+    else
+    {
+	if (pPicture->transform)
+	{
+	    xfree (pPicture->transform);
+	    pPicture->transform = 0;
+	}
+    }
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+    return Success;
+}
+
+void
+CopyPicture (PicturePtr	pSrc,
+	     Mask	mask,
+	     PicturePtr	pDst)
+{
+    PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+    Mask origMask = mask;
+
+    pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    pDst->stateChanges |= mask;
+
+    while (mask) {
+	Mask bit = lowbit(mask);
+
+	switch (bit)
+	{
+	case CPRepeat:
+	    pDst->repeat = pSrc->repeat;
+	    pDst->repeatType = pSrc->repeatType;
+	    break;
+	case CPAlphaMap:
+	    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+		pSrc->alphaMap->refcnt++;
+	    if (pDst->alphaMap)
+		FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+	    pDst->alphaMap = pSrc->alphaMap;
+	    break;
+	case CPAlphaXOrigin:
+	    pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+	    break;
+	case CPAlphaYOrigin:
+	    pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+	    break;
+	case CPClipXOrigin:
+	    pDst->clipOrigin.x = pSrc->clipOrigin.x;
+	    break;
+	case CPClipYOrigin:
+	    pDst->clipOrigin.y = pSrc->clipOrigin.y;
+	    break;
+	case CPClipMask:
+	    switch (pSrc->clientClipType) {
+	    case CT_NONE:
+		(*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+		break;
+	    case CT_REGION:
+		if (!pSrc->clientClip) {
+		    (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+		} else {
+		    RegionPtr clientClip;
+		    RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+		    clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+			REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+			REGION_NUM_RECTS(srcClientClip));
+		    (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+		}
+		break;
+	    default:
+		/* XXX: CT_PIXMAP unimplemented */
+		break;
+	    }
+	    break;
+	case CPGraphicsExposure:
+	    pDst->graphicsExposures = pSrc->graphicsExposures;
+	    break;
+	case CPPolyEdge:
+	    pDst->polyEdge = pSrc->polyEdge;
+	    break;
+	case CPPolyMode:
+	    pDst->polyMode = pSrc->polyMode;
+	    break;
+	case CPDither:
+	    pDst->dither = pSrc->dither;
+	    break;
+	case CPComponentAlpha:
+	    pDst->componentAlpha = pSrc->componentAlpha;
+	    break;
+	}
+	mask &= ~bit;
+    }
+
+    (*ps->ChangePicture)(pDst, origMask);
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+    if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+    {
+	PictureScreenPtr    ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+	(*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+	pPicture->stateChanges = 0;
+	pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+    }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+    ValidateOnePicture (pPicture);
+    if (pPicture->alphaMap)
+	ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer	value,
+	     XID	pid)
+{
+    PicturePtr	pPicture = (PicturePtr) value;
+
+    if (--pPicture->refcnt == 0)
+    {
+	if (pPicture->transform)
+	    xfree (pPicture->transform);
+        if (!pPicture->pDrawable) {
+            if (pPicture->pSourcePict) {
+                if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+                    xfree(pPicture->pSourcePict->linear.stops);
+                xfree(pPicture->pSourcePict);
+            }
+        } else {
+            ScreenPtr	    pScreen = pPicture->pDrawable->pScreen;
+            PictureScreenPtr    ps = GetPictureScreen(pScreen);
+	
+            if (pPicture->alphaMap)
+                FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+            (*ps->DestroyPicture) (pPicture);
+            (*ps->DestroyPictureClip) (pPicture);
+            if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+            {
+                WindowPtr	pWindow = (WindowPtr) pPicture->pDrawable;
+                PicturePtr	*pPrev;
+
+                for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+                     *pPrev;
+                     pPrev = &(*pPrev)->pNext)
+                {
+                    if (*pPrev == pPicture)
+                    {
+                        *pPrev = pPicture->pNext;
+                        break;
+                    }
+                }
+            }
+            else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+            {
+                (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+            }
+        }
+	xfree (pPicture);
+    }
+    return Success;
+}
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid)
+{
+    return Success;
+}
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    if (pMask)
+	ValidatePicture (pMask);
+    ValidatePicture (pDst);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+}
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+
+    #ifdef TEST
+    fprintf(stderr, "CompositeGlyphs: Going to composite glyphs with "
+		"source at [%p] and destination at [%p].\n",
+		    (void *) pSrc, (void *) pDst);
+    #endif
+
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pDst);
+    (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+AddTraps (PicturePtr	pPicture,
+	  INT16		xOff,
+	  INT16		yOff,
+	  int		ntrap,
+	  xTrap		*traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+    
+    ValidatePicture (pPicture);
+    (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
+
+#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+                         PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] *
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    *vector = result;
+    return TRUE;
+}
+
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] * 
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    for (j = 0; j < 2; j++)
+    {
+	partial = (xFixed_48_16) result.vector[j] << 16;
+	v = partial / result.vector[2];
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	vector->vector[j] = (xFixed) v;
+    }
+    vector->vector[2] = xFixed1;
+    return TRUE;
+}
+
+#ifndef True
+# define True 1
+#endif
+
+#ifndef False
+# define False 0
+#endif
+
+void nxagentReconnectPictFormat(void*, XID, void*);
+
+Bool nxagentReconnectAllPictFormat(void *p)
+{
+  PictFormatPtr formats_old, formats;
+  int nformats, nformats_old;
+  VisualPtr pVisual;
+  Bool success = True;
+  Bool matched;
+  int i, n;
+  CARD32 type, a, r, g, b;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+  fprintf(stderr, "nxagentReconnectAllPictFormat\n");
+  #endif
+
+  formats_old = GetPictureScreen(nxagentDefaultScreen) -> formats;
+  nformats_old = GetPictureScreen(nxagentDefaultScreen) -> nformats;
+
+  /*
+   * TODO: We could copy PictureCreateDefaultFormats,
+   *       in order not to waste ID with FakeClientID().
+   */
+  formats = PictureCreateDefaultFormats (nxagentDefaultScreen, &nformats);
+
+  if (!formats)
+    return False;
+
+  for (n = 0; n < nformats; n++)
+  {
+    if (formats[n].type == PictTypeIndexed)
+    {
+      pVisual = nxagentVisualFromID(nxagentDefaultScreen, formats[n].index.vid);
+
+      if ((pVisual->class | DynamicClass) == PseudoColor)
+        type = PICT_TYPE_COLOR;
+      else
+        type = PICT_TYPE_GRAY;
+      a = r = g = b = 0;
+    }
+    else
+    {
+      if ((formats[n].direct.redMask|
+           formats[n].direct.blueMask|
+           formats[n].direct.greenMask) == 0)
+        type = PICT_TYPE_A;
+      else if (formats[n].direct.red > formats[n].direct.blue)
+        type = PICT_TYPE_ARGB;
+      else
+        type = PICT_TYPE_ABGR;
+      a = Ones (formats[n].direct.alphaMask);
+      r = Ones (formats[n].direct.redMask);
+      g = Ones (formats[n].direct.greenMask);
+      b = Ones (formats[n].direct.blueMask);
+    }
+    formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+  }
+
+  for (n = 0; n < nformats_old; n++)
+  {
+    for (i = 0, matched = False; (!matched) && (i < nformats); i++)
+    {
+      if (formats_old[n].format == formats[i].format &&
+          formats_old[n].type == formats[i].type &&
+          formats_old[n].direct.red == formats[i].direct.red &&
+          formats_old[n].direct.green == formats[i].direct.green &&
+          formats_old[n].direct.blue == formats[i].direct.blue &&
+          formats_old[n].direct.redMask == formats[i].direct.redMask &&
+          formats_old[n].direct.greenMask == formats[i].direct.greenMask &&
+          formats_old[n].direct.blueMask == formats[i].direct.blueMask &&
+          formats_old[n].direct.alpha == formats[i].direct.alpha &&
+          formats_old[n].direct.alphaMask == formats[i].direct.alphaMask)
+      {
+       /*
+        * Regard depth 16 and 15 as were the same, if all other values match.
+        */
+
+        if ((formats_old[n].depth == formats[i].depth) ||
+               ((formats_old[n].depth == 15 || formats_old[n].depth == 16) &&
+                    (formats[i].depth == 15 || formats[i].depth == 16)))
+        {
+          matched = True;
+        }
+      }
+    }
+
+    if (!matched)
+    {
+      return False;
+    }
+  }
+
+  xfree(formats);
+
+  /* TODO: Perhaps do i have to do PictureFinishInit ?. */
+  /* TODO: We have to check for new Render protocol version. */
+
+  for (i = 0; (i < MAXCLIENTS) && (success); i++)
+  {
+    if (clients[i])
+    {
+      FindClientResourcesByType(clients[i], PictFormatType, nxagentReconnectPictFormat, &success);
+    }
+  }
+
+  return success;
+}
+
+/*
+ * It seem we don't have nothing
+ * to do for reconnect PictureFormat.
+ */
+
+void nxagentReconnectPictFormat(void *p0, XID x1, void *p2)
+{
+  PictFormatPtr pFormat;
+  Bool *pBool;
+
+  pFormat = (PictFormatPtr)p0;
+  pBool = (Bool*)p2;
+
+  #if defined(NXAGENT_RECONNECT_DEBUG) || defined(NXAGENT_RECONNECT_PICTFORMAT_DEBUG)
+  fprintf(stderr, "nxagentReconnectPictFormat.\n");
+  #endif
+}
+
+/*
+ * The set of picture formats may change considerably
+ * between different X servers. This poses a problem
+ * while migrating NX sessions, because a requisite to
+ * successfully reconnect the session is that all pic-
+ * ture formats have to be available on the new X server.
+ * To reduce such problems, we use a limited set of
+ * pictures available on the most X servers.
+ */
+
+void nxagentPictureCreateDefaultFormats(ScreenPtr pScreen, FormatInitRec *formats, int *nformats)
+{
+  DepthPtr  pDepth;
+  VisualPtr pVisual;
+
+  CARD32 format;
+  CARD8 depth;
+
+  int r, g, b;
+  int bpp;
+  int d;
+  int v;
+
+
+  formats[*nformats].format = PICT_a1;
+  formats[*nformats].depth = 1;
+  *nformats += 1;
+  formats[*nformats].format = PICT_a4;
+  formats[*nformats].depth = 4;
+  *nformats += 1;
+  formats[*nformats].format = PICT_a8;
+  formats[*nformats].depth = 8;
+  *nformats += 1;
+  formats[*nformats].format = PICT_a8r8g8b8;
+  formats[*nformats].depth = 32;
+  *nformats += 1;
+
+  /*
+   * This format should be required by the
+   * protocol, but it's not used by Xgl.
+   *
+   * formats[*nformats].format = PICT_x8r8g8b8;
+   * formats[*nformats].depth = 32;
+   * *nformats += 1;
+   */
+
+  /* now look through the depths and visuals adding other formats */
+  for (v = 0; v < pScreen->numVisuals; v++)
+  {
+    pVisual = &pScreen->visuals[v];
+    depth = visualDepth (pScreen, pVisual);
+    if (!depth)
+      continue;
+
+    bpp = BitsPerPixel (depth);
+
+    switch (pVisual->class)
+    {
+      case DirectColor:
+      case TrueColor:
+        r = Ones (pVisual->redMask);
+        g = Ones (pVisual->greenMask);
+        b = Ones (pVisual->blueMask);
+
+        if (pVisual->offsetBlue == 0 &&
+            pVisual->offsetGreen == b &&
+            pVisual->offsetRed == b + g)
+        {
+    	  format = PICT_FORMAT(bpp, PICT_TYPE_ARGB, 0, r, g, b);
+    	  *nformats = addFormat (formats, *nformats, format, depth);
+        }
+        break;
+      case StaticColor:
+      case PseudoColor:
+      case StaticGray:
+      case GrayScale:
+        break;
+    }
+  }
+
+  for (d = 0; d < pScreen -> numDepths; d++)
+  {
+    pDepth = &pScreen -> allowedDepths[d];
+    bpp = BitsPerPixel(pDepth -> depth);
+
+    switch (bpp) {
+    case 16:
+      if (pDepth->depth == 15)
+      {
+        *nformats = addFormat (formats, *nformats,
+    			      PICT_x1r5g5b5, pDepth->depth);
+      }
+
+      if (pDepth->depth == 16) 
+      {
+        *nformats = addFormat (formats, *nformats,
+    	                      PICT_r5g6b5, pDepth->depth);
+      }
+      break;
+    case 24:
+      if (pDepth->depth == 24)
+      {
+        *nformats = addFormat (formats, *nformats,
+    	                      PICT_r8g8b8, pDepth->depth);
+      }
+      break;
+    case 32:
+      if (pDepth->depth == 24)
+      {
+	*nformats = addFormat (formats, *nformats,
+			      PICT_x8r8g8b8, pDepth->depth);
+      }
+      break;
+    }
+  }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original
new file mode 100644
index 000000000..3ed60310e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.X.original
@@ -0,0 +1,1864 @@
+/*
+ * $XFree86: xc/programs/Xserver/render/picture.c,v 1.29 2002/11/23 02:38:15 keithp Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "picturestr.h"
+
+int		PictureScreenPrivateIndex = -1;
+int		PictureWindowPrivateIndex;
+int		PictureGeneration;
+RESTYPE		PictureType;
+RESTYPE		PictFormatType;
+RESTYPE		GlyphSetType;
+int		PictureCmapPolicy = PictureCmapPolicyDefault;
+
+/* Picture Private machinery */
+
+static int picturePrivateCount;
+
+void
+ResetPicturePrivateIndex (void)
+{
+    picturePrivateCount = 0;
+}
+
+int
+AllocatePicturePrivateIndex (void)
+{
+    return picturePrivateCount++;
+}
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    unsigned int	oldamount;
+
+    /* Round up sizes for proper alignment */
+    amount = ((amount + (sizeof(long) - 1)) / sizeof(long)) * sizeof(long);
+
+    if (index2 >= ps->PicturePrivateLen)
+    {
+	unsigned int *nsizes;
+
+	nsizes = (unsigned int *)xrealloc(ps->PicturePrivateSizes,
+					  (index2 + 1) * sizeof(unsigned int));
+	if (!nsizes)
+	    return FALSE;
+	while (ps->PicturePrivateLen <= index2)
+	{
+	    nsizes[ps->PicturePrivateLen++] = 0;
+	    ps->totalPictureSize += sizeof(DevUnion);
+	}
+	ps->PicturePrivateSizes = nsizes;
+    }
+    oldamount = ps->PicturePrivateSizes[index2];
+    if (amount > oldamount)
+    {
+	ps->PicturePrivateSizes[index2] = amount;
+	ps->totalPictureSize += (amount - oldamount);
+    }
+
+    return TRUE;
+}
+
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow)
+{
+    ScreenPtr		pScreen = pWindow->drawable.pScreen;
+    PicturePtr		pPicture;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool		ret;
+
+    while ((pPicture = GetPictureWindow(pWindow)))
+    {
+	SetPictureWindow(pWindow, pPicture->pNext);
+	if (pPicture->id)
+	    FreeResource (pPicture->id, PictureType);
+	FreePicture ((pointer) pPicture, pPicture->id);
+    }
+    pScreen->DestroyWindow = ps->DestroyWindow;
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    return ret;
+}
+
+Bool
+PictureCloseScreen (int index, ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    Bool                ret;
+    int			n;
+
+    pScreen->CloseScreen = ps->CloseScreen;
+    ret = (*pScreen->CloseScreen) (index, pScreen);
+    PictureResetFilters (pScreen);
+    for (n = 0; n < ps->nformats; n++)
+	if (ps->formats[n].type == PictTypeIndexed)
+	    (*ps->CloseIndexed) (pScreen, &ps->formats[n]);
+    SetPictureScreen(pScreen, 0);
+    if (ps->PicturePrivateSizes)
+	xfree (ps->PicturePrivateSizes);
+    xfree (ps->formats);
+    xfree (ps);
+    return ret;
+}
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+    ScreenPtr		pScreen = pColormap->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    pScreen->StoreColors = ps->StoreColors;
+    (*pScreen->StoreColors) (pColormap, ndef, pdef);
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (pColormap->class == PseudoColor || pColormap->class == GrayScale)
+    {
+	PictFormatPtr	format = ps->formats;
+	int		nformats = ps->nformats;
+
+	while (nformats--)
+	{
+	    if (format->type == PictTypeIndexed &&
+		format->index.pColormap == pColormap)
+	    {
+		(*ps->UpdateIndexed) (pScreen, format, ndef, pdef);
+		break;
+	    }
+	    format++;
+	}
+    }
+}
+
+static int
+visualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    int		d, v;
+    DepthPtr	pDepth;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	for (v = 0; v < pDepth->numVids; v++)
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+    }
+    return 0;
+}
+
+typedef struct _formatInit {
+    CARD32  format;
+    CARD8   depth;
+} FormatInitRec, *FormatInitPtr;
+
+static int
+addFormat (FormatInitRec    formats[256],
+	   int		    nformat,
+	   CARD32	    format,
+	   CARD8	    depth)
+{
+    int	n;
+
+    for (n = 0; n < nformat; n++)
+	if (formats[n].format == format && formats[n].depth == depth)
+	    return nformat;
+    formats[nformat].format = format;
+    formats[nformat].depth = depth;
+    return ++nformat;
+}
+
+#define Mask(n)	((n) == 32 ? 0xffffffff : ((1 << (n))-1))
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
+{
+    int		    nformats, f;
+    PictFormatPtr   pFormats;
+    FormatInitRec   formats[1024];
+    CARD32	    format;
+    CARD8	    depth;
+    VisualPtr	    pVisual;
+    int		    v;
+    int		    bpp;
+    int		    type;
+    int		    r, g, b;
+    int		    d;
+    DepthPtr	    pDepth;
+
+    nformats = 0;
+    /* formats required by protocol */
+    formats[nformats].format = PICT_a1;
+    formats[nformats].depth = 1;
+    nformats++;
+    formats[nformats].format = PICT_a8;
+    formats[nformats].depth = 8;
+    nformats++;
+    formats[nformats].format = PICT_a4;
+    formats[nformats].depth = 4;
+    nformats++;
+    formats[nformats].format = PICT_a8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+    formats[nformats].format = PICT_x8r8g8b8;
+    formats[nformats].depth = 32;
+    nformats++;
+
+    /* now look through the depths and visuals adding other formats */
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = &pScreen->visuals[v];
+	depth = visualDepth (pScreen, pVisual);
+	if (!depth)
+	    continue;
+    	bpp = BitsPerPixel (depth);
+	switch (pVisual->class) {
+	case DirectColor:
+	case TrueColor:
+	    r = Ones (pVisual->redMask);
+	    g = Ones (pVisual->greenMask);
+	    b = Ones (pVisual->blueMask);
+	    type = PICT_TYPE_OTHER;
+	    /*
+	     * Current rendering code supports only two direct formats,
+	     * fields must be packed together at the bottom of the pixel
+	     * and must be either RGB or BGR
+	     */
+	    if (pVisual->offsetBlue == 0 &&
+		pVisual->offsetGreen == b &&
+		pVisual->offsetRed == b + g)
+	    {
+		type = PICT_TYPE_ARGB;
+	    }
+	    else if (pVisual->offsetRed == 0 &&
+		     pVisual->offsetGreen == r && 
+		     pVisual->offsetBlue == r + g)
+	    {
+		type = PICT_TYPE_ABGR;
+	    }
+	    if (type != PICT_TYPE_OTHER)
+	    {
+		format = PICT_FORMAT(bpp, type, 0, r, g, b);
+		nformats = addFormat (formats, nformats, format, depth);
+	    }
+	    break;
+	case StaticColor:
+	case PseudoColor:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_COLOR, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	case StaticGray:
+	case GrayScale:
+	    format = PICT_VISFORMAT (bpp, PICT_TYPE_GRAY, v);
+	    nformats = addFormat (formats, nformats, format, depth);
+	    break;
+	}
+    }
+    /*
+     * Walk supported depths and add useful Direct formats
+     */
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = &pScreen->allowedDepths[d];
+	bpp = BitsPerPixel (pDepth->depth);
+	format = 0;
+	switch (bpp) {
+	case 16:
+	    /* depth 12 formats */
+	    if (pDepth->depth >= 12)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x4b4g4r4, pDepth->depth);
+	    }
+	    /* depth 15 formats */
+	    if (pDepth->depth >= 15)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x1b5g5r5, pDepth->depth);
+	    }
+	    /* depth 16 formats */
+	    if (pDepth->depth >= 16) 
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_a1r5g5b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a1b5g5r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_r5g6b5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b5g6r5, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4r4g4b4, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_a4b4g4r4, pDepth->depth);
+	    }
+	    break;
+	case 24:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_b8g8r8, pDepth->depth);
+	    }
+	    break;
+	case 32:
+	    if (pDepth->depth >= 24)
+	    {
+		nformats = addFormat (formats, nformats,
+				      PICT_x8r8g8b8, pDepth->depth);
+		nformats = addFormat (formats, nformats,
+				      PICT_x8b8g8r8, pDepth->depth);
+	    }
+	    break;
+	}
+    }
+    
+
+    pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+    if (!pFormats)
+	return 0;
+    memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+    for (f = 0; f < nformats; f++)
+    {
+        pFormats[f].id = FakeClientID (0);
+	pFormats[f].depth = formats[f].depth;
+	format = formats[f].format;
+	pFormats[f].format = format;
+	switch (PICT_FORMAT_TYPE(format)) {
+	case PICT_TYPE_ARGB:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = (PICT_FORMAT_G(format) + 
+				      PICT_FORMAT_B(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_B(format);
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = 0;
+	    break;
+
+	case PICT_TYPE_ABGR:
+	    pFormats[f].type = PictTypeDirect;
+	    
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+	    if (pFormats[f].direct.alphaMask)
+		pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
+					    PICT_FORMAT_G(format) +
+					    PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
+	    pFormats[f].direct.blue = (PICT_FORMAT_G(format) + 
+				       PICT_FORMAT_R(format));
+	    
+	    pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
+	    pFormats[f].direct.green = PICT_FORMAT_R(format);
+	    
+	    pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
+	    pFormats[f].direct.red = 0;
+	    break;
+
+	case PICT_TYPE_A:
+	    pFormats[f].type = PictTypeDirect;
+
+	    pFormats[f].direct.alpha = 0;
+	    pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
+
+	    /* remaining fields already set to zero */
+	    break;
+	    
+	case PICT_TYPE_COLOR:
+	case PICT_TYPE_GRAY:
+	    pFormats[f].type = PictTypeIndexed;
+	    pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
+	    break;
+	}
+    }
+    *nformatp = nformats;
+    return pFormats;
+}
+
+static VisualPtr
+PictureFindVisual (ScreenPtr pScreen, VisualID visual)
+{
+    int         i;
+    VisualPtr   pVisual;
+    for (i = 0, pVisual = pScreen->visuals;
+         i < pScreen->numVisuals;
+         i++, pVisual++)
+    {
+        if (pVisual->vid == visual)
+            return pVisual;
+    }
+    return 0;
+}
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return FALSE;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->type == PictTypeIndexed && !format->index.pColormap)
+	{
+	    if (format->index.vid == pScreen->rootVisual)
+		format->index.pColormap = (ColormapPtr) LookupIDByType(pScreen->defColormap,
+								       RT_COLORMAP);
+	    else
+	    {
+                VisualPtr   pVisual;
+
+                pVisual = PictureFindVisual (pScreen, format->index.vid);
+		if (CreateColormap (FakeClientID (0), pScreen,
+				    pVisual,
+				    &format->index.pColormap, AllocNone,
+				    0) != Success)
+		{
+		    return FALSE;
+		}
+	    }
+	    if (!(*ps->InitIndexed) (pScreen, format))
+		return FALSE;
+	}
+	format++;
+    }
+    return TRUE;
+}
+
+Bool
+PictureFinishInit (void)
+{
+    int	    s;
+
+    for (s = 0; s < screenInfo.numScreens; s++)
+    {
+	if (!PictureInitIndexedFormats (screenInfo.screens[s]))
+	    return FALSE;
+	(void) AnimCurInit (screenInfo.screens[s]);
+    }
+
+    return TRUE;
+}
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return FALSE;
+    ps->subpixel = subpixel;
+    return TRUE;
+    
+}
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+
+    if (!ps)
+	return SubPixelUnknown;
+    return ps->subpixel;
+}
+    
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+    int			type;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    switch (pVisual->class) {
+    case StaticGray:
+    case GrayScale:
+    case StaticColor:
+    case PseudoColor:
+	type = PictTypeIndexed;
+	break;
+    case TrueColor:
+    case DirectColor:
+	type = PictTypeDirect;
+	break;
+    default:
+	return 0;
+    }
+    while (nformat--)
+    {
+	if (format->depth == depth && format->type == type)
+	{
+	    if (type == PictTypeIndexed)
+	    {
+		if (format->index.vid == pVisual->vid)
+		    return format;
+	    }
+	    else
+	    {
+		if (format->direct.redMask << format->direct.red == 
+		    pVisual->redMask &&
+		    format->direct.greenMask << format->direct.green == 
+		    pVisual->greenMask &&
+		    format->direct.blueMask << format->direct.blue == 
+		    pVisual->blueMask)
+		{
+		    return format;
+		}
+	    }
+	}
+	format++;
+    }
+    return 0;
+}
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 f)
+{
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+    PictFormatPtr	format;
+    int			nformat;
+
+    if (!ps)
+	return 0;
+    format = ps->formats;
+    nformat = ps->nformats;
+    while (nformat--)
+    {
+	if (format->depth == depth && format->format == (f & 0xffffff))
+	    return format;
+	format++;
+    }
+    return 0;
+}
+
+int
+PictureParseCmapPolicy (const char *name)
+{
+    if ( strcmp (name, "default" ) == 0)
+	return PictureCmapPolicyDefault;
+    else if ( strcmp (name, "mono" ) == 0)
+	return PictureCmapPolicyMono;
+    else if ( strcmp (name, "gray" ) == 0)
+	return PictureCmapPolicyGray;
+    else if ( strcmp (name, "color" ) == 0)
+	return PictureCmapPolicyColor;
+    else if ( strcmp (name, "all" ) == 0)
+	return PictureCmapPolicyAll;
+    else
+	return PictureCmapPolicyInvalid;
+}
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+    PictureScreenPtr	ps;
+    int			n;
+    CARD32		type, a, r, g, b;
+    
+    if (PictureGeneration != serverGeneration)
+    {
+	PictureType = CreateNewResourceType (FreePicture);
+	if (!PictureType)
+	    return FALSE;
+	PictFormatType = CreateNewResourceType (FreePictFormat);
+	if (!PictFormatType)
+	    return FALSE;
+	GlyphSetType = CreateNewResourceType (FreeGlyphSet);
+	if (!GlyphSetType)
+	    return FALSE;
+	PictureScreenPrivateIndex = AllocateScreenPrivateIndex();
+	if (PictureScreenPrivateIndex < 0)
+	    return FALSE;
+	PictureWindowPrivateIndex = AllocateWindowPrivateIndex();
+	PictureGeneration = serverGeneration;
+#ifdef XResExtension
+	RegisterResourceName (PictureType, "PICTURE");
+	RegisterResourceName (PictFormatType, "PICTFORMAT");
+	RegisterResourceName (GlyphSetType, "GLYPHSET");
+#endif
+    }
+    if (!AllocateWindowPrivate (pScreen, PictureWindowPrivateIndex, 0))
+	return FALSE;
+    
+    if (!formats)
+    {
+	formats = PictureCreateDefaultFormats (pScreen, &nformats);
+	if (!formats)
+	    return FALSE;
+    }
+    for (n = 0; n < nformats; n++)
+    {
+	if (!AddResource (formats[n].id, PictFormatType, (pointer) (formats+n)))
+	{
+	    xfree (formats);
+	    return FALSE;
+	}
+	if (formats[n].type == PictTypeIndexed)
+	{
+            VisualPtr   pVisual = PictureFindVisual (pScreen, formats[n].index.vid);
+	    if ((pVisual->class | DynamicClass) == PseudoColor)
+		type = PICT_TYPE_COLOR;
+	    else
+		type = PICT_TYPE_GRAY;
+	    a = r = g = b = 0;
+	}
+	else
+	{
+	    if ((formats[n].direct.redMask|
+		 formats[n].direct.blueMask|
+		 formats[n].direct.greenMask) == 0)
+		type = PICT_TYPE_A;
+	    else if (formats[n].direct.red > formats[n].direct.blue)
+		type = PICT_TYPE_ARGB;
+	    else
+		type = PICT_TYPE_ABGR;
+	    a = Ones (formats[n].direct.alphaMask);
+	    r = Ones (formats[n].direct.redMask);
+	    g = Ones (formats[n].direct.greenMask);
+	    b = Ones (formats[n].direct.blueMask);
+	}
+	formats[n].format = PICT_FORMAT(0,type,a,r,g,b);
+    }
+    ps = (PictureScreenPtr) xalloc (sizeof (PictureScreenRec));
+    if (!ps)
+    {
+	xfree (formats);
+	return FALSE;
+    }
+    SetPictureScreen(pScreen, ps);
+    if (!GlyphInit (pScreen))
+    {
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    ps->totalPictureSize = sizeof (PictureRec);
+    ps->PicturePrivateSizes = 0;
+    ps->PicturePrivateLen = 0;
+    
+    ps->formats = formats;
+    ps->fallback = formats;
+    ps->nformats = nformats;
+    
+    ps->filters = 0;
+    ps->nfilters = 0;
+    ps->filterAliases = 0;
+    ps->nfilterAliases = 0;
+
+    ps->subpixel = SubPixelUnknown;
+
+    ps->CloseScreen = pScreen->CloseScreen;
+    ps->DestroyWindow = pScreen->DestroyWindow;
+    ps->StoreColors = pScreen->StoreColors;
+    pScreen->DestroyWindow = PictureDestroyWindow;
+    pScreen->CloseScreen = PictureCloseScreen;
+    pScreen->StoreColors = PictureStoreColors;
+
+    if (!PictureSetDefaultFilters (pScreen))
+    {
+	PictureResetFilters (pScreen);
+	SetPictureScreen(pScreen, 0);
+	xfree (formats);
+	xfree (ps);
+	return FALSE;
+    }
+
+    return TRUE;
+}
+
+void
+SetPictureToDefaults (PicturePtr    pPicture)
+{
+    pPicture->refcnt = 1;
+    pPicture->repeat = 0;
+    pPicture->graphicsExposures = FALSE;
+    pPicture->subWindowMode = ClipByChildren;
+    pPicture->polyEdge = PolyEdgeSharp;
+    pPicture->polyMode = PolyModePrecise;
+    pPicture->freeCompClip = FALSE;
+    pPicture->clientClipType = CT_NONE;
+    pPicture->componentAlpha = FALSE;
+    pPicture->repeatType = RepeatNone;
+
+    pPicture->alphaMap = 0;
+    pPicture->alphaOrigin.x = 0;
+    pPicture->alphaOrigin.y = 0;
+
+    pPicture->clipOrigin.x = 0;
+    pPicture->clipOrigin.y = 0;
+    pPicture->clientClip = 0;
+
+    pPicture->transform = 0;
+
+    pPicture->dither = None;
+    pPicture->filter = PictureGetFilterId (FilterNearest, -1, TRUE);
+    pPicture->filter_params = 0;
+    pPicture->filter_nparams = 0;
+
+    pPicture->serialNumber = GC_CHANGE_SERIAL_BIT;
+    pPicture->stateChanges = (1 << (CPLastBit+1)) - 1;
+    pPicture->pSourcePict = 0;
+}
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    PicturePtr		pPicture;
+    char		*ptr;
+    DevUnion		*ppriv;
+    unsigned int    	*sizes;
+    unsigned int    	size;
+    int			i;
+
+    pPicture = (PicturePtr) xalloc (ps->totalPictureSize);
+    if (!pPicture)
+	return 0;
+    ppriv = (DevUnion *)(pPicture + 1);
+    pPicture->devPrivates = ppriv;
+    sizes = ps->PicturePrivateSizes;
+    ptr = (char *)(ppriv + ps->PicturePrivateLen);
+    for (i = ps->PicturePrivateLen; --i >= 0; ppriv++, sizes++)
+    {
+	if ( (size = *sizes) )
+	{
+	    ppriv->ptr = (pointer)ptr;
+	    ptr += size;
+	}
+	else
+	    ppriv->ptr = (pointer)NULL;
+    }
+    return pPicture;
+}
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		vmask,
+	       XID		*vlist,
+	       ClientPtr	client,
+	       int		*error)
+{
+    PicturePtr		pPicture;
+    PictureScreenPtr	ps = GetPictureScreen(pDrawable->pScreen);
+
+    pPicture = AllocatePicture (pDrawable->pScreen);
+    if (!pPicture)
+    {
+	*error = BadAlloc;
+	return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pDrawable = pDrawable;
+    pPicture->pFormat = pFormat;
+    pPicture->format = pFormat->format | (pDrawable->bitsPerPixel << 24);
+    if (pDrawable->type == DRAWABLE_PIXMAP)
+    {
+	++((PixmapPtr)pDrawable)->refcnt;
+	pPicture->pNext = 0;
+    }
+    else
+    {
+	pPicture->pNext = GetPictureWindow(((WindowPtr) pDrawable));
+	SetPictureWindow(((WindowPtr) pDrawable), pPicture);
+    }
+
+    SetPictureToDefaults (pPicture);
+    
+    if (vmask)
+	*error = ChangePicture (pPicture, vmask, vlist, 0, client);
+    else
+	*error = Success;
+    if (*error == Success)
+	*error = (*ps->CreatePicture) (pPicture);
+    if (*error != Success)
+    {
+	FreePicture (pPicture, (XID) 0);
+	pPicture = 0;
+    }
+    return pPicture;
+}
+
+static CARD32 xRenderColorToCard32(xRenderColor c)
+{
+    return
+        (c.alpha >> 8 << 24) |
+        (c.red >> 8 << 16) |
+        (c.green & 0xff00) |
+        (c.blue >> 8);
+}
+
+static unsigned int premultiply(unsigned int x)
+{
+    unsigned int a = x >> 24;
+    unsigned int t = (x & 0xff00ff) * a;
+    t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+    t &= 0xff00ff;
+
+    x = ((x >> 8) & 0xff) * a;
+    x = (x + ((x >> 8) & 0xff) + 0x80);
+    x &= 0xff00;
+    x |= t | (a << 24);
+    return x;
+}
+
+static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
+                                          unsigned int y, unsigned int b)
+{
+    CARD32 t = (x & 0xff00ff) * a + (y & 0xff00ff) * b;
+    t >>= 8;
+    t &= 0xff00ff;
+
+    x = ((x >> 8) & 0xff00ff) * a + ((y >> 8) & 0xff00ff) * b;
+    x &= 0xff00ff00;
+    x |= t;
+    return x;
+}
+
+static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+{
+    int begin_pos, end_pos;
+    xFixed incr, dpos;
+    int pos, current_stop;
+    PictGradientStopPtr stops = pGradient->linear.stops;
+    int nstops = pGradient->linear.nstops;
+
+    /* The position where the gradient begins and ends */
+    begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+    end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
+
+    pos = 0; /* The position in the color table. */
+
+    /* Up to first point */
+    while (pos <= begin_pos) {
+        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
+        ++pos;
+    }
+
+    incr =  (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
+    dpos = incr * pos; /* The position in terms of 0-1. */
+
+    current_stop = 0; /* We always interpolate between current and current + 1. */
+
+    /* Gradient area */
+    while (pos < end_pos) {
+        unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
+        unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+
+        int dist = (int)(256*(dpos - stops[current_stop].x)
+                         / (stops[current_stop+1].x - stops[current_stop].x));
+        int idist = 256 - dist;
+
+        pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+
+        ++pos;
+        dpos += incr;
+
+        if (dpos > stops[current_stop + 1].x)
+            ++current_stop;
+    }
+
+    /* After last point */
+    while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
+        pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
+        ++pos;
+    }
+}
+
+static void initGradient(SourcePictPtr pGradient, int stopCount,
+                         xFixed *stopPoints, xRenderColor *stopColors, int *error)
+{
+    int i;
+    xFixed dpos;
+
+    if (stopCount <= 0) {
+        *error = BadValue;
+        return;
+    }
+
+    dpos = -1;
+    for (i = 0; i < stopCount; ++i) {
+        if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+            *error = BadValue;
+            return;
+        }
+        dpos = stopPoints[i];
+    }
+
+    pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
+    if (!pGradient->linear.stops) {
+        *error = BadAlloc;
+        return;
+    }
+
+    pGradient->linear.nstops = stopCount;
+
+    for (i = 0; i < stopCount; ++i) {
+        pGradient->linear.stops[i].x = stopPoints[i];
+        pGradient->linear.stops[i].color = stopColors[i];
+    }
+    initGradientColorTable(pGradient, error);
+}
+
+static PicturePtr createSourcePicture(void)
+{
+    PicturePtr pPicture;
+    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+    pPicture->pDrawable = 0;
+    pPicture->pFormat = 0;
+    pPicture->pNext = 0;
+
+    SetPictureToDefaults(pPicture);
+    return pPicture;
+}
+
+PicturePtr
+CreateSolidPicture (Picture pid, xRenderColor *color, int *error)
+{
+    PicturePtr pPicture;
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictSolidFill));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+    pPicture->pSourcePict->type = SourcePictTypeSolidFill;
+    pPicture->pSourcePict->solidFill.color = xRenderColorToCard32(*color);
+    return pPicture;
+}
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
+                             int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+    if (p1->x == p2->x && p1->y == p2->y) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+
+    pPicture->pSourcePict->linear.type = SourcePictTypeLinear;
+    pPicture->pSourcePict->linear.p1 = *p1;
+    pPicture->pSourcePict->linear.p2 = *p2;
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+#define FixedToDouble(x) ((x)/65536.)
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer,
+                             xFixed innerRadius, xFixed outerRadius,
+                             int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+    PictRadialGradient *radial;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+    {
+        double dx = (double)(inner->x - outer->x);
+        double dy = (double)(inner->y - outer->y);
+        if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
+            *error = BadValue;
+            return 0;
+        }
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+    radial = &pPicture->pSourcePict->radial;
+
+    radial->type = SourcePictTypeRadial;
+    {
+        double x = (double)innerRadius / (double)outerRadius;
+        radial->dx = (outer->x - inner->x);
+        radial->dy = (outer->y - inner->y);
+        radial->fx = (inner->x) - x*radial->dx;
+        radial->fy = (inner->y) - x*radial->dy;
+        radial->m = 1./(1+x);
+        radial->b = -x*radial->m;
+        radial->dx /= 65536.;
+        radial->dy /= 65536.;
+        radial->fx /= 65536.;
+        radial->fy /= 65536.;
+        x = outerRadius/65536.;
+        radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
+    }
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid, xPointFixed *center, xFixed angle,
+                              int nStops, xFixed *stops, xRenderColor *colors, int *error)
+{
+    PicturePtr pPicture;
+
+    if (nStops < 2) {
+        *error = BadValue;
+        return 0;
+    }
+
+    pPicture = createSourcePicture();
+    if (!pPicture) {
+        *error = BadAlloc;
+        return 0;
+    }
+
+    pPicture->id = pid;
+    pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictConicalGradient));
+    if (!pPicture->pSourcePict) {
+        *error = BadAlloc;
+        xfree(pPicture);
+        return 0;
+    }
+
+    pPicture->pSourcePict->conical.type = SourcePictTypeConical;
+    pPicture->pSourcePict->conical.center = *center;
+    pPicture->pSourcePict->conical.angle = angle;
+
+    initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
+    if (*error) {
+        xfree(pPicture);
+        return 0;
+    }
+    return pPicture;
+}
+
+#define NEXT_VAL(_type) (vlist ? (_type) *vlist++ : (_type) ulist++->val)
+
+#define NEXT_PTR(_type) ((_type) ulist++->ptr)
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client)
+{
+    ScreenPtr pScreen = pPicture->pDrawable ? pPicture->pDrawable->pScreen : 0;
+    PictureScreenPtr ps = pScreen ? GetPictureScreen(pScreen) : 0;
+    BITS32		index2;
+    int			error = 0;
+    BITS32		maskQ;
+    
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    maskQ = vmask;
+    while (vmask && !error)
+    {
+	index2 = (BITS32) lowbit (vmask);
+	vmask &= ~index2;
+	pPicture->stateChanges |= index2;
+	switch (index2)
+	{
+	case CPRepeat:
+	    {
+		unsigned int	newr;
+		newr = NEXT_VAL(unsigned int);
+		if (newr <= RepeatReflect)
+		{
+		    pPicture->repeat = (newr != RepeatNone);
+		    pPicture->repeatType = newr;
+		}
+		else
+		{
+		    client->errorValue = newr;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPAlphaMap:
+	    {
+		PicturePtr  pAlpha;
+		
+		if (vlist)
+		{
+		    Picture	pid = NEXT_VAL(Picture);
+
+		    if (pid == None)
+			pAlpha = 0;
+		    else
+		    {
+			pAlpha = (PicturePtr) SecurityLookupIDByType(client,
+								     pid, 
+								     PictureType, 
+								     SecurityWriteAccess|SecurityReadAccess);
+			if (!pAlpha)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+			if (pAlpha->pDrawable->type != DRAWABLE_PIXMAP)
+			{
+			    client->errorValue = pid;
+			    error = BadMatch;
+			    break;
+			}
+		    }
+		}
+		else
+		    pAlpha = NEXT_PTR(PicturePtr);
+		if (!error)
+		{
+		    if (pAlpha && pAlpha->pDrawable->type == DRAWABLE_PIXMAP)
+			pAlpha->refcnt++;
+		    if (pPicture->alphaMap)
+			FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+		    pPicture->alphaMap = pAlpha;
+		}
+	    }
+	    break;
+	case CPAlphaXOrigin:
+	    pPicture->alphaOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPAlphaYOrigin:
+	    pPicture->alphaOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipXOrigin:
+	    pPicture->clipOrigin.x = NEXT_VAL(INT16);
+	    break;
+	case CPClipYOrigin:
+	    pPicture->clipOrigin.y = NEXT_VAL(INT16);
+	    break;
+	case CPClipMask:
+	    {
+		Pixmap	    pid;
+		PixmapPtr   pPixmap;
+		int	    clipType;
+                if (!pScreen)
+                    return BadDrawable;
+
+		if (vlist)
+		{
+		    pid = NEXT_VAL(Pixmap);
+		    if (pid == None)
+		    {
+			clipType = CT_NONE;
+			pPixmap = NullPixmap;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap = (PixmapPtr)SecurityLookupIDByType(client,
+								    pid, 
+								    RT_PIXMAP,
+								    SecurityReadAccess);
+			if (!pPixmap)
+			{
+			    client->errorValue = pid;
+			    error = BadPixmap;
+			    break;
+			}
+		    }
+		}
+		else
+		{
+		    pPixmap = NEXT_PTR(PixmapPtr);
+		    if (pPixmap)
+			clipType = CT_PIXMAP;
+		    else
+			clipType = CT_NONE;
+		}
+
+		if (pPixmap)
+		{
+		    if ((pPixmap->drawable.depth != 1) ||
+			(pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			break;
+		    }
+		    else
+		    {
+			clipType = CT_PIXMAP;
+			pPixmap->refcnt++;
+		    }
+		}
+		error = (*ps->ChangePictureClip)(pPicture, clipType,
+						 (pointer)pPixmap, 0);
+		break;
+	    }
+	case CPGraphicsExposure:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe <= xTrue)
+		    pPicture->graphicsExposures = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPSubwindowMode:
+	    {
+		unsigned int	news;
+		news = NEXT_VAL(unsigned int);
+		if (news == ClipByChildren || news == IncludeInferiors)
+		    pPicture->subWindowMode = news;
+		else
+		{
+		    client->errorValue = news;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyEdge:
+	    {
+		unsigned int	newe;
+		newe = NEXT_VAL(unsigned int);
+		if (newe == PolyEdgeSharp || newe == PolyEdgeSmooth)
+		    pPicture->polyEdge = newe;
+		else
+		{
+		    client->errorValue = newe;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPPolyMode:
+	    {
+		unsigned int	newm;
+		newm = NEXT_VAL(unsigned int);
+		if (newm == PolyModePrecise || newm == PolyModeImprecise)
+		    pPicture->polyMode = newm;
+		else
+		{
+		    client->errorValue = newm;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	case CPDither:
+	    pPicture->dither = NEXT_VAL(Atom);
+	    break;
+	case CPComponentAlpha:
+	    {
+		unsigned int	newca;
+
+		newca = NEXT_VAL (unsigned int);
+		if (newca <= xTrue)
+		    pPicture->componentAlpha = newca;
+		else
+		{
+		    client->errorValue = newca;
+		    error = BadValue;
+		}
+	    }
+	    break;
+	default:
+	    client->errorValue = maskQ;
+	    error = BadValue;
+	    break;
+	}
+    }
+    if (ps)
+        (*ps->ChangePicture) (pPicture, maskQ);
+    return error;
+}
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr	ps = GetPictureScreen(pScreen);
+    RegionPtr		clientClip;
+    int			result;
+
+    clientClip = RECTS_TO_REGION(pScreen,
+				 nRect, rects, CT_UNSORTED);
+    if (!clientClip)
+	return BadAlloc;
+    result =(*ps->ChangePictureClip) (pPicture, CT_REGION, 
+				      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+	pPicture->clipOrigin.x = xOrigin;
+	pPicture->clipOrigin.y = yOrigin;
+	pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+	pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+int
+SetPictureClipRegion (PicturePtr    pPicture,
+                      int           xOrigin,
+                      int           yOrigin,
+                      RegionPtr     pRegion)
+{
+    ScreenPtr           pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    RegionPtr           clientClip;
+    int                 result;
+    int                 type;
+
+    if (pRegion)
+    {
+        type = CT_REGION;
+        clientClip = REGION_CREATE (pScreen,
+                                    REGION_EXTENTS(pScreen, pRegion),
+                                    REGION_NUM_RECTS(pRegion));
+        if (!clientClip)
+            return BadAlloc;
+        if (!REGION_COPY (pSCreen, clientClip, pRegion))
+        {
+            REGION_DESTROY (pScreen, clientClip);
+            return BadAlloc;
+        }
+    }
+    else
+    {
+        type = CT_NONE;
+        clientClip = 0;
+    }
+
+    result =(*ps->ChangePictureClip) (pPicture, type,
+                                      (pointer) clientClip, 0);
+    if (result == Success)
+    {
+        pPicture->clipOrigin.x = xOrigin;
+        pPicture->clipOrigin.y = yOrigin;
+        pPicture->stateChanges |= CPClipXOrigin|CPClipYOrigin|CPClipMask;
+        pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    }
+    return result;
+}
+
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform)
+{
+    static const PictTransform	identity = { {
+	{ xFixed1, 0x00000, 0x00000 },
+	{ 0x00000, xFixed1, 0x00000 },
+	{ 0x00000, 0x00000, xFixed1 },
+    } };
+
+    if (transform && memcmp (transform, &identity, sizeof (PictTransform)) == 0)
+	transform = 0;
+    
+    if (transform)
+    {
+	if (!pPicture->transform)
+	{
+	    pPicture->transform = (PictTransform *) xalloc (sizeof (PictTransform));
+	    if (!pPicture->transform)
+		return BadAlloc;
+	}
+	*pPicture->transform = *transform;
+    }
+    else
+    {
+	if (pPicture->transform)
+	{
+	    xfree (pPicture->transform);
+	    pPicture->transform = 0;
+	}
+    }
+    pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+    return Success;
+}
+
+void
+CopyPicture (PicturePtr	pSrc,
+	     Mask	mask,
+	     PicturePtr	pDst)
+{
+    PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
+    Mask origMask = mask;
+
+    pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+    pDst->stateChanges |= mask;
+
+    while (mask) {
+	Mask bit = lowbit(mask);
+
+	switch (bit)
+	{
+	case CPRepeat:
+	    pDst->repeat = pSrc->repeat;
+	    pDst->repeatType = pSrc->repeatType;
+	    break;
+	case CPAlphaMap:
+	    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable->type == DRAWABLE_PIXMAP)
+		pSrc->alphaMap->refcnt++;
+	    if (pDst->alphaMap)
+		FreePicture ((pointer) pDst->alphaMap, (XID) 0);
+	    pDst->alphaMap = pSrc->alphaMap;
+	    break;
+	case CPAlphaXOrigin:
+	    pDst->alphaOrigin.x = pSrc->alphaOrigin.x;
+	    break;
+	case CPAlphaYOrigin:
+	    pDst->alphaOrigin.y = pSrc->alphaOrigin.y;
+	    break;
+	case CPClipXOrigin:
+	    pDst->clipOrigin.x = pSrc->clipOrigin.x;
+	    break;
+	case CPClipYOrigin:
+	    pDst->clipOrigin.y = pSrc->clipOrigin.y;
+	    break;
+	case CPClipMask:
+	    switch (pSrc->clientClipType) {
+	    case CT_NONE:
+		(*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+		break;
+	    case CT_REGION:
+		if (!pSrc->clientClip) {
+		    (*ps->ChangePictureClip)(pDst, CT_NONE, NULL, 0);
+		} else {
+		    RegionPtr clientClip;
+		    RegionPtr srcClientClip = (RegionPtr)pSrc->clientClip;
+
+		    clientClip = REGION_CREATE(pSrc->pDrawable->pScreen,
+			REGION_EXTENTS(pSrc->pDrawable->pScreen, srcClientClip),
+			REGION_NUM_RECTS(srcClientClip));
+		    (*ps->ChangePictureClip)(pDst, CT_REGION, clientClip, 0);
+		}
+		break;
+	    default:
+		/* XXX: CT_PIXMAP unimplemented */
+		break;
+	    }
+	    break;
+	case CPGraphicsExposure:
+	    pDst->graphicsExposures = pSrc->graphicsExposures;
+	    break;
+	case CPPolyEdge:
+	    pDst->polyEdge = pSrc->polyEdge;
+	    break;
+	case CPPolyMode:
+	    pDst->polyMode = pSrc->polyMode;
+	    break;
+	case CPDither:
+	    pDst->dither = pSrc->dither;
+	    break;
+	case CPComponentAlpha:
+	    pDst->componentAlpha = pSrc->componentAlpha;
+	    break;
+	}
+	mask &= ~bit;
+    }
+
+    (*ps->ChangePicture)(pDst, origMask);
+}
+
+static void
+ValidateOnePicture (PicturePtr pPicture)
+{
+    if (pPicture->pDrawable && pPicture->serialNumber != pPicture->pDrawable->serialNumber)
+    {
+	PictureScreenPtr    ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+
+	(*ps->ValidatePicture) (pPicture, pPicture->stateChanges);
+	pPicture->stateChanges = 0;
+	pPicture->serialNumber = pPicture->pDrawable->serialNumber;
+    }
+}
+
+void
+ValidatePicture(PicturePtr pPicture)
+{
+    ValidateOnePicture (pPicture);
+    if (pPicture->alphaMap)
+	ValidateOnePicture (pPicture->alphaMap);
+}
+
+int
+FreePicture (pointer	value,
+	     XID	pid)
+{
+    PicturePtr	pPicture = (PicturePtr) value;
+
+    if (--pPicture->refcnt == 0)
+    {
+	if (pPicture->transform)
+	    xfree (pPicture->transform);
+        if (!pPicture->pDrawable) {
+            if (pPicture->pSourcePict) {
+                if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+                    xfree(pPicture->pSourcePict->linear.stops);
+                xfree(pPicture->pSourcePict);
+            }
+        } else {
+            ScreenPtr	    pScreen = pPicture->pDrawable->pScreen;
+            PictureScreenPtr    ps = GetPictureScreen(pScreen);
+	
+            if (pPicture->alphaMap)
+                FreePicture ((pointer) pPicture->alphaMap, (XID) 0);
+            (*ps->DestroyPicture) (pPicture);
+            (*ps->DestroyPictureClip) (pPicture);
+            if (pPicture->pDrawable->type == DRAWABLE_WINDOW)
+            {
+                WindowPtr	pWindow = (WindowPtr) pPicture->pDrawable;
+                PicturePtr	*pPrev;
+
+                for (pPrev = (PicturePtr *) &((pWindow)->devPrivates[PictureWindowPrivateIndex].ptr);
+                     *pPrev;
+                     pPrev = &(*pPrev)->pNext)
+                {
+                    if (*pPrev == pPicture)
+                    {
+                        *pPrev = pPicture->pNext;
+                        break;
+                    }
+                }
+            }
+            else if (pPicture->pDrawable->type == DRAWABLE_PIXMAP)
+            {
+                (*pScreen->DestroyPixmap) ((PixmapPtr)pPicture->pDrawable);
+            }
+        }
+	xfree (pPicture);
+    }
+    return Success;
+}
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid)
+{
+    return Success;
+}
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    if (pMask)
+	ValidatePicture (pMask);
+    ValidatePicture (pDst);
+    (*ps->Composite) (op,
+		       pSrc,
+		       pMask,
+		       pDst,
+		       xSrc,
+		       ySrc,
+		       xMask,
+		       yMask,
+		       xDst,
+		       yDst,
+		       width,
+		       height);
+}
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs);
+}
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pDst);
+    (*ps->CompositeRects) (op, pDst, color, nRect, rects);
+}
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Trapezoids) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, traps);
+}
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntriangles, triangles);
+}
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    
+    ValidatePicture (pSrc);
+    ValidatePicture (pDst);
+    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+}
+
+void
+AddTraps (PicturePtr	pPicture,
+	  INT16		xOff,
+	  INT16		yOff,
+	  int		ntrap,
+	  xTrap		*traps)
+{
+    PictureScreenPtr	ps = GetPictureScreen(pPicture->pDrawable->pScreen);
+    
+    ValidatePicture (pPicture);
+    (*ps->AddTraps) (pPicture, xOff, yOff, ntrap, traps);
+}
+
+#define MAX_FIXED_48_16	    ((xFixed_48_16) 0x7fffffff)
+#define MIN_FIXED_48_16	    (-((xFixed_48_16) 1 << 31))
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+                         PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] *
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    *vector = result;
+    return TRUE;
+}
+
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector)
+{
+    PictVector	    result;
+    int		    i, j;
+    xFixed_32_32    partial;
+    xFixed_48_16    v;
+
+    for (j = 0; j < 3; j++)
+    {
+	v = 0;
+	for (i = 0; i < 3; i++)
+	{
+	    partial = ((xFixed_48_16) transform->matrix[j][i] * 
+		       (xFixed_48_16) vector->vector[i]);
+	    v += partial >> 16;
+	}
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	result.vector[j] = (xFixed) v;
+    }
+    if (!result.vector[2])
+	return FALSE;
+    for (j = 0; j < 2; j++)
+    {
+	partial = (xFixed_48_16) result.vector[j] << 16;
+	v = partial / result.vector[2];
+	if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
+	    return FALSE;
+	vector->vector[j] = (xFixed) v;
+    }
+    vector->vector[2] = xFixed1;
+    return TRUE;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
new file mode 100644
index 000000000..255411a9b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
@@ -0,0 +1,678 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original
+ * picturestr.h or symbols  will be redefined. We
+ * should define a new types and cast when appro-
+ * priate.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "NXglyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+    CARD16	    red, redMask;
+    CARD16	    green, greenMask;
+    CARD16	    blue, blueMask;
+    CARD16	    alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+    VisualID	    vid;
+    ColormapPtr	    pColormap;
+    int		    nvalues;
+    xIndexValue	    *pValues;
+    void	    *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+    CARD32	    id;
+    CARD32	    format;	    /* except bpp */
+    unsigned char   type;
+    unsigned char   depth;
+    DirectFormatRec direct;
+    IndexFormatRec  index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+    xFixed	    vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+    xFixed	    matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+#define PICT_GRADIENT_STOPTABLE_SIZE 1024
+#define SourcePictTypeSolidFill 0
+#define SourcePictTypeLinear 1
+#define SourcePictTypeRadial 2
+#define SourcePictTypeConical 3
+
+typedef struct _PictSolidFill {
+    unsigned int type;
+    CARD32 color;
+} PictSolidFill, *PictSolidFillPtr;
+
+typedef struct _PictGradientStop {
+    xFixed x;
+    xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
+
+typedef struct _PictGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+} PictGradient, *PictGradientPtr;
+
+typedef struct _PictLinearGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    xPointFixed p1;
+    xPointFixed p2;
+} PictLinearGradient, *PictLinearGradientPtr;
+
+typedef struct _PictRadialGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    double fx;
+    double fy;
+    double dx;
+    double dy;
+    double a;
+    double m;
+    double b;
+} PictRadialGradient, *PictRadialGradientPtr;
+
+typedef struct _PictConicalGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    xPointFixed center;
+    xFixed angle;
+} PictConicalGradient, *PictConicalGradientPtr;
+
+typedef union _SourcePict {
+    unsigned int type;
+    PictSolidFill solidFill;
+    PictGradient gradient;
+    PictLinearGradient linear;
+    PictRadialGradient radial;
+    PictConicalGradient conical;
+} SourcePict, *SourcePictPtr;
+
+typedef struct _Picture {
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    CARD32	    format;	    /* PICT_FORMAT */
+    int		    refcnt;
+    CARD32	    id;
+    PicturePtr	    pNext;	    /* chain on same drawable */
+
+    unsigned int    repeat : 1;
+    unsigned int    graphicsExposures : 1;
+    unsigned int    subWindowMode : 1;
+    unsigned int    polyEdge : 1;
+    unsigned int    polyMode : 1;
+    unsigned int    freeCompClip : 1;
+    unsigned int    clientClipType : 2;
+    unsigned int    componentAlpha : 1;
+    unsigned int    repeatType : 2;
+    unsigned int    unused : 21;
+
+    PicturePtr	    alphaMap;
+    DDXPointRec	    alphaOrigin;
+
+    DDXPointRec	    clipOrigin;
+    pointer	    clientClip;
+
+    Atom	    dither;
+
+    unsigned long   stateChanges;
+    unsigned long   serialNumber;
+
+    RegionPtr	    pCompositeClip;
+
+    DevUnion	    *devPrivates;
+
+    PictTransform   *transform;
+
+    int		    filter;
+    xFixed	    *filter_params;
+    int		    filter_nparams;
+    SourcePictPtr   pSourcePict;
+} PictureRec;
+
+typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+						 xFixed *params, int nparams);
+typedef struct {
+    char			    *name;
+    int				    id;
+    PictFilterValidateParamsProcPtr ValidateParams;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest	0
+#define PictFilterBilinear	1
+
+#define PictFilterFast		2
+#define PictFilterGood		3
+#define PictFilterBest		4
+
+#define PictFilterConvolution	5
+
+typedef struct {
+    char	    *alias;
+    int		    alias_id;
+    int		    filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int	(*CreatePictureProcPtr)	    (PicturePtr pPicture);
+typedef void	(*DestroyPictureProcPtr)    (PicturePtr pPicture);
+typedef int	(*ChangePictureClipProcPtr) (PicturePtr	pPicture,
+					     int	clipType,
+					     pointer    value,
+					     int	n);
+typedef void	(*DestroyPictureClipProcPtr)(PicturePtr	pPicture);
+
+typedef int	(*ChangePictureTransformProcPtr)    (PicturePtr	    pPicture,
+						     PictTransform  *transform);
+
+typedef int	(*ChangePictureFilterProcPtr)	(PicturePtr	pPicture,
+						 int		filter,
+						 xFixed		*params,
+						 int		nparams);
+
+typedef void	(*DestroyPictureFilterProcPtr)	(PicturePtr pPicture);
+
+typedef void	(*ChangePictureProcPtr)	    (PicturePtr pPicture,
+					     Mask	mask);
+typedef void	(*ValidatePictureProcPtr)    (PicturePtr pPicture,
+					     Mask       mask);
+typedef void	(*CompositeProcPtr)	    (CARD8	op,
+					     PicturePtr pSrc,
+					     PicturePtr pMask,
+					     PicturePtr pDst,
+					     INT16	xSrc,
+					     INT16	ySrc,
+					     INT16	xMask,
+					     INT16	yMask,
+					     INT16	xDst,
+					     INT16	yDst,
+					     CARD16	width,
+					     CARD16	height);
+
+typedef void	(*GlyphsProcPtr)	    (CARD8      op,
+					     PicturePtr pSrc,
+					     PicturePtr pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16      xSrc,
+					     INT16      ySrc,
+					     int	nlists,
+					     GlyphListPtr   lists,
+					     GlyphPtr	*glyphs);
+
+typedef void	(*CompositeRectsProcPtr)    (CARD8	    op,
+					     PicturePtr	    pDst,
+					     xRenderColor   *color,
+					     int	    nRect,
+					     xRectangle	    *rects);
+
+typedef void	(*RasterizeTrapezoidProcPtr)(PicturePtr	    pMask,
+					     xTrapezoid	    *trap,
+					     int	    x_off,
+					     int	    y_off);
+
+typedef void	(*TrapezoidsProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntrap,
+					     xTrapezoid	    *traps);
+
+typedef void	(*TrianglesProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef void	(*TriStripProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef void	(*TriFanProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef Bool	(*InitIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*CloseIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*UpdateIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat,
+					     int	    ndef,
+					     xColorItem	    *pdef);
+
+typedef void	(*AddTrapsProcPtr)	    (PicturePtr	    pPicture,
+					     INT16	    xOff,
+					     INT16	    yOff,
+					     int	    ntrap,
+					     xTrap	    *traps);
+
+typedef void	(*AddTrianglesProcPtr)	    (PicturePtr	    pPicture,
+					     INT16	    xOff,
+					     INT16	    yOff,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef struct _PictureScreen {
+    int				totalPictureSize;
+    unsigned int		*PicturePrivateSizes;
+    int				PicturePrivateLen;
+
+    PictFormatPtr		formats;
+    PictFormatPtr		fallback;
+    int				nformats;
+
+    CreatePictureProcPtr	CreatePicture;
+    DestroyPictureProcPtr	DestroyPicture;
+    ChangePictureClipProcPtr	ChangePictureClip;
+    DestroyPictureClipProcPtr	DestroyPictureClip;
+
+    ChangePictureProcPtr	ChangePicture;
+    ValidatePictureProcPtr	ValidatePicture;
+
+    CompositeProcPtr		Composite;
+    GlyphsProcPtr		Glyphs;
+    CompositeRectsProcPtr	CompositeRects;
+
+    DestroyWindowProcPtr	DestroyWindow;
+    CloseScreenProcPtr		CloseScreen;
+
+    StoreColorsProcPtr		StoreColors;
+
+    InitIndexedProcPtr		InitIndexed;
+    CloseIndexedProcPtr		CloseIndexed;
+    UpdateIndexedProcPtr	UpdateIndexed;
+
+    int				subpixel;
+
+    PictFilterPtr		filters;
+    int				nfilters;
+    PictFilterAliasPtr		filterAliases;
+    int				nfilterAliases;
+
+    ChangePictureTransformProcPtr   ChangePictureTransform;
+    ChangePictureFilterProcPtr	ChangePictureFilter;
+    DestroyPictureFilterProcPtr	DestroyPictureFilter;
+
+    TrapezoidsProcPtr		Trapezoids;
+    TrianglesProcPtr		Triangles;
+    TriStripProcPtr		TriStrip;
+    TriFanProcPtr		TriFan;
+
+    RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
+
+    AddTrianglesProcPtr		AddTriangles;
+
+    AddTrapsProcPtr		AddTraps;
+
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int		PictureScreenPrivateIndex;
+extern int		PictureWindowPrivateIndex;
+extern RESTYPE		PictureType;
+extern RESTYPE		PictFormatType;
+extern RESTYPE		GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr			    pScreen,
+		  char				    *filter,
+		  PictFilterValidateParamsProcPtr   ValidateParams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		mask,
+	       XID		*list,
+	       ClientPtr	client,
+	       int		*error);
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client);
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects);
+
+int
+SetPictureClipRegion (PicturePtr    pPicture,
+		      int	    xOrigin,
+		      int	    yOrigin,
+		      RegionPtr	    pRegion);
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform);
+
+void
+CopyPicture (PicturePtr	pSrc,
+	     Mask	mask,
+	     PicturePtr	pDst);
+
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer	pPicture,
+	     XID	pid);
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid);
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height);
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs);
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects);
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps);
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles);
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points);
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector);
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+                         PictVectorPtr	vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+void
+AddTraps (PicturePtr	pPicture,
+	  INT16		xOff,
+	  INT16		yOff,
+	  int		ntraps,
+	  xTrap		*traps);
+
+PicturePtr
+CreateSolidPicture (Picture pid,
+                    xRenderColor *color,
+                    int *error);
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid,
+                             xPointFixed *p1,
+                             xPointFixed *p2,
+                             int nStops,
+                             xFixed *stops,
+                             xRenderColor *colors,
+                             int *error);
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid,
+                             xPointFixed *inner,
+                             xPointFixed *outer,
+                             xFixed innerRadius,
+                             xFixed outerRadius,
+                             int nStops,
+                             xFixed *stops,
+                             xRenderColor *colors,
+                             int *error);
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid,
+                              xPointFixed *center,
+                              xFixed angle,
+                              int nStops,
+                              xFixed *stops,
+                              xRenderColor *colors,
+                              int *error);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
new file mode 100644
index 000000000..255411a9b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
@@ -0,0 +1,678 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/*
+ * This must keep the same symbol as the original
+ * picturestr.h or symbols  will be redefined. We
+ * should define a new types and cast when appro-
+ * priate.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "NXglyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+    CARD16	    red, redMask;
+    CARD16	    green, greenMask;
+    CARD16	    blue, blueMask;
+    CARD16	    alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+    VisualID	    vid;
+    ColormapPtr	    pColormap;
+    int		    nvalues;
+    xIndexValue	    *pValues;
+    void	    *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+    CARD32	    id;
+    CARD32	    format;	    /* except bpp */
+    unsigned char   type;
+    unsigned char   depth;
+    DirectFormatRec direct;
+    IndexFormatRec  index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+    xFixed	    vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+    xFixed	    matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+#define PICT_GRADIENT_STOPTABLE_SIZE 1024
+#define SourcePictTypeSolidFill 0
+#define SourcePictTypeLinear 1
+#define SourcePictTypeRadial 2
+#define SourcePictTypeConical 3
+
+typedef struct _PictSolidFill {
+    unsigned int type;
+    CARD32 color;
+} PictSolidFill, *PictSolidFillPtr;
+
+typedef struct _PictGradientStop {
+    xFixed x;
+    xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
+
+typedef struct _PictGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+} PictGradient, *PictGradientPtr;
+
+typedef struct _PictLinearGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    xPointFixed p1;
+    xPointFixed p2;
+} PictLinearGradient, *PictLinearGradientPtr;
+
+typedef struct _PictRadialGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    double fx;
+    double fy;
+    double dx;
+    double dy;
+    double a;
+    double m;
+    double b;
+} PictRadialGradient, *PictRadialGradientPtr;
+
+typedef struct _PictConicalGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    xPointFixed center;
+    xFixed angle;
+} PictConicalGradient, *PictConicalGradientPtr;
+
+typedef union _SourcePict {
+    unsigned int type;
+    PictSolidFill solidFill;
+    PictGradient gradient;
+    PictLinearGradient linear;
+    PictRadialGradient radial;
+    PictConicalGradient conical;
+} SourcePict, *SourcePictPtr;
+
+typedef struct _Picture {
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    CARD32	    format;	    /* PICT_FORMAT */
+    int		    refcnt;
+    CARD32	    id;
+    PicturePtr	    pNext;	    /* chain on same drawable */
+
+    unsigned int    repeat : 1;
+    unsigned int    graphicsExposures : 1;
+    unsigned int    subWindowMode : 1;
+    unsigned int    polyEdge : 1;
+    unsigned int    polyMode : 1;
+    unsigned int    freeCompClip : 1;
+    unsigned int    clientClipType : 2;
+    unsigned int    componentAlpha : 1;
+    unsigned int    repeatType : 2;
+    unsigned int    unused : 21;
+
+    PicturePtr	    alphaMap;
+    DDXPointRec	    alphaOrigin;
+
+    DDXPointRec	    clipOrigin;
+    pointer	    clientClip;
+
+    Atom	    dither;
+
+    unsigned long   stateChanges;
+    unsigned long   serialNumber;
+
+    RegionPtr	    pCompositeClip;
+
+    DevUnion	    *devPrivates;
+
+    PictTransform   *transform;
+
+    int		    filter;
+    xFixed	    *filter_params;
+    int		    filter_nparams;
+    SourcePictPtr   pSourcePict;
+} PictureRec;
+
+typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+						 xFixed *params, int nparams);
+typedef struct {
+    char			    *name;
+    int				    id;
+    PictFilterValidateParamsProcPtr ValidateParams;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest	0
+#define PictFilterBilinear	1
+
+#define PictFilterFast		2
+#define PictFilterGood		3
+#define PictFilterBest		4
+
+#define PictFilterConvolution	5
+
+typedef struct {
+    char	    *alias;
+    int		    alias_id;
+    int		    filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int	(*CreatePictureProcPtr)	    (PicturePtr pPicture);
+typedef void	(*DestroyPictureProcPtr)    (PicturePtr pPicture);
+typedef int	(*ChangePictureClipProcPtr) (PicturePtr	pPicture,
+					     int	clipType,
+					     pointer    value,
+					     int	n);
+typedef void	(*DestroyPictureClipProcPtr)(PicturePtr	pPicture);
+
+typedef int	(*ChangePictureTransformProcPtr)    (PicturePtr	    pPicture,
+						     PictTransform  *transform);
+
+typedef int	(*ChangePictureFilterProcPtr)	(PicturePtr	pPicture,
+						 int		filter,
+						 xFixed		*params,
+						 int		nparams);
+
+typedef void	(*DestroyPictureFilterProcPtr)	(PicturePtr pPicture);
+
+typedef void	(*ChangePictureProcPtr)	    (PicturePtr pPicture,
+					     Mask	mask);
+typedef void	(*ValidatePictureProcPtr)    (PicturePtr pPicture,
+					     Mask       mask);
+typedef void	(*CompositeProcPtr)	    (CARD8	op,
+					     PicturePtr pSrc,
+					     PicturePtr pMask,
+					     PicturePtr pDst,
+					     INT16	xSrc,
+					     INT16	ySrc,
+					     INT16	xMask,
+					     INT16	yMask,
+					     INT16	xDst,
+					     INT16	yDst,
+					     CARD16	width,
+					     CARD16	height);
+
+typedef void	(*GlyphsProcPtr)	    (CARD8      op,
+					     PicturePtr pSrc,
+					     PicturePtr pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16      xSrc,
+					     INT16      ySrc,
+					     int	nlists,
+					     GlyphListPtr   lists,
+					     GlyphPtr	*glyphs);
+
+typedef void	(*CompositeRectsProcPtr)    (CARD8	    op,
+					     PicturePtr	    pDst,
+					     xRenderColor   *color,
+					     int	    nRect,
+					     xRectangle	    *rects);
+
+typedef void	(*RasterizeTrapezoidProcPtr)(PicturePtr	    pMask,
+					     xTrapezoid	    *trap,
+					     int	    x_off,
+					     int	    y_off);
+
+typedef void	(*TrapezoidsProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntrap,
+					     xTrapezoid	    *traps);
+
+typedef void	(*TrianglesProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef void	(*TriStripProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef void	(*TriFanProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef Bool	(*InitIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*CloseIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*UpdateIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat,
+					     int	    ndef,
+					     xColorItem	    *pdef);
+
+typedef void	(*AddTrapsProcPtr)	    (PicturePtr	    pPicture,
+					     INT16	    xOff,
+					     INT16	    yOff,
+					     int	    ntrap,
+					     xTrap	    *traps);
+
+typedef void	(*AddTrianglesProcPtr)	    (PicturePtr	    pPicture,
+					     INT16	    xOff,
+					     INT16	    yOff,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef struct _PictureScreen {
+    int				totalPictureSize;
+    unsigned int		*PicturePrivateSizes;
+    int				PicturePrivateLen;
+
+    PictFormatPtr		formats;
+    PictFormatPtr		fallback;
+    int				nformats;
+
+    CreatePictureProcPtr	CreatePicture;
+    DestroyPictureProcPtr	DestroyPicture;
+    ChangePictureClipProcPtr	ChangePictureClip;
+    DestroyPictureClipProcPtr	DestroyPictureClip;
+
+    ChangePictureProcPtr	ChangePicture;
+    ValidatePictureProcPtr	ValidatePicture;
+
+    CompositeProcPtr		Composite;
+    GlyphsProcPtr		Glyphs;
+    CompositeRectsProcPtr	CompositeRects;
+
+    DestroyWindowProcPtr	DestroyWindow;
+    CloseScreenProcPtr		CloseScreen;
+
+    StoreColorsProcPtr		StoreColors;
+
+    InitIndexedProcPtr		InitIndexed;
+    CloseIndexedProcPtr		CloseIndexed;
+    UpdateIndexedProcPtr	UpdateIndexed;
+
+    int				subpixel;
+
+    PictFilterPtr		filters;
+    int				nfilters;
+    PictFilterAliasPtr		filterAliases;
+    int				nfilterAliases;
+
+    ChangePictureTransformProcPtr   ChangePictureTransform;
+    ChangePictureFilterProcPtr	ChangePictureFilter;
+    DestroyPictureFilterProcPtr	DestroyPictureFilter;
+
+    TrapezoidsProcPtr		Trapezoids;
+    TrianglesProcPtr		Triangles;
+    TriStripProcPtr		TriStrip;
+    TriFanProcPtr		TriFan;
+
+    RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
+
+    AddTrianglesProcPtr		AddTriangles;
+
+    AddTrapsProcPtr		AddTraps;
+
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int		PictureScreenPrivateIndex;
+extern int		PictureWindowPrivateIndex;
+extern RESTYPE		PictureType;
+extern RESTYPE		PictFormatType;
+extern RESTYPE		GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr			    pScreen,
+		  char				    *filter,
+		  PictFilterValidateParamsProcPtr   ValidateParams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		mask,
+	       XID		*list,
+	       ClientPtr	client,
+	       int		*error);
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client);
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects);
+
+int
+SetPictureClipRegion (PicturePtr    pPicture,
+		      int	    xOrigin,
+		      int	    yOrigin,
+		      RegionPtr	    pRegion);
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform);
+
+void
+CopyPicture (PicturePtr	pSrc,
+	     Mask	mask,
+	     PicturePtr	pDst);
+
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer	pPicture,
+	     XID	pid);
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid);
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height);
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs);
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects);
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps);
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles);
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points);
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector);
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+                         PictVectorPtr	vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+void
+AddTraps (PicturePtr	pPicture,
+	  INT16		xOff,
+	  INT16		yOff,
+	  int		ntraps,
+	  xTrap		*traps);
+
+PicturePtr
+CreateSolidPicture (Picture pid,
+                    xRenderColor *color,
+                    int *error);
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid,
+                             xPointFixed *p1,
+                             xPointFixed *p2,
+                             int nStops,
+                             xFixed *stops,
+                             xRenderColor *colors,
+                             int *error);
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid,
+                             xPointFixed *inner,
+                             xPointFixed *outer,
+                             xFixed innerRadius,
+                             xFixed outerRadius,
+                             int nStops,
+                             xFixed *stops,
+                             xRenderColor *colors,
+                             int *error);
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid,
+                              xPointFixed *center,
+                              xFixed angle,
+                              int nStops,
+                              xFixed *stops,
+                              xRenderColor *colors,
+                              int *error);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original
new file mode 100644
index 000000000..4775793ab
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.X.original
@@ -0,0 +1,654 @@
+/*
+ * $Id: picturestr.h,v 1.15 2005/12/09 18:35:21 ajax Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _PICTURESTR_H_
+#define _PICTURESTR_H_
+
+#include "glyphstr.h"
+#include "scrnintstr.h"
+#include "resource.h"
+
+typedef struct _DirectFormat {
+    CARD16	    red, redMask;
+    CARD16	    green, greenMask;
+    CARD16	    blue, blueMask;
+    CARD16	    alpha, alphaMask;
+} DirectFormatRec;
+
+typedef struct _IndexFormat {
+    VisualID	    vid;
+    ColormapPtr	    pColormap;
+    int		    nvalues;
+    xIndexValue	    *pValues;
+    void	    *devPrivate;
+} IndexFormatRec;
+
+typedef struct _PictFormat {
+    CARD32	    id;
+    CARD32	    format;	    /* except bpp */
+    unsigned char   type;
+    unsigned char   depth;
+    DirectFormatRec direct;
+    IndexFormatRec  index;
+} PictFormatRec;
+
+typedef struct _PictVector {
+    xFixed	    vector[3];
+} PictVector, *PictVectorPtr;
+
+typedef struct _PictTransform {
+    xFixed	    matrix[3][3];
+} PictTransform, *PictTransformPtr;
+
+#define PICT_GRADIENT_STOPTABLE_SIZE 1024
+#define SourcePictTypeSolidFill 0
+#define SourcePictTypeLinear 1
+#define SourcePictTypeRadial 2
+#define SourcePictTypeConical 3
+
+typedef struct _PictSolidFill {
+    unsigned int type;
+    CARD32 color;
+} PictSolidFill, *PictSolidFillPtr;
+
+typedef struct _PictGradientStop {
+    xFixed x;
+    xRenderColor color;
+} PictGradientStop, *PictGradientStopPtr;
+
+typedef struct _PictGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+} PictGradient, *PictGradientPtr;
+
+typedef struct _PictLinearGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    xPointFixed p1;
+    xPointFixed p2;
+} PictLinearGradient, *PictLinearGradientPtr;
+
+typedef struct _PictRadialGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    double fx;
+    double fy;
+    double dx;
+    double dy;
+    double a;
+    double m;
+    double b;
+} PictRadialGradient, *PictRadialGradientPtr;
+
+typedef struct _PictConicalGradient {
+    unsigned int type;
+    int nstops;
+    PictGradientStopPtr stops;
+    CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+    xPointFixed center;
+    xFixed angle;
+} PictConicalGradient, *PictConicalGradientPtr;
+
+typedef union _SourcePict {
+    unsigned int type;
+    PictSolidFill solidFill;
+    PictGradient gradient;
+    PictLinearGradient linear;
+    PictRadialGradient radial;
+    PictConicalGradient conical;
+} SourcePict, *SourcePictPtr;
+
+typedef struct _Picture {
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    CARD32	    format;	    /* PICT_FORMAT */
+    int		    refcnt;
+    CARD32	    id;
+    PicturePtr	    pNext;	    /* chain on same drawable */
+
+    unsigned int    repeat : 1;
+    unsigned int    graphicsExposures : 1;
+    unsigned int    subWindowMode : 1;
+    unsigned int    polyEdge : 1;
+    unsigned int    polyMode : 1;
+    unsigned int    freeCompClip : 1;
+    unsigned int    clientClipType : 2;
+    unsigned int    componentAlpha : 1;
+    unsigned int    repeatType : 2;
+    unsigned int    unused : 21;
+
+    PicturePtr	    alphaMap;
+    DDXPointRec	    alphaOrigin;
+
+    DDXPointRec	    clipOrigin;
+    pointer	    clientClip;
+
+    Atom	    dither;
+
+    unsigned long   stateChanges;
+    unsigned long   serialNumber;
+
+    RegionPtr	    pCompositeClip;
+
+    DevUnion	    *devPrivates;
+
+    PictTransform   *transform;
+
+    int		    filter;
+    xFixed	    *filter_params;
+    int		    filter_nparams;
+    SourcePictPtr   pSourcePict;
+} PictureRec;
+
+typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+						 xFixed *params, int nparams);
+typedef struct {
+    char			    *name;
+    int				    id;
+    PictFilterValidateParamsProcPtr ValidateParams;
+} PictFilterRec, *PictFilterPtr;
+
+#define PictFilterNearest	0
+#define PictFilterBilinear	1
+
+#define PictFilterFast		2
+#define PictFilterGood		3
+#define PictFilterBest		4
+
+#define PictFilterConvolution	5
+
+typedef struct {
+    char	    *alias;
+    int		    alias_id;
+    int		    filter_id;
+} PictFilterAliasRec, *PictFilterAliasPtr;
+
+typedef int	(*CreatePictureProcPtr)	    (PicturePtr pPicture);
+typedef void	(*DestroyPictureProcPtr)    (PicturePtr pPicture);
+typedef int	(*ChangePictureClipProcPtr) (PicturePtr	pPicture,
+					     int	clipType,
+					     pointer    value,
+					     int	n);
+typedef void	(*DestroyPictureClipProcPtr)(PicturePtr	pPicture);
+
+typedef int	(*ChangePictureTransformProcPtr)    (PicturePtr	    pPicture,
+						     PictTransform  *transform);
+
+typedef int	(*ChangePictureFilterProcPtr)	(PicturePtr	pPicture,
+						 int		filter,
+						 xFixed		*params,
+						 int		nparams);
+
+typedef void	(*DestroyPictureFilterProcPtr)	(PicturePtr pPicture);
+
+typedef void	(*ChangePictureProcPtr)	    (PicturePtr pPicture,
+					     Mask	mask);
+typedef void	(*ValidatePictureProcPtr)    (PicturePtr pPicture,
+					     Mask       mask);
+typedef void	(*CompositeProcPtr)	    (CARD8	op,
+					     PicturePtr pSrc,
+					     PicturePtr pMask,
+					     PicturePtr pDst,
+					     INT16	xSrc,
+					     INT16	ySrc,
+					     INT16	xMask,
+					     INT16	yMask,
+					     INT16	xDst,
+					     INT16	yDst,
+					     CARD16	width,
+					     CARD16	height);
+
+typedef void	(*GlyphsProcPtr)	    (CARD8      op,
+					     PicturePtr pSrc,
+					     PicturePtr pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16      xSrc,
+					     INT16      ySrc,
+					     int	nlists,
+					     GlyphListPtr   lists,
+					     GlyphPtr	*glyphs);
+
+typedef void	(*CompositeRectsProcPtr)    (CARD8	    op,
+					     PicturePtr	    pDst,
+					     xRenderColor   *color,
+					     int	    nRect,
+					     xRectangle	    *rects);
+
+typedef void	(*RasterizeTrapezoidProcPtr)(PicturePtr	    pMask,
+					     xTrapezoid	    *trap,
+					     int	    x_off,
+					     int	    y_off);
+
+typedef void	(*TrapezoidsProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntrap,
+					     xTrapezoid	    *traps);
+
+typedef void	(*TrianglesProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef void	(*TriStripProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef void	(*TriFanProcPtr)	    (CARD8	    op,
+					     PicturePtr	    pSrc,
+					     PicturePtr	    pDst,
+					     PictFormatPtr  maskFormat,
+					     INT16	    xSrc,
+					     INT16	    ySrc,
+					     int	    npoint,
+					     xPointFixed    *points);
+
+typedef Bool	(*InitIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*CloseIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat);
+
+typedef void	(*UpdateIndexedProcPtr)	    (ScreenPtr	    pScreen,
+					     PictFormatPtr  pFormat,
+					     int	    ndef,
+					     xColorItem	    *pdef);
+
+typedef void	(*AddTrapsProcPtr)	    (PicturePtr	    pPicture,
+					     INT16	    xOff,
+					     INT16	    yOff,
+					     int	    ntrap,
+					     xTrap	    *traps);
+
+typedef void	(*AddTrianglesProcPtr)	    (PicturePtr	    pPicture,
+					     INT16	    xOff,
+					     INT16	    yOff,
+					     int	    ntri,
+					     xTriangle	    *tris);
+
+typedef struct _PictureScreen {
+    int				totalPictureSize;
+    unsigned int		*PicturePrivateSizes;
+    int				PicturePrivateLen;
+
+    PictFormatPtr		formats;
+    PictFormatPtr		fallback;
+    int				nformats;
+
+    CreatePictureProcPtr	CreatePicture;
+    DestroyPictureProcPtr	DestroyPicture;
+    ChangePictureClipProcPtr	ChangePictureClip;
+    DestroyPictureClipProcPtr	DestroyPictureClip;
+
+    ChangePictureProcPtr	ChangePicture;
+    ValidatePictureProcPtr	ValidatePicture;
+
+    CompositeProcPtr		Composite;
+    GlyphsProcPtr		Glyphs;
+    CompositeRectsProcPtr	CompositeRects;
+
+    DestroyWindowProcPtr	DestroyWindow;
+    CloseScreenProcPtr		CloseScreen;
+
+    StoreColorsProcPtr		StoreColors;
+
+    InitIndexedProcPtr		InitIndexed;
+    CloseIndexedProcPtr		CloseIndexed;
+    UpdateIndexedProcPtr	UpdateIndexed;
+
+    int				subpixel;
+
+    PictFilterPtr		filters;
+    int				nfilters;
+    PictFilterAliasPtr		filterAliases;
+    int				nfilterAliases;
+
+    ChangePictureTransformProcPtr   ChangePictureTransform;
+    ChangePictureFilterProcPtr	ChangePictureFilter;
+    DestroyPictureFilterProcPtr	DestroyPictureFilter;
+
+    TrapezoidsProcPtr		Trapezoids;
+    TrianglesProcPtr		Triangles;
+    TriStripProcPtr		TriStrip;
+    TriFanProcPtr		TriFan;
+
+    RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
+
+    AddTrianglesProcPtr		AddTriangles;
+
+    AddTrapsProcPtr		AddTraps;
+
+} PictureScreenRec, *PictureScreenPtr;
+
+extern int		PictureScreenPrivateIndex;
+extern int		PictureWindowPrivateIndex;
+extern RESTYPE		PictureType;
+extern RESTYPE		PictFormatType;
+extern RESTYPE		GlyphSetType;
+
+#define GetPictureScreen(s) ((PictureScreenPtr) ((s)->devPrivates[PictureScreenPrivateIndex].ptr))
+#define GetPictureScreenIfSet(s) ((PictureScreenPrivateIndex != -1) ? GetPictureScreen(s) : NULL)
+#define SetPictureScreen(s,p) ((s)->devPrivates[PictureScreenPrivateIndex].ptr = (pointer) (p))
+#define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr))
+#define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p))
+
+#define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+void
+ResetPicturePrivateIndex (void);
+
+int
+AllocatePicturePrivateIndex (void);
+
+Bool
+AllocatePicturePrivate (ScreenPtr pScreen, int index2, unsigned int amount);
+
+Bool
+PictureDestroyWindow (WindowPtr pWindow);
+
+Bool
+PictureCloseScreen (int Index, ScreenPtr pScreen);
+
+void
+PictureStoreColors (ColormapPtr pColormap, int ndef, xColorItem *pdef);
+
+Bool
+PictureInitIndexedFormats (ScreenPtr pScreen);
+
+Bool
+PictureSetSubpixelOrder (ScreenPtr pScreen, int subpixel);
+
+int
+PictureGetSubpixelOrder (ScreenPtr pScreen);
+
+PictFormatPtr
+PictureCreateDefaultFormats (ScreenPtr pScreen, int *nformatp);
+
+PictFormatPtr
+PictureMatchVisual (ScreenPtr pScreen, int depth, VisualPtr pVisual);
+
+PictFormatPtr
+PictureMatchFormat (ScreenPtr pScreen, int depth, CARD32 format);
+
+Bool
+PictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+int
+PictureGetFilterId (char *filter, int len, Bool makeit);
+
+char *
+PictureGetFilterName (int id);
+
+int
+PictureAddFilter (ScreenPtr			    pScreen,
+		  char				    *filter,
+		  PictFilterValidateParamsProcPtr   ValidateParams);
+
+Bool
+PictureSetFilterAlias (ScreenPtr pScreen, char *filter, char *alias);
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen);
+
+void
+PictureResetFilters (ScreenPtr pScreen);
+
+PictFilterPtr
+PictureFindFilter (ScreenPtr pScreen, char *name, int len);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+
+Bool
+PictureFinishInit (void);
+
+void
+SetPictureToDefaults (PicturePtr pPicture);
+
+PicturePtr
+AllocatePicture (ScreenPtr  pScreen);
+
+#if 0
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+#endif
+
+
+PicturePtr
+CreatePicture (Picture		pid,
+	       DrawablePtr	pDrawable,
+	       PictFormatPtr	pFormat,
+	       Mask		mask,
+	       XID		*list,
+	       ClientPtr	client,
+	       int		*error);
+
+int
+ChangePicture (PicturePtr	pPicture,
+	       Mask		vmask,
+	       XID		*vlist,
+	       DevUnion		*ulist,
+	       ClientPtr	client);
+
+int
+SetPictureClipRects (PicturePtr	pPicture,
+		     int	xOrigin,
+		     int	yOrigin,
+		     int	nRect,
+		     xRectangle	*rects);
+
+int
+SetPictureClipRegion (PicturePtr    pPicture,
+		      int	    xOrigin,
+		      int	    yOrigin,
+		      RegionPtr	    pRegion);
+
+int
+SetPictureTransform (PicturePtr	    pPicture,
+		     PictTransform  *transform);
+
+void
+CopyPicture (PicturePtr	pSrc,
+	     Mask	mask,
+	     PicturePtr	pDst);
+
+void
+ValidatePicture(PicturePtr pPicture);
+
+int
+FreePicture (pointer	pPicture,
+	     XID	pid);
+
+int
+FreePictFormat (pointer	pPictFormat,
+		XID     pid);
+
+void
+CompositePicture (CARD8		op,
+		  PicturePtr	pSrc,
+		  PicturePtr	pMask,
+		  PicturePtr	pDst,
+		  INT16		xSrc,
+		  INT16		ySrc,
+		  INT16		xMask,
+		  INT16		yMask,
+		  INT16		xDst,
+		  INT16		yDst,
+		  CARD16	width,
+		  CARD16	height);
+
+void
+CompositeGlyphs (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		nlist,
+		 GlyphListPtr	lists,
+		 GlyphPtr	*glyphs);
+
+void
+CompositeRects (CARD8		op,
+		PicturePtr	pDst,
+		xRenderColor	*color,
+		int		nRect,
+		xRectangle      *rects);
+
+void
+CompositeTrapezoids (CARD8	    op,
+		     PicturePtr	    pSrc,
+		     PicturePtr	    pDst,
+		     PictFormatPtr  maskFormat,
+		     INT16	    xSrc,
+		     INT16	    ySrc,
+		     int	    ntrap,
+		     xTrapezoid	    *traps);
+
+void
+CompositeTriangles (CARD8	    op,
+		    PicturePtr	    pSrc,
+		    PicturePtr	    pDst,
+		    PictFormatPtr   maskFormat,
+		    INT16	    xSrc,
+		    INT16	    ySrc,
+		    int		    ntriangles,
+		    xTriangle	    *triangles);
+
+void
+CompositeTriStrip (CARD8	    op,
+		   PicturePtr	    pSrc,
+		   PicturePtr	    pDst,
+		   PictFormatPtr    maskFormat,
+		   INT16	    xSrc,
+		   INT16	    ySrc,
+		   int		    npoints,
+		   xPointFixed	    *points);
+
+void
+CompositeTriFan (CARD8		op,
+		 PicturePtr	pSrc,
+		 PicturePtr	pDst,
+		 PictFormatPtr	maskFormat,
+		 INT16		xSrc,
+		 INT16		ySrc,
+		 int		npoints,
+		 xPointFixed	*points);
+
+Bool
+PictureTransformPoint (PictTransformPtr transform,
+		       PictVectorPtr	vector);
+
+Bool
+PictureTransformPoint3d (PictTransformPtr transform,
+                         PictVectorPtr	vector);
+
+void RenderExtensionInit (void);
+
+Bool
+AnimCurInit (ScreenPtr pScreen);
+
+int
+AnimCursorCreate (CursorPtr *cursors, CARD32 *deltas, int ncursor, CursorPtr *ppCursor);
+
+void
+AddTraps (PicturePtr	pPicture,
+	  INT16		xOff,
+	  INT16		yOff,
+	  int		ntraps,
+	  xTrap		*traps);
+
+PicturePtr
+CreateSolidPicture (Picture pid,
+                    xRenderColor *color,
+                    int *error);
+
+PicturePtr
+CreateLinearGradientPicture (Picture pid,
+                             xPointFixed *p1,
+                             xPointFixed *p2,
+                             int nStops,
+                             xFixed *stops,
+                             xRenderColor *colors,
+                             int *error);
+
+PicturePtr
+CreateRadialGradientPicture (Picture pid,
+                             xPointFixed *inner,
+                             xPointFixed *outer,
+                             xFixed innerRadius,
+                             xFixed outerRadius,
+                             int nStops,
+                             xFixed *stops,
+                             xRenderColor *colors,
+                             int *error);
+
+PicturePtr
+CreateConicalGradientPicture (Picture pid,
+                              xPointFixed *center,
+                              xFixed angle,
+                              int nStops,
+                              xFixed *stops,
+                              xRenderColor *colors,
+                              int *error);
+
+#ifdef PANORAMIX
+void PanoramiXRenderInit (void);
+void PanoramiXRenderReset (void);
+#endif
+
+#endif /* _PICTURESTR_H_ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
new file mode 100644
index 000000000..3d08a3228
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -0,0 +1,904 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+
+#if defined(LBX) || defined(LBX_COMPAT)
+#if 0 /* no header in X11 environment, not used in X11 environment */
+int fWriteToClient(ClientPtr client, int len, char *buf)
+{
+    return WriteToClient(client, len, buf);
+}
+#endif
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ *    ChangeProperty, DeleteProperty, GetProperties,
+ *    ListProperties
+ *
+ *   Properties below to windows.  A allocate slots each time
+ *   a property is added.  No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+    PropertyPtr pProp;
+    register int j;
+
+    pProp = pWin->userProps;
+    while (pProp)
+    {
+        ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
+        ErrorF("property format: %d\n", pProp->format);
+        ErrorF("property data: \n");
+        for (j=0; j<(pProp->format/8)*pProp->size; j++)
+           ErrorF("%c\n", pProp->data[j]);
+        pProp = pProp->next;
+    }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+    int     i, j, delta;
+    REQUEST(xRotatePropertiesReq);
+    WindowPtr pWin;
+    register    Atom * atoms;
+    PropertyPtr * props;               /* array of pointer */
+    PropertyPtr pProp;
+    xEvent event;
+
+    REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+    UpdateCurrentTime();
+    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!stuff->nAtoms)
+	return(Success);
+    atoms = (Atom *) & stuff[1];
+    props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+    if (!props)
+	return(BadAlloc);
+    for (i = 0; i < stuff->nAtoms; i++)
+    {
+#ifdef XCSECURITY
+	char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+				SecurityReadAccess|SecurityWriteAccess);
+#endif
+        if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+	    || (SecurityErrorOperation == action)
+#endif
+	   )
+        {
+            DEALLOCATE_LOCAL(props);
+	    client->errorValue = atoms[i];
+            return BadAtom;
+        }
+#ifdef XCSECURITY
+	if (SecurityIgnoreOperation == action)
+        {
+            DEALLOCATE_LOCAL(props);
+	    return Success;
+	}
+#endif
+        for (j = i + 1; j < stuff->nAtoms; j++)
+            if (atoms[j] == atoms[i])
+            {
+                DEALLOCATE_LOCAL(props);
+                return BadMatch;
+            }
+        pProp = wUserProps (pWin);
+        while (pProp)
+        {
+            if (pProp->propertyName == atoms[i])
+                goto found;
+	    pProp = pProp->next;
+        }
+        DEALLOCATE_LOCAL(props);
+        return BadMatch;
+found: 
+        props[i] = pProp;
+    }
+    delta = stuff->nPositions;
+
+    /* If the rotation is a complete 360 degrees, then moving the properties
+	around and generating PropertyNotify events should be skipped. */
+
+    if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
+    {
+	while (delta < 0)                  /* faster if abs value is small */
+            delta += stuff->nAtoms;
+    	for (i = 0; i < stuff->nAtoms; i++)
+ 	{
+	    /* Generate a PropertyNotify event for each property whose value
+		is changed in the order in which they appear in the request. */
+ 
+ 	    event.u.u.type = PropertyNotify;
+            event.u.property.window = pWin->drawable.id;
+    	    event.u.property.state = PropertyNewValue;
+	    event.u.property.atom = props[i]->propertyName;	
+	    event.u.property.time = currentTime.milliseconds;
+	    DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	
+            props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+	}
+    }
+    DEALLOCATE_LOCAL(props);
+    return Success;
+}
+
+int 
+ProcChangeProperty(ClientPtr client)
+{	      
+    WindowPtr pWin;
+    char format, mode;
+    unsigned long len;
+    int sizeInBytes;
+    int totalSize;
+    int err;
+    REQUEST(xChangePropertyReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+    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(xChangePropertyReq, totalSize);
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+       extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
+
+       pWin = nxagentGetClipboardWindow(stuff->property, NULL);
+    }
+
+    if (pWin == NULL)
+#endif
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+	return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return(BadAtom);
+    }
+    if (!ValidAtom(stuff->type))
+    {
+	client->errorValue = stuff->type;
+	return(BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					SecurityWriteAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+#ifdef NXAGENT_ARTSD
+    {
+    /* Do not process MCOPGLOBALS property changes,
+      they are already set reflecting the server side settings.
+      Just return success.
+    */
+      extern Atom mcop_local_atom;
+      if (stuff->property == mcop_local_atom)
+        return client->noClientException;
+    }
+#endif
+
+#ifdef LBX
+    err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+	 (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+    err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+			       (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+    if (err != Success)
+	return err;
+    else
+    {
+      if (nxagentOption(Rootless) == 1)
+      {
+        nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
+                                  (int) mode, len, (pointer) &stuff[1]);
+      }
+
+      nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
+
+      nxagentGuessShadowHint(client, stuff->property);
+
+      return client->noClientException;
+    }
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, 
+                     int mode, unsigned long len, pointer value, 
+                     Bool sendevent)
+{
+#ifdef LBX
+    return LbxChangeWindowProperty(NULL, pWin, property, type,
+				   format, mode, len, TRUE, value,
+				   sendevent, NULL);
+#else
+    PropertyPtr pProp;
+    xEvent event;
+    int sizeInBytes;
+    int totalSize;
+    pointer data;
+
+    sizeInBytes = format>>3;
+    totalSize = len * sizeInBytes;
+
+    /* first see if property already exists */
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	pProp = pProp->next;
+    }
+    if (!pProp)   /* just add to list */
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return(BadAlloc);
+        pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+	if (!pProp)
+	    return(BadAlloc);
+        data = (pointer)xalloc(totalSize);
+	if (!data && len)
+	{
+	    xfree(pProp);
+	    return(BadAlloc);
+	}
+        pProp->propertyName = property;
+        pProp->type = type;
+        pProp->format = format;
+        pProp->data = data;
+	if (len)
+	    memmove((char *)data, (char *)value, totalSize);
+	pProp->size = len;
+        pProp->next = pWin->optional->userProps;
+        pWin->optional->userProps = pProp;
+    }
+    else
+    {
+	/* 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 != pProp->format) && (mode != PropModeReplace))
+	    return(BadMatch);
+        if ((pProp->type != type) && (mode != PropModeReplace))
+            return(BadMatch);
+        if (mode == PropModeReplace)
+        {
+	    if (totalSize != pProp->size * (pProp->format >> 3))
+	    {
+	    	data = (pointer)xrealloc(pProp->data, totalSize);
+	    	if (!data && len)
+		    return(BadAlloc);
+            	pProp->data = data;
+	    }
+	    if (len)
+		memmove((char *)pProp->data, (char *)value, totalSize);
+	    pProp->size = len;
+    	    pProp->type = type;
+	    pProp->format = format;
+	}
+	else if (len == 0)
+	{
+	    /* do nothing */
+	}
+        else if (mode == PropModeAppend)
+        {
+	    data = (pointer)xrealloc(pProp->data,
+				     sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+            pProp->data = data;
+	    memmove(&((char *)data)[pProp->size * sizeInBytes], 
+		    (char *)value,
+		  totalSize);
+            pProp->size += len;
+	}
+        else if (mode == PropModePrepend)
+        {
+            data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+	    memmove(&((char *)data)[totalSize], (char *)pProp->data, 
+		  (int)(pProp->size * sizeInBytes));
+            memmove((char *)data, (char *)value, totalSize);
+	    xfree(pProp->data);
+            pProp->data = data;
+            pProp->size += len;
+	}
+    }
+    if (sendevent)
+    {
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyNewValue;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+    return(Success);
+#endif
+}
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+    PropertyPtr pProp, prevProp;
+    xEvent event;
+
+    if (!(pProp = wUserProps (pWin)))
+	return(Success);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == propName)
+	    break;
+        prevProp = pProp;
+	pProp = pProp->next;
+    }
+    if (pProp) 
+    {		    
+        if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
+        {
+            if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+        }
+	else
+        {
+            prevProp->next = pProp->next;
+        }
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+        event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	xfree(pProp->data);
+        xfree(pProp);
+    }
+    return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+    PropertyPtr pProp, pNextProp;
+    xEvent event;
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	pNextProp = pProp->next;
+        xfree(pProp->data);
+        xfree(pProp);
+	pProp = pNextProp;
+    }
+}
+
+static int
+NullPropertyReply(
+    ClientPtr client,
+    ATOM propertyType,
+    int format,
+    xGetPropertyReply *reply)
+{
+    reply->nItems = 0;
+    reply->length = 0;
+    reply->bytesAfter = 0;
+    reply->propertyType = propertyType;
+    reply->format = format;
+    WriteReplyToClient(client, sizeof(xGenericReply), reply);
+    return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ *    If type Any is specified, returns the property from the specified
+ *    window regardless of its type.  If a type is specified, returns the
+ *    property only if its type equals the specified type.
+ *    If delete is True and a property is returned, the property is also
+ *    deleted from the window and a PropertyNotify event is generated on the
+ *    window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+    WindowPtr pWin;
+    xGetPropertyReply reply;
+    REQUEST(xGetPropertyReq);
+
+    REQUEST_SIZE_MATCH(xGetPropertyReq);
+    if (stuff->delete)
+	UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    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);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == stuff->property) 
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    if (!pProp) 
+	return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+    {
+	Mask access_mode = SecurityReadAccess;
+
+	if (stuff->delete)
+	    access_mode |= SecurityDestroyAccess;
+	switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					   access_mode))
+	{
+	    case SecurityErrorOperation:
+		client->errorValue = stuff->property;
+		return BadAtom;;
+	    case SecurityIgnoreOperation:
+		return NullPropertyReply(client, pProp->type, pProp->format,
+					 &reply);
+	}
+    }
+#endif
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((stuff->type != pProp->type) &&
+	 (stuff->type != AnyPropertyType))
+       )
+    {
+	reply.bytesAfter = pProp->size;
+	reply.format = pProp->format;
+	reply.length = 0;
+	reply.nItems = 0;
+	reply.propertyType = pProp->type;
+	WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+	return(Success);
+    }
+#ifdef LBX
+    /* make sure we have the current value */                       
+    if (pProp->tag_id && pProp->owner_pid) {
+	LbxStallPropRequest(client, pProp);
+	return client->noClientException;
+    }                                              
+#endif
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->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);
+
+    reply.bytesAfter = n - (ind + len);
+    reply.format = pProp->format;
+    reply.length = (len + 3) >> 2;
+    reply.nItems = len / (pProp->format / 8 );
+    reply.propertyType = pProp->type;
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+    if (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,
+				 (char *)pProp->data + ind);
+    }
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(client->noClientException);
+}
+
+#ifdef NXAGENT_CLIPBOARD
+/* GetWindowProperty clipboard use only */
+int
+GetWindowProperty(pWin, property, longOffset, longLength, delete,
+            type, actualType, format, nItems, bytesAfter, propData )
+    WindowPtr	        pWin;
+    Atom		property;
+    long			longOffset;
+    long			longLength;
+    Bool			delete;
+    Atom		type;
+    Atom		*actualType;
+    int			*format;
+    unsigned long	*nItems;
+    unsigned long	*bytesAfter;
+    unsigned char	**propData;
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+
+    if (!pWin)
+	return BadWindow;
+
+
+    if (!ValidAtom(property))
+    {
+	return(BadAtom);
+    }
+    if ((type != AnyPropertyType) && !ValidAtom(type))
+    {
+	return(BadAtom);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+
+    if (!pProp)
+	return (BadAtom);
+
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((type != pProp->type) &&
+	 (type != AnyPropertyType))
+       )
+    {
+	*bytesAfter = pProp->size;
+	*format = pProp->format;
+	*nItems = 0;
+	*actualType = pProp->type;
+	return(Success);
+    }
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+    ind = longOffset << 2;
+
+   /* If longOffset is invalid such that it causes "len" to
+	    be negative, it's a value error. */
+
+    if (n < ind)
+    {
+	return BadValue;
+    }
+
+    len = min(n - ind, 4 * longLength);
+
+    *bytesAfter = n - (ind + len);
+    *format = pProp->format;
+    *nItems = len / (pProp->format / 8 );
+    *actualType = pProp->type;
+
+    if (delete && (*bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    if (len)
+    {
+	 *propData = (unsigned char *)(pProp->data) + ind;
+    }
+
+    if (delete && (*bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(Success);
+}
+#endif
+
+int
+ProcListProperties(ClientPtr client)
+{
+    Atom *pAtoms = NULL, *temppAtoms;
+    xListPropertiesReply xlpr;
+    int	numProps = 0;
+    WindowPtr pWin;
+    PropertyPtr pProp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {        
+        pProp = pProp->next;
+	numProps++;
+    }
+    if (numProps)
+        if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+            return(BadAlloc);
+
+    xlpr.type = X_Reply;
+    xlpr.nProperties = numProps;
+    xlpr.length = (numProps * sizeof(Atom)) >> 2;
+    xlpr.sequenceNumber = client->sequence;
+    pProp = wUserProps (pWin);
+    temppAtoms = pAtoms;
+    while (pProp)
+    {
+	*temppAtoms++ = pProp->propertyName;
+	pProp = pProp->next;
+    }
+    WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+    if (numProps)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+        DEALLOCATE_LOCAL(pAtoms);
+    }
+    return(client->noClientException);
+}
+
+int 
+ProcDeleteProperty(register ClientPtr client)
+{
+    WindowPtr pWin;
+    REQUEST(xDeletePropertyReq);
+    int result;
+              
+    REQUEST_SIZE_MATCH(xDeletePropertyReq);
+    UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return (BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+				       SecurityDestroyAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+    result = DeleteProperty(pWin, stuff->property);
+    if (client->noClientException != Success)
+	return(client->noClientException);
+    else
+	return(result);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
new file mode 100644
index 000000000..3d08a3228
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -0,0 +1,904 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "../../dix/dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#include "Options.h"
+#include "Rootless.h"
+#include "Client.h"
+
+#if defined(LBX) || defined(LBX_COMPAT)
+#if 0 /* no header in X11 environment, not used in X11 environment */
+int fWriteToClient(ClientPtr client, int len, char *buf)
+{
+    return WriteToClient(client, len, buf);
+}
+#endif
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ *    ChangeProperty, DeleteProperty, GetProperties,
+ *    ListProperties
+ *
+ *   Properties below to windows.  A allocate slots each time
+ *   a property is added.  No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+    PropertyPtr pProp;
+    register int j;
+
+    pProp = pWin->userProps;
+    while (pProp)
+    {
+        ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
+        ErrorF("property format: %d\n", pProp->format);
+        ErrorF("property data: \n");
+        for (j=0; j<(pProp->format/8)*pProp->size; j++)
+           ErrorF("%c\n", pProp->data[j]);
+        pProp = pProp->next;
+    }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+    int     i, j, delta;
+    REQUEST(xRotatePropertiesReq);
+    WindowPtr pWin;
+    register    Atom * atoms;
+    PropertyPtr * props;               /* array of pointer */
+    PropertyPtr pProp;
+    xEvent event;
+
+    REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+    UpdateCurrentTime();
+    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!stuff->nAtoms)
+	return(Success);
+    atoms = (Atom *) & stuff[1];
+    props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+    if (!props)
+	return(BadAlloc);
+    for (i = 0; i < stuff->nAtoms; i++)
+    {
+#ifdef XCSECURITY
+	char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+				SecurityReadAccess|SecurityWriteAccess);
+#endif
+        if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+	    || (SecurityErrorOperation == action)
+#endif
+	   )
+        {
+            DEALLOCATE_LOCAL(props);
+	    client->errorValue = atoms[i];
+            return BadAtom;
+        }
+#ifdef XCSECURITY
+	if (SecurityIgnoreOperation == action)
+        {
+            DEALLOCATE_LOCAL(props);
+	    return Success;
+	}
+#endif
+        for (j = i + 1; j < stuff->nAtoms; j++)
+            if (atoms[j] == atoms[i])
+            {
+                DEALLOCATE_LOCAL(props);
+                return BadMatch;
+            }
+        pProp = wUserProps (pWin);
+        while (pProp)
+        {
+            if (pProp->propertyName == atoms[i])
+                goto found;
+	    pProp = pProp->next;
+        }
+        DEALLOCATE_LOCAL(props);
+        return BadMatch;
+found: 
+        props[i] = pProp;
+    }
+    delta = stuff->nPositions;
+
+    /* If the rotation is a complete 360 degrees, then moving the properties
+	around and generating PropertyNotify events should be skipped. */
+
+    if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
+    {
+	while (delta < 0)                  /* faster if abs value is small */
+            delta += stuff->nAtoms;
+    	for (i = 0; i < stuff->nAtoms; i++)
+ 	{
+	    /* Generate a PropertyNotify event for each property whose value
+		is changed in the order in which they appear in the request. */
+ 
+ 	    event.u.u.type = PropertyNotify;
+            event.u.property.window = pWin->drawable.id;
+    	    event.u.property.state = PropertyNewValue;
+	    event.u.property.atom = props[i]->propertyName;	
+	    event.u.property.time = currentTime.milliseconds;
+	    DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	
+            props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+	}
+    }
+    DEALLOCATE_LOCAL(props);
+    return Success;
+}
+
+int 
+ProcChangeProperty(ClientPtr client)
+{	      
+    WindowPtr pWin;
+    char format, mode;
+    unsigned long len;
+    int sizeInBytes;
+    int totalSize;
+    int err;
+    REQUEST(xChangePropertyReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+    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(xChangePropertyReq, totalSize);
+
+#ifdef NXAGENT_CLIPBOARD
+    {
+       extern WindowPtr nxagentGetClipboardWindow(Atom, WindowPtr);
+
+       pWin = nxagentGetClipboardWindow(stuff->property, NULL);
+    }
+
+    if (pWin == NULL)
+#endif
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+	return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return(BadAtom);
+    }
+    if (!ValidAtom(stuff->type))
+    {
+	client->errorValue = stuff->type;
+	return(BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					SecurityWriteAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+#ifdef NXAGENT_ARTSD
+    {
+    /* Do not process MCOPGLOBALS property changes,
+      they are already set reflecting the server side settings.
+      Just return success.
+    */
+      extern Atom mcop_local_atom;
+      if (stuff->property == mcop_local_atom)
+        return client->noClientException;
+    }
+#endif
+
+#ifdef LBX
+    err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+	 (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+    err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+			       (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+    if (err != Success)
+	return err;
+    else
+    {
+      if (nxagentOption(Rootless) == 1)
+      {
+        nxagentExportProperty(pWin, stuff->property, stuff->type, (int) format,
+                                  (int) mode, len, (pointer) &stuff[1]);
+      }
+
+      nxagentGuessClientHint(client, stuff->property, (char *) &stuff[1]);
+
+      nxagentGuessShadowHint(client, stuff->property);
+
+      return client->noClientException;
+    }
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, 
+                     int mode, unsigned long len, pointer value, 
+                     Bool sendevent)
+{
+#ifdef LBX
+    return LbxChangeWindowProperty(NULL, pWin, property, type,
+				   format, mode, len, TRUE, value,
+				   sendevent, NULL);
+#else
+    PropertyPtr pProp;
+    xEvent event;
+    int sizeInBytes;
+    int totalSize;
+    pointer data;
+
+    sizeInBytes = format>>3;
+    totalSize = len * sizeInBytes;
+
+    /* first see if property already exists */
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	pProp = pProp->next;
+    }
+    if (!pProp)   /* just add to list */
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return(BadAlloc);
+        pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+	if (!pProp)
+	    return(BadAlloc);
+        data = (pointer)xalloc(totalSize);
+	if (!data && len)
+	{
+	    xfree(pProp);
+	    return(BadAlloc);
+	}
+        pProp->propertyName = property;
+        pProp->type = type;
+        pProp->format = format;
+        pProp->data = data;
+	if (len)
+	    memmove((char *)data, (char *)value, totalSize);
+	pProp->size = len;
+        pProp->next = pWin->optional->userProps;
+        pWin->optional->userProps = pProp;
+    }
+    else
+    {
+	/* 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 != pProp->format) && (mode != PropModeReplace))
+	    return(BadMatch);
+        if ((pProp->type != type) && (mode != PropModeReplace))
+            return(BadMatch);
+        if (mode == PropModeReplace)
+        {
+	    if (totalSize != pProp->size * (pProp->format >> 3))
+	    {
+	    	data = (pointer)xrealloc(pProp->data, totalSize);
+	    	if (!data && len)
+		    return(BadAlloc);
+            	pProp->data = data;
+	    }
+	    if (len)
+		memmove((char *)pProp->data, (char *)value, totalSize);
+	    pProp->size = len;
+    	    pProp->type = type;
+	    pProp->format = format;
+	}
+	else if (len == 0)
+	{
+	    /* do nothing */
+	}
+        else if (mode == PropModeAppend)
+        {
+	    data = (pointer)xrealloc(pProp->data,
+				     sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+            pProp->data = data;
+	    memmove(&((char *)data)[pProp->size * sizeInBytes], 
+		    (char *)value,
+		  totalSize);
+            pProp->size += len;
+	}
+        else if (mode == PropModePrepend)
+        {
+            data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+	    memmove(&((char *)data)[totalSize], (char *)pProp->data, 
+		  (int)(pProp->size * sizeInBytes));
+            memmove((char *)data, (char *)value, totalSize);
+	    xfree(pProp->data);
+            pProp->data = data;
+            pProp->size += len;
+	}
+    }
+    if (sendevent)
+    {
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyNewValue;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+    return(Success);
+#endif
+}
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+    PropertyPtr pProp, prevProp;
+    xEvent event;
+
+    if (!(pProp = wUserProps (pWin)))
+	return(Success);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == propName)
+	    break;
+        prevProp = pProp;
+	pProp = pProp->next;
+    }
+    if (pProp) 
+    {		    
+        if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
+        {
+            if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+        }
+	else
+        {
+            prevProp->next = pProp->next;
+        }
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+        event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	xfree(pProp->data);
+        xfree(pProp);
+    }
+    return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+    PropertyPtr pProp, pNextProp;
+    xEvent event;
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	pNextProp = pProp->next;
+        xfree(pProp->data);
+        xfree(pProp);
+	pProp = pNextProp;
+    }
+}
+
+static int
+NullPropertyReply(
+    ClientPtr client,
+    ATOM propertyType,
+    int format,
+    xGetPropertyReply *reply)
+{
+    reply->nItems = 0;
+    reply->length = 0;
+    reply->bytesAfter = 0;
+    reply->propertyType = propertyType;
+    reply->format = format;
+    WriteReplyToClient(client, sizeof(xGenericReply), reply);
+    return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ *    If type Any is specified, returns the property from the specified
+ *    window regardless of its type.  If a type is specified, returns the
+ *    property only if its type equals the specified type.
+ *    If delete is True and a property is returned, the property is also
+ *    deleted from the window and a PropertyNotify event is generated on the
+ *    window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+    WindowPtr pWin;
+    xGetPropertyReply reply;
+    REQUEST(xGetPropertyReq);
+
+    REQUEST_SIZE_MATCH(xGetPropertyReq);
+    if (stuff->delete)
+	UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    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);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == stuff->property) 
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    if (!pProp) 
+	return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+    {
+	Mask access_mode = SecurityReadAccess;
+
+	if (stuff->delete)
+	    access_mode |= SecurityDestroyAccess;
+	switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					   access_mode))
+	{
+	    case SecurityErrorOperation:
+		client->errorValue = stuff->property;
+		return BadAtom;;
+	    case SecurityIgnoreOperation:
+		return NullPropertyReply(client, pProp->type, pProp->format,
+					 &reply);
+	}
+    }
+#endif
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((stuff->type != pProp->type) &&
+	 (stuff->type != AnyPropertyType))
+       )
+    {
+	reply.bytesAfter = pProp->size;
+	reply.format = pProp->format;
+	reply.length = 0;
+	reply.nItems = 0;
+	reply.propertyType = pProp->type;
+	WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+	return(Success);
+    }
+#ifdef LBX
+    /* make sure we have the current value */                       
+    if (pProp->tag_id && pProp->owner_pid) {
+	LbxStallPropRequest(client, pProp);
+	return client->noClientException;
+    }                                              
+#endif
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->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);
+
+    reply.bytesAfter = n - (ind + len);
+    reply.format = pProp->format;
+    reply.length = (len + 3) >> 2;
+    reply.nItems = len / (pProp->format / 8 );
+    reply.propertyType = pProp->type;
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+    if (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,
+				 (char *)pProp->data + ind);
+    }
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(client->noClientException);
+}
+
+#ifdef NXAGENT_CLIPBOARD
+/* GetWindowProperty clipboard use only */
+int
+GetWindowProperty(pWin, property, longOffset, longLength, delete,
+            type, actualType, format, nItems, bytesAfter, propData )
+    WindowPtr	        pWin;
+    Atom		property;
+    long			longOffset;
+    long			longLength;
+    Bool			delete;
+    Atom		type;
+    Atom		*actualType;
+    int			*format;
+    unsigned long	*nItems;
+    unsigned long	*bytesAfter;
+    unsigned char	**propData;
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+
+    if (!pWin)
+	return BadWindow;
+
+
+    if (!ValidAtom(property))
+    {
+	return(BadAtom);
+    }
+    if ((type != AnyPropertyType) && !ValidAtom(type))
+    {
+	return(BadAtom);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+
+    if (!pProp)
+	return (BadAtom);
+
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((type != pProp->type) &&
+	 (type != AnyPropertyType))
+       )
+    {
+	*bytesAfter = pProp->size;
+	*format = pProp->format;
+	*nItems = 0;
+	*actualType = pProp->type;
+	return(Success);
+    }
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */
+    ind = longOffset << 2;
+
+   /* If longOffset is invalid such that it causes "len" to
+	    be negative, it's a value error. */
+
+    if (n < ind)
+    {
+	return BadValue;
+    }
+
+    len = min(n - ind, 4 * longLength);
+
+    *bytesAfter = n - (ind + len);
+    *format = pProp->format;
+    *nItems = len / (pProp->format / 8 );
+    *actualType = pProp->type;
+
+    if (delete && (*bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    if (len)
+    {
+	 *propData = (unsigned char *)(pProp->data) + ind;
+    }
+
+    if (delete && (*bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(Success);
+}
+#endif
+
+int
+ProcListProperties(ClientPtr client)
+{
+    Atom *pAtoms = NULL, *temppAtoms;
+    xListPropertiesReply xlpr;
+    int	numProps = 0;
+    WindowPtr pWin;
+    PropertyPtr pProp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {        
+        pProp = pProp->next;
+	numProps++;
+    }
+    if (numProps)
+        if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+            return(BadAlloc);
+
+    xlpr.type = X_Reply;
+    xlpr.nProperties = numProps;
+    xlpr.length = (numProps * sizeof(Atom)) >> 2;
+    xlpr.sequenceNumber = client->sequence;
+    pProp = wUserProps (pWin);
+    temppAtoms = pAtoms;
+    while (pProp)
+    {
+	*temppAtoms++ = pProp->propertyName;
+	pProp = pProp->next;
+    }
+    WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+    if (numProps)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+        DEALLOCATE_LOCAL(pAtoms);
+    }
+    return(client->noClientException);
+}
+
+int 
+ProcDeleteProperty(register ClientPtr client)
+{
+    WindowPtr pWin;
+    REQUEST(xDeletePropertyReq);
+    int result;
+              
+    REQUEST_SIZE_MATCH(xDeletePropertyReq);
+    UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return (BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+				       SecurityDestroyAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+    result = DeleteProperty(pWin, stuff->property);
+    if (client->noClientException != Success)
+	return(client->noClientException);
+    else
+	return(result);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original
new file mode 100644
index 000000000..cabe46ecc
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.X.original
@@ -0,0 +1,729 @@
+/* $XFree86: xc/programs/Xserver/dix/property.c,v 3.12 2002/02/19 11:09:22 alanh Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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.
+
+******************************************************************/
+/* $Xorg: property.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "propertyst.h"
+#include "dixstruct.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#include "lbxtags.h"
+#endif
+
+#if defined(LBX) || defined(LBX_COMPAT)
+#if 0 /* no header in X11 environment, not used in X11 environment */
+int fWriteToClient(ClientPtr client, int len, char *buf)
+{
+    return WriteToClient(client, len, buf);
+}
+#endif
+#endif
+
+/*****************************************************************
+ * Property Stuff
+ *
+ *    ChangeProperty, DeleteProperty, GetProperties,
+ *    ListProperties
+ *
+ *   Properties below to windows.  A allocate slots each time
+ *   a property is added.  No fancy searching done.
+ *
+ *****************************************************************/
+
+#ifdef notdef
+static void
+PrintPropertys(WindowPtr pWin)
+{
+    PropertyPtr pProp;
+    register int j;
+
+    pProp = pWin->userProps;
+    while (pProp)
+    {
+        ErrorF(  "%x %x\n", pProp->propertyName, pProp->type);
+        ErrorF("property format: %d\n", pProp->format);
+        ErrorF("property data: \n");
+        for (j=0; j<(pProp->format/8)*pProp->size; j++)
+           ErrorF("%c\n", pProp->data[j]);
+        pProp = pProp->next;
+    }
+}
+#endif
+
+int
+ProcRotateProperties(ClientPtr client)
+{
+    int     i, j, delta;
+    REQUEST(xRotatePropertiesReq);
+    WindowPtr pWin;
+    register    Atom * atoms;
+    PropertyPtr * props;               /* array of pointer */
+    PropertyPtr pProp;
+    xEvent event;
+
+    REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2);
+    UpdateCurrentTime();
+    pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+					    SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!stuff->nAtoms)
+	return(Success);
+    atoms = (Atom *) & stuff[1];
+    props = (PropertyPtr *)ALLOCATE_LOCAL(stuff->nAtoms * sizeof(PropertyPtr));
+    if (!props)
+	return(BadAlloc);
+    for (i = 0; i < stuff->nAtoms; i++)
+    {
+#ifdef XCSECURITY
+	char action = SecurityCheckPropertyAccess(client, pWin, atoms[i],
+				SecurityReadAccess|SecurityWriteAccess);
+#endif
+        if (!ValidAtom(atoms[i])
+#ifdef XCSECURITY
+	    || (SecurityErrorOperation == action)
+#endif
+	   )
+        {
+            DEALLOCATE_LOCAL(props);
+	    client->errorValue = atoms[i];
+            return BadAtom;
+        }
+#ifdef XCSECURITY
+	if (SecurityIgnoreOperation == action)
+        {
+            DEALLOCATE_LOCAL(props);
+	    return Success;
+	}
+#endif
+        for (j = i + 1; j < stuff->nAtoms; j++)
+            if (atoms[j] == atoms[i])
+            {
+                DEALLOCATE_LOCAL(props);
+                return BadMatch;
+            }
+        pProp = wUserProps (pWin);
+        while (pProp)
+        {
+            if (pProp->propertyName == atoms[i])
+                goto found;
+	    pProp = pProp->next;
+        }
+        DEALLOCATE_LOCAL(props);
+        return BadMatch;
+found: 
+        props[i] = pProp;
+    }
+    delta = stuff->nPositions;
+
+    /* If the rotation is a complete 360 degrees, then moving the properties
+	around and generating PropertyNotify events should be skipped. */
+
+    if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) 
+    {
+	while (delta < 0)                  /* faster if abs value is small */
+            delta += stuff->nAtoms;
+    	for (i = 0; i < stuff->nAtoms; i++)
+ 	{
+	    /* Generate a PropertyNotify event for each property whose value
+		is changed in the order in which they appear in the request. */
+ 
+ 	    event.u.u.type = PropertyNotify;
+            event.u.property.window = pWin->drawable.id;
+    	    event.u.property.state = PropertyNewValue;
+	    event.u.property.atom = props[i]->propertyName;	
+	    event.u.property.time = currentTime.milliseconds;
+	    DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	
+            props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms];
+	}
+    }
+    DEALLOCATE_LOCAL(props);
+    return Success;
+}
+
+int 
+ProcChangeProperty(ClientPtr client)
+{	      
+    WindowPtr pWin;
+    char format, mode;
+    unsigned long len;
+    int sizeInBytes;
+    int totalSize;
+    int err;
+    REQUEST(xChangePropertyReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+    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(xChangePropertyReq, totalSize);
+
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+	return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return(BadAtom);
+    }
+    if (!ValidAtom(stuff->type))
+    {
+	client->errorValue = stuff->type;
+	return(BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					SecurityWriteAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+#ifdef LBX
+    err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+	 (int)format, (int)mode, len, TRUE, (pointer)&stuff[1], TRUE, NULL);
+#else
+    err = ChangeWindowProperty(pWin, stuff->property, stuff->type, (int)format,
+			       (int)mode, len, (pointer)&stuff[1], TRUE);
+#endif
+    if (err != Success)
+	return err;
+    else
+	return client->noClientException;
+}
+
+int
+ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format, 
+                     int mode, unsigned long len, pointer value, 
+                     Bool sendevent)
+{
+#ifdef LBX
+    return LbxChangeWindowProperty(NULL, pWin, property, type,
+				   format, mode, len, TRUE, value,
+				   sendevent, NULL);
+#else
+    PropertyPtr pProp;
+    xEvent event;
+    int sizeInBytes;
+    int totalSize;
+    pointer data;
+
+    sizeInBytes = format>>3;
+    totalSize = len * sizeInBytes;
+
+    /* first see if property already exists */
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+	if (pProp->propertyName == property)
+	    break;
+	pProp = pProp->next;
+    }
+    if (!pProp)   /* just add to list */
+    {
+	if (!pWin->optional && !MakeWindowOptional (pWin))
+	    return(BadAlloc);
+        pProp = (PropertyPtr)xalloc(sizeof(PropertyRec));
+	if (!pProp)
+	    return(BadAlloc);
+        data = (pointer)xalloc(totalSize);
+	if (!data && len)
+	{
+	    xfree(pProp);
+	    return(BadAlloc);
+	}
+        pProp->propertyName = property;
+        pProp->type = type;
+        pProp->format = format;
+        pProp->data = data;
+	if (len)
+	    memmove((char *)data, (char *)value, totalSize);
+	pProp->size = len;
+        pProp->next = pWin->optional->userProps;
+        pWin->optional->userProps = pProp;
+    }
+    else
+    {
+	/* 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 != pProp->format) && (mode != PropModeReplace))
+	    return(BadMatch);
+        if ((pProp->type != type) && (mode != PropModeReplace))
+            return(BadMatch);
+        if (mode == PropModeReplace)
+        {
+	    if (totalSize != pProp->size * (pProp->format >> 3))
+	    {
+	    	data = (pointer)xrealloc(pProp->data, totalSize);
+	    	if (!data && len)
+		    return(BadAlloc);
+            	pProp->data = data;
+	    }
+	    if (len)
+		memmove((char *)pProp->data, (char *)value, totalSize);
+	    pProp->size = len;
+    	    pProp->type = type;
+	    pProp->format = format;
+	}
+	else if (len == 0)
+	{
+	    /* do nothing */
+	}
+        else if (mode == PropModeAppend)
+        {
+	    data = (pointer)xrealloc(pProp->data,
+				     sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+            pProp->data = data;
+	    memmove(&((char *)data)[pProp->size * sizeInBytes], 
+		    (char *)value,
+		  totalSize);
+            pProp->size += len;
+	}
+        else if (mode == PropModePrepend)
+        {
+            data = (pointer)xalloc(sizeInBytes * (len + pProp->size));
+	    if (!data)
+		return(BadAlloc);
+	    memmove(&((char *)data)[totalSize], (char *)pProp->data, 
+		  (int)(pProp->size * sizeInBytes));
+            memmove((char *)data, (char *)value, totalSize);
+	    xfree(pProp->data);
+            pProp->data = data;
+            pProp->size += len;
+	}
+    }
+    if (sendevent)
+    {
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyNewValue;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+    return(Success);
+#endif
+}
+
+int
+DeleteProperty(WindowPtr pWin, Atom propName)
+{
+    PropertyPtr pProp, prevProp;
+    xEvent event;
+
+    if (!(pProp = wUserProps (pWin)))
+	return(Success);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == propName)
+	    break;
+        prevProp = pProp;
+	pProp = pProp->next;
+    }
+    if (pProp) 
+    {		    
+        if (prevProp == (PropertyPtr)NULL)      /* takes care of head */
+        {
+            if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+        }
+	else
+        {
+            prevProp->next = pProp->next;
+        }
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+        event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	xfree(pProp->data);
+        xfree(pProp);
+    }
+    return(Success);
+}
+
+void
+DeleteAllWindowProperties(WindowPtr pWin)
+{
+    PropertyPtr pProp, pNextProp;
+    xEvent event;
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+	pNextProp = pProp->next;
+        xfree(pProp->data);
+        xfree(pProp);
+	pProp = pNextProp;
+    }
+}
+
+static int
+NullPropertyReply(
+    ClientPtr client,
+    ATOM propertyType,
+    int format,
+    xGetPropertyReply *reply)
+{
+    reply->nItems = 0;
+    reply->length = 0;
+    reply->bytesAfter = 0;
+    reply->propertyType = propertyType;
+    reply->format = format;
+    WriteReplyToClient(client, sizeof(xGenericReply), reply);
+    return(client->noClientException);
+}
+
+/*****************
+ * GetProperty
+ *    If type Any is specified, returns the property from the specified
+ *    window regardless of its type.  If a type is specified, returns the
+ *    property only if its type equals the specified type.
+ *    If delete is True and a property is returned, the property is also
+ *    deleted from the window and a PropertyNotify event is generated on the
+ *    window.
+ *****************/
+
+int
+ProcGetProperty(ClientPtr client)
+{
+    PropertyPtr pProp, prevProp;
+    unsigned long n, len, ind;
+    WindowPtr pWin;
+    xGetPropertyReply reply;
+    REQUEST(xGetPropertyReq);
+
+    REQUEST_SIZE_MATCH(xGetPropertyReq);
+    if (stuff->delete)
+	UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityReadAccess);
+    if (!pWin)
+	return BadWindow;
+
+    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);
+    }
+
+    pProp = wUserProps (pWin);
+    prevProp = (PropertyPtr)NULL;
+    while (pProp)
+    {
+	if (pProp->propertyName == stuff->property) 
+	    break;
+	prevProp = pProp;
+	pProp = pProp->next;
+    }
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    if (!pProp) 
+	return NullPropertyReply(client, None, 0, &reply);
+
+#ifdef XCSECURITY
+    {
+	Mask access_mode = SecurityReadAccess;
+
+	if (stuff->delete)
+	    access_mode |= SecurityDestroyAccess;
+	switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+					   access_mode))
+	{
+	    case SecurityErrorOperation:
+		client->errorValue = stuff->property;
+		return BadAtom;;
+	    case SecurityIgnoreOperation:
+		return NullPropertyReply(client, pProp->type, pProp->format,
+					 &reply);
+	}
+    }
+#endif
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((stuff->type != pProp->type) &&
+	 (stuff->type != AnyPropertyType))
+       )
+    {
+	reply.bytesAfter = pProp->size;
+	reply.format = pProp->format;
+	reply.length = 0;
+	reply.nItems = 0;
+	reply.propertyType = pProp->type;
+	WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+	return(Success);
+    }
+#ifdef LBX
+    /* make sure we have the current value */                       
+    if (pProp->tag_id && pProp->owner_pid) {
+	LbxStallPropRequest(client, pProp);
+	return client->noClientException;
+    }                                              
+#endif
+
+/*
+ *  Return type, format, value to client
+ */
+    n = (pProp->format/8) * pProp->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);
+
+    reply.bytesAfter = n - (ind + len);
+    reply.format = pProp->format;
+    reply.length = (len + 3) >> 2;
+    reply.nItems = len / (pProp->format / 8 );
+    reply.propertyType = pProp->type;
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* send the event */
+	xEvent event;
+
+	event.u.u.type = PropertyNotify;
+	event.u.property.window = pWin->drawable.id;
+	event.u.property.state = PropertyDelete;
+	event.u.property.atom = pProp->propertyName;
+	event.u.property.time = currentTime.milliseconds;
+	DeliverEvents(pWin, &event, 1, (WindowPtr)NULL);
+    }
+
+    WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+    if (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,
+				 (char *)pProp->data + ind);
+    }
+
+    if (stuff->delete && (reply.bytesAfter == 0))
+    { /* delete the Property */
+#ifdef LBX
+	if (pProp->tag_id)
+	    TagDeleteTag(pProp->tag_id);
+#endif
+	if (prevProp == (PropertyPtr)NULL) /* takes care of head */
+	{
+	    if (!(pWin->optional->userProps = pProp->next))
+		CheckWindowOptionalNeed (pWin);
+	}
+	else
+	    prevProp->next = pProp->next;
+	xfree(pProp->data);
+	xfree(pProp);
+    }
+    return(client->noClientException);
+}
+
+int
+ProcListProperties(ClientPtr client)
+{
+    Atom *pAtoms = NULL, *temppAtoms;
+    xListPropertiesReply xlpr;
+    int	numProps = 0;
+    WindowPtr pWin;
+    PropertyPtr pProp;
+    REQUEST(xResourceReq);
+
+    REQUEST_SIZE_MATCH(xResourceReq);
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+					   SecurityReadAccess);
+    if (!pWin)
+        return(BadWindow);
+
+    pProp = wUserProps (pWin);
+    while (pProp)
+    {        
+        pProp = pProp->next;
+	numProps++;
+    }
+    if (numProps)
+        if(!(pAtoms = (Atom *)ALLOCATE_LOCAL(numProps * sizeof(Atom))))
+            return(BadAlloc);
+
+    xlpr.type = X_Reply;
+    xlpr.nProperties = numProps;
+    xlpr.length = (numProps * sizeof(Atom)) >> 2;
+    xlpr.sequenceNumber = client->sequence;
+    pProp = wUserProps (pWin);
+    temppAtoms = pAtoms;
+    while (pProp)
+    {
+	*temppAtoms++ = pProp->propertyName;
+	pProp = pProp->next;
+    }
+    WriteReplyToClient(client, sizeof(xGenericReply), &xlpr);
+    if (numProps)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
+        DEALLOCATE_LOCAL(pAtoms);
+    }
+    return(client->noClientException);
+}
+
+int 
+ProcDeleteProperty(register ClientPtr client)
+{
+    WindowPtr pWin;
+    REQUEST(xDeletePropertyReq);
+    int result;
+              
+    REQUEST_SIZE_MATCH(xDeletePropertyReq);
+    UpdateCurrentTime();
+    pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+					   SecurityWriteAccess);
+    if (!pWin)
+        return(BadWindow);
+    if (!ValidAtom(stuff->property))
+    {
+	client->errorValue = stuff->property;
+	return (BadAtom);
+    }
+
+#ifdef XCSECURITY
+    switch(SecurityCheckPropertyAccess(client, pWin, stuff->property,
+				       SecurityDestroyAccess))
+    {
+	case SecurityErrorOperation:
+	    client->errorValue = stuff->property;
+	    return BadAtom;;
+	case SecurityIgnoreOperation:
+	    return Success;
+    }
+#endif
+
+    result = DeleteProperty(pWin, stuff->property);
+    if (client->noClientException != Success)
+	return(client->noClientException);
+    else
+	return(result);
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
new file mode 100644
index 000000000..426d15b1b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
@@ -0,0 +1,1344 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
new file mode 100644
index 000000000..426d15b1b
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
@@ -0,0 +1,1344 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* 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/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
new file mode 100644
index 000000000..3911a3498
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
@@ -0,0 +1,1319 @@
+/*
+ * $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 "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;
+}
+		
+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;
+#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++)
+	{
+	    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;
+    
+    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/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
new file mode 100644
index 000000000..00c55cde7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -0,0 +1,3799 @@
+/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.12 2005/08/28 19:47:39 ajax Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.27tsi Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/render.h>
+#include <X11/extensions/renderproto.h>
+#include <X11/Xfuncproto.h>
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+#include "Cursor.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+/*
+ * From NXmiglyph.c.
+ */
+
+void miGlyphExtents(int nlist, GlyphListPtr list,
+                        GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * From NXmitrap.c.
+ */
+
+void miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+/*
+ * Functions from Render.c.
+ */
+
+int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+int  nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
+void nxagentChangePicture(PicturePtr, Mask);
+int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
+void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
+                          INT16, INT16, INT16, INT16, CARD16, CARD16);
+void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
+void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+                                 pointer params, int nparams);
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
+                           INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
+
+/*
+ * The void pointer is actually a XGlyphElt8.
+ */
+
+void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
+                       INT16, INT16, int, void *, int, GlyphPtr *);
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    ProcRenderQueryVersion,
+    ProcRenderQueryPictFormats,
+    ProcRenderQueryPictIndexValues,
+    ProcRenderQueryDithers,
+    ProcRenderCreatePicture,
+    ProcRenderChangePicture,
+    ProcRenderSetPictureClipRectangles,
+    ProcRenderFreePicture,
+    ProcRenderComposite,
+    ProcRenderScale,
+    ProcRenderTrapezoids,
+    ProcRenderTriangles,
+    ProcRenderTriStrip,
+    ProcRenderTriFan,
+    ProcRenderColorTrapezoids,
+    ProcRenderColorTriangles,
+    ProcRenderTransform,
+    ProcRenderCreateGlyphSet,
+    ProcRenderReferenceGlyphSet,
+    ProcRenderFreeGlyphSet,
+    ProcRenderAddGlyphs,
+    ProcRenderAddGlyphsFromPicture,
+    ProcRenderFreeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderFillRectangles,
+    ProcRenderCreateCursor,
+    ProcRenderSetPictureTransform,
+    ProcRenderQueryFilters,
+    ProcRenderSetPictureFilter,
+    ProcRenderCreateAnimCursor,
+    ProcRenderAddTraps,
+    ProcRenderCreateSolidFill,
+    ProcRenderCreateLinearGradient,
+    ProcRenderCreateRadialGradient,
+    ProcRenderCreateConicalGradient
+};
+
+int	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    SProcRenderQueryVersion,
+    SProcRenderQueryPictFormats,
+    SProcRenderQueryPictIndexValues,
+    SProcRenderQueryDithers,
+    SProcRenderCreatePicture,
+    SProcRenderChangePicture,
+    SProcRenderSetPictureClipRectangles,
+    SProcRenderFreePicture,
+    SProcRenderComposite,
+    SProcRenderScale,
+    SProcRenderTrapezoids,
+    SProcRenderTriangles,
+    SProcRenderTriStrip,
+    SProcRenderTriFan,
+    SProcRenderColorTrapezoids,
+    SProcRenderColorTriangles,
+    SProcRenderTransform,
+    SProcRenderCreateGlyphSet,
+    SProcRenderReferenceGlyphSet,
+    SProcRenderFreeGlyphSet,
+    SProcRenderAddGlyphs,
+    SProcRenderAddGlyphsFromPicture,
+    SProcRenderFreeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderFillRectangles,
+    SProcRenderCreateCursor,
+    SProcRenderSetPictureTransform,
+    SProcRenderQueryFilters,
+    SProcRenderSetPictureFilter,
+    SProcRenderCreateAnimCursor,
+    SProcRenderAddTraps,
+    SProcRenderCreateSolidFill,
+    SProcRenderCreateLinearGradient,
+    SProcRenderCreateRadialGradient,
+    SProcRenderCreateConicalGradient
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+    
+#if 0
+static CARD8	RenderReqCode;
+#endif
+int	RenderErrBase;
+int	RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+    int	    major_version;
+    int	    minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient)    ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr	*list,
+		      pointer		closure,
+		      pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
+
+    pRenderClient->major_version = 0;
+    pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+    ExtensionEntry *extEntry;
+
+    if (!PictureType)
+	return;
+    if (!PictureFinishInit ())
+	return;
+    RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+    if (!AllocateClientPrivate (RenderClientPrivateIndex, 
+				sizeof (RenderClientRec)))
+	return;
+    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+	return;
+
+    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+			     ProcRenderDispatch, SProcRenderDispatch,
+			     RenderResetProc, StandardMinorOpcode);
+    if (!extEntry)
+	return;
+#if 0
+    RenderReqCode = (CARD8) extEntry->base;
+#endif
+    RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+    ResetPicturePrivateIndex();
+    ResetGlyphSetPrivateIndex();
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+    RenderClientPtr pRenderClient = GetRenderClient (client);
+    xRenderQueryVersionReply rep;
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    pRenderClient->major_version = stuff->majorVersion;
+    pRenderClient->minor_version = stuff->minorVersion;
+
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = nxagentRenderVersionMajor;
+    rep.minorVersion = nxagentRenderVersionMinor;
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.majorVersion, n);
+	swapl(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    DepthPtr    pDepth;
+    int		d, v;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = pScreen->allowedDepths + d;
+	for (v = 0; v < pDepth->numVids; v++)
+	{
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+	}
+    }
+    return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+    VisualPtr	pVisual;
+    int		v;
+
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = pScreen->visuals + v;
+	if (pVisual->vid == vid)
+	    return pVisual;
+    }
+    return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+    RenderClientPtr		    pRenderClient = GetRenderClient (client);
+    xRenderQueryPictFormatsReply    *reply;
+    xPictScreen			    *pictScreen;
+    xPictDepth			    *pictDepth;
+    xPictVisual			    *pictVisual;
+    xPictFormInfo		    *pictForm;
+    CARD32			    *pictSubpixel;
+    ScreenPtr			    pScreen;
+    VisualPtr			    pVisual;
+    DepthPtr			    pDepth;
+    int				    v, d;
+    PictureScreenPtr		    ps;
+    PictFormatPtr		    pFormat;
+    int				    nformat;
+    int				    ndepth;
+    int				    nvisual;
+    int				    rlength;
+    int				    s;
+    int				    n;
+    int				    numScreens;
+    int				    numSubpixel;
+
+    extern int                      nxagentAlphaEnabled;
+/*    REQUEST(xRenderQueryPictFormatsReq); */
+
+    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+    numScreens = screenInfo.numScreens;
+#endif
+    ndepth = nformat = nvisual = 0;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pDepth = pScreen->allowedDepths + d;
+	    ++ndepth;
+
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+		    ++nvisual;
+	    }
+	}
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    nformat += ps->nformats;
+    }
+    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+	numSubpixel = 0;
+    else
+	numSubpixel = numScreens;
+    
+    rlength = (sizeof (xRenderQueryPictFormatsReply) +
+	       nformat * sizeof (xPictFormInfo) +
+	       numScreens * sizeof (xPictScreen) +
+	       ndepth * sizeof (xPictDepth) +
+	       nvisual * sizeof (xPictVisual) +
+	       numSubpixel * sizeof (CARD32));
+    reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numFormats = nformat;
+    reply->numScreens = numScreens;
+    reply->numDepths = ndepth;
+    reply->numVisuals = nvisual;
+    reply->numSubpixel = numSubpixel;
+    
+    pictForm = (xPictFormInfo *) (reply + 1);
+    
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	{
+	    for (nformat = 0, pFormat = ps->formats; 
+		 nformat < ps->nformats;
+		 nformat++, pFormat++)
+	    {
+		pictForm->id = pFormat->id;
+		pictForm->type = pFormat->type;
+		pictForm->depth = pFormat->depth;
+		pictForm->direct.red = pFormat->direct.red;
+		pictForm->direct.redMask = pFormat->direct.redMask;
+		pictForm->direct.green = pFormat->direct.green;
+		pictForm->direct.greenMask = pFormat->direct.greenMask;
+		pictForm->direct.blue = pFormat->direct.blue;
+		pictForm->direct.blueMask = pFormat->direct.blueMask;
+		pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+		    pictForm->colormap = pFormat->index.pColormap->mid;
+		else
+		    pictForm->colormap = None;
+		if (client->swapped)
+		{
+		    swapl (&pictForm->id, n);
+		    swaps (&pictForm->direct.red, n);
+		    swaps (&pictForm->direct.redMask, n);
+		    swaps (&pictForm->direct.green, n);
+		    swaps (&pictForm->direct.greenMask, n);
+		    swaps (&pictForm->direct.blue, n);
+		    swaps (&pictForm->direct.blueMask, n);
+		    swaps (&pictForm->direct.alpha, n);
+		    swaps (&pictForm->direct.alphaMask, n);
+		    swapl (&pictForm->colormap, n);
+		}
+		pictForm++;
+	    }
+	}
+    }
+    
+    pictScreen = (xPictScreen *) pictForm;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	pictDepth = (xPictDepth *) (pictScreen + 1);
+	ndepth = 0;
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pictVisual = (xPictVisual *) (pictDepth + 1);
+	    pDepth = pScreen->allowedDepths + d;
+
+	    nvisual = 0;
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && (pFormat = PictureMatchVisual (pScreen, 
+							      pDepth->depth, 
+							      pVisual)))
+		{
+		    pictVisual->visual = pVisual->vid;
+		    pictVisual->format = pFormat->id;
+		    if (client->swapped)
+		    {
+			swapl (&pictVisual->visual, n);
+			swapl (&pictVisual->format, n);
+		    }
+		    pictVisual++;
+		    nvisual++;
+		}
+	    }
+	    pictDepth->depth = pDepth->depth;
+	    pictDepth->nPictVisuals = nvisual;
+	    if (client->swapped)
+	    {
+		swaps (&pictDepth->nPictVisuals, n);
+	    }
+	    ndepth++;
+	    pictDepth = (xPictDepth *) pictVisual;
+	}
+	pictScreen->nDepth = ndepth;
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    pictScreen->fallback = ps->fallback->id;
+	else
+	    pictScreen->fallback = 0;
+	if (client->swapped)
+	{
+	    swapl (&pictScreen->nDepth, n);
+	    swapl (&pictScreen->fallback, n);
+	}
+	pictScreen = (xPictScreen *) pictDepth;
+    }
+    pictSubpixel = (CARD32 *) pictScreen;
+    
+    for (s = 0; s < numSubpixel; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    *pictSubpixel = ps->subpixel;
+	else
+	    *pictSubpixel = SubPixelUnknown;
+	if (client->swapped)
+	{
+	    swapl (pictSubpixel, n);
+	}
+	++pictSubpixel;
+    }
+    
+    if (client->swapped)
+    {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numFormats, n);
+	swapl (&reply->numScreens, n);
+	swapl (&reply->numDepths, n);
+	swapl (&reply->numVisuals, n);
+	swapl (&reply->numSubpixel, n);
+    }
+    WriteToClient(client, rlength, (char *) reply);
+    xfree (reply);
+    return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    PictFormatPtr   pFormat;
+    int		    num;
+    int		    rlength;
+    int		    i, n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    xRenderQueryPictIndexValuesReply *reply;
+    xIndexValue	    *values;
+
+    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->type != PictTypeIndexed)
+    {
+	client->errorValue = stuff->format;
+	return BadMatch;
+    }
+    num = pFormat->index.nvalues;
+    rlength = (sizeof (xRenderQueryPictIndexValuesReply) + 
+	       num * sizeof(xIndexValue));
+    reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numIndexValues = num;
+
+    values = (xIndexValue *) (reply + 1);
+    
+    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+    
+    if (client->swapped)
+    {
+	for (i = 0; i < num; i++)
+	{
+	    swapl (&values[i].pixel, n);
+	    swaps (&values[i].red, n);
+	    swaps (&values[i].green, n);
+	    swaps (&values[i].blue, n);
+	    swaps (&values[i].alpha, n);
+	}
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numIndexValues, n);
+    }
+
+    WriteToClient(client, rlength, (char *) reply);
+    xfree(reply);
+    return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    int		    len;
+    int		    error;
+    REQUEST(xRenderCreatePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+			     SecurityWriteAccess);
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->depth != pDrawable->depth)
+	return BadMatch;
+    len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    pPicture = CreatePicture (stuff->pid,
+			      pDrawable,
+			      pFormat,
+			      stuff->mask,
+			      (XID *) (stuff + 1),
+			      client,
+			      &error);
+    if (!pPicture)
+	return error;
+    nxagentCreatePicture(pPicture, stuff -> mask);
+
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    REQUEST(xRenderChangePictureReq);
+    int len;
+    int error;
+
+    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+
+    len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+			  (DevUnion *) 0, client);
+    
+    nxagentChangePicture(pPicture, stuff->mask);
+
+    return error;
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    PicturePtr	    pPicture;
+    int		    nr;
+    int		    result;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pPicture->pDrawable)
+        return BadDrawable;
+
+    /*
+     * The original code used sizeof(xRenderChangePictureReq).
+     * This was harmless, as both structures have the same size.
+     *
+     * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+     */
+    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+    if (nr & 4)
+	return BadLength;
+    nr >>= 3;
+    result = SetPictureClipRects (pPicture, 
+				  stuff->xOrigin, stuff->yOrigin,
+				  nr, (xRectangle *) &stuff[1]);
+    nxagentChangePictureClip (pPicture,
+                              CT_NONE,
+                              nr,
+                              (xRectangle *) &stuff[1],
+                              (int)stuff -> xOrigin,
+                              (int)stuff -> yOrigin);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+    PicturePtr	pPicture;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+		    RenderErrBase + BadPicture);
+
+    nxagentDestroyPicture(pPicture);
+
+    FreeResource (stuff->picture, RT_NONE);
+    return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+	return TRUE;
+    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+	return TRUE;
+    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Check if both pictures have drawables which are
+ * virtual pixmaps. See the corresponding define
+ * in NXpicture.c
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#define nxagentCompositePredicate(pSrc, pDst)  TRUE
+
+#else
+
+/*
+ * This is still under development. The final
+ * goal is to let pictures point to the real
+ * pixmaps instead of pointing to virtuals.
+ */
+
+int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
+{
+  PixmapPtr pPixmap1;
+  PixmapPtr pPixmap2;
+
+  pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pSrc -> pDrawable) : NULL);
+
+  pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pDst -> pDrawable) : NULL);
+
+  if (pPixmap1 == NULL || pPixmap2 == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
+    #endif
+
+    return FALSE;
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
+    #endif
+
+    if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
+            nxagentPixmapIsVirtual(pPixmap2) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
+      #endif
+
+      return TRUE;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
+  #endif
+
+  return FALSE;
+}
+
+#endif
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+    PicturePtr	pSrc, pMask, pDst;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
+		  RenderErrBase + BadPicture);
+    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
+
+    ValidatePicture (pSrc);
+    if (pMask)
+        ValidatePicture (pMask);
+    ValidatePicture (pDst);
+
+    #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+    if (nxagentCompositePredicate(pSrc, pDst))
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pMask, (void *) pDst);
+      #endif
+
+    CompositePicture (stuff->op,
+		      pSrc,
+		      pMask,
+		      pDst,
+		      stuff->xSrc,
+		      stuff->ySrc,
+		      stuff->xMask,
+		      stuff->yMask,
+		      stuff->xDst,
+		      stuff->yDst,
+		      stuff->width,
+		      stuff->height);
+    }
+
+    #else
+
+    if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+            pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
+    {
+      PixmapPtr pVirtualPixmapSrc;
+      PixmapPtr pVirtualPixmapDst;
+      PixmapPtr pVirtualPixmapMask;
+
+      PicturePtr pVirtualPictureSrc;
+      PicturePtr pVirtualPictureDst;
+      PicturePtr pVirtualPictureMask;
+
+      pVirtualPixmapSrc  = (PixmapPtr) pSrc  -> pDrawable;
+      pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
+
+      pVirtualPixmapDst  = (PixmapPtr) pDst  -> pDrawable;
+      pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
+
+      if (pMask)
+      {
+        pVirtualPixmapMask  = (PixmapPtr) pMask  -> pDrawable;
+        pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
+      }
+      else
+      {
+        pVirtualPixmapMask  = NULL;
+        pVirtualPictureMask = NULL;
+      }
+
+      if (pVirtualPictureSrc && pVirtualPictureDst)
+      {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
+                          (void *) pVirtualPixmapDst);
+      #endif
+
+      CompositePicture (stuff->op,
+                        pVirtualPictureSrc,
+                        pVirtualPictureMask,
+                        pVirtualPictureDst,
+                        stuff->xSrc,
+                        stuff->ySrc,
+                        stuff->xMask,
+                        stuff->yMask,
+                        stuff->xDst,
+                        stuff->yDst,
+                        stuff->width,
+                        stuff->height);
+      }
+    }
+
+    #endif
+
+    nxagentComposite (stuff -> op,
+                      pSrc,
+                      pMask,
+                      pDst,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      stuff -> xMask,
+                      stuff -> yMask,
+                      stuff -> xDst,
+                      stuff -> yDst,
+                      stuff -> width,
+                      stuff -> height);
+
+    return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+    if (ntraps % sizeof (xTrapezoid))
+	return BadLength;
+    ntraps /= sizeof (xTrapezoid);
+    if (ntraps)
+    {
+      if (pFormat != NULL)
+      {
+        nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+        miTrapezoidBounds (ntraps, (xTrapezoid *) &stuff[1], nxagentTrapezoidExtents);
+      }
+
+      if (nxagentCompositePredicate(pSrc, pDst) == 1)
+      {
+	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+			     stuff->xSrc, stuff->ySrc,
+			     ntraps, (xTrapezoid *) &stuff[1]);
+      }
+
+      nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
+                             stuff->xSrc, stuff->ySrc,
+                                 ntraps, (xTrapezoid *) &stuff[1]);
+
+      if (nxagentTrapezoidExtents != NullBox)
+      {
+        xfree(nxagentTrapezoidExtents);
+
+        nxagentTrapezoidExtents = NullBox;
+      }
+    }
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+    int		ntris;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+    if (ntris % sizeof (xTriangle))
+	return BadLength;
+    ntris /= sizeof (xTriangle);
+    if (ntris)
+	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+			    stuff->xSrc, stuff->ySrc,
+			    ntris, (xTriangle *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+			   stuff->xSrc, stuff->ySrc,
+			   npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+			 stuff->xSrc, stuff->ySrc,
+			 npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr	    glyphSet;
+    PictFormatPtr   format;
+    int		    f;
+    REQUEST(xRenderCreateGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+    format = (PictFormatPtr) SecurityLookupIDByType (client,
+						     stuff->format,
+						     PictFormatType,
+						     SecurityReadAccess);
+    if (!format)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    switch (format->depth) {
+    case 1:
+	f = GlyphFormat1;
+	break;
+    case 4:
+	f = GlyphFormat4;
+	break;
+    case 8:
+	f = GlyphFormat8;
+	break;
+    case 16:
+	f = GlyphFormat16;
+	break;
+    case 32:
+	f = GlyphFormat32;
+	break;
+    default:
+	return BadMatch;
+    }
+    if (format->type != PictTypeDirect)
+	return BadMatch;
+    glyphSet = AllocateGlyphSet (f, format);
+    if (!glyphSet)
+	return BadAlloc;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+
+    nxagentCreateGlyphSet(glyphSet);
+
+    return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderReferenceGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->existing,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->existing;
+	return RenderErrBase + BadGlyphSet;
+    }
+    glyphSet->refcnt++;
+
+    nxagentReferenceGlyphSet(glyphSet);
+
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return client->noClientException;
+}
+
+#define NLOCALDELTA	64
+#define NLOCALGLYPH	256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderFreeGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityDestroyAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nxagentFreeGlyphSet(glyphSet);
+
+    FreeResource (stuff->glyphset, RT_NONE);
+    return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+    Glyph	id;
+    GlyphPtr    glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderAddGlyphsReq);
+    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
+    GlyphNewPtr	    glyphsBase, glyphs;
+    GlyphPtr	    glyph = NULL;
+    int		    remain, nglyphs;
+    CARD32	    *gids;
+    xGlyphInfo	    *gi;
+    CARD8	    *bits;
+    int		    size;
+    int		    err = BadAlloc;
+
+    int             totSizeImages;
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nglyphs = stuff->nglyphs;
+    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
+	    return BadAlloc;
+
+    if (nglyphs <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+
+    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+    glyphs = glyphsBase;
+
+    totSizeImages = 0;
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + nglyphs);
+    bits = (CARD8 *) (gi + nglyphs);
+    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+
+    while (remain >= 0 && nglyphs)
+    {
+	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+	if (!glyph)
+	{
+	    err = BadAlloc;
+	    goto bail;
+	}
+	
+	glyphs->glyph = glyph;
+	glyphs->id = *gids;	
+	
+	size = glyph->size - sizeof (xGlyphInfo);
+	if (remain < size)
+	    break;
+	memcpy ((CARD8 *) (glyph + 1), bits, size);
+	
+	if (size & 3)
+	    size += 4 - (size & 3);
+	bits += size;
+	totSizeImages += size;
+	remain -= size;
+	gi++;
+	gids++;
+	glyphs++;
+	nglyphs--;
+    }
+
+    if (nglyphs || remain)
+    {
+	err = BadLength;
+	goto bail;
+    }
+    nglyphs = stuff->nglyphs;
+    if (!ResizeGlyphSet (glyphSet, nglyphs))
+    {
+	err = BadAlloc;
+	goto bail;
+    }
+    glyphs = glyphsBase;
+    while (nglyphs--) {
+	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+	glyphs++;
+    }
+
+    if (glyphsBase != glyphsLocal)
+	Xfree (glyphsBase);
+    return client->noClientException;
+bail:
+    while (glyphs != glyphsBase)
+    {
+	--glyphs;
+	xfree (glyphs->glyph);
+    }
+    if (glyphsBase != glyphsLocal)
+	Xfree (glyphsBase);
+    return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+    REQUEST(xRenderFreeGlyphsReq);
+    GlyphSetPtr     glyphSet;
+    int		    nglyph;
+    CARD32	    *gids;
+    CARD32	    glyph;
+
+    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+    gids = (CARD32 *) (stuff + 1);
+
+    nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
+    while (nglyph-- > 0)
+    {
+	glyph = *gids++;
+	if (!DeleteGlyph (glyphSet, glyph))
+	{
+	    client->errorValue = glyph;
+	    return RenderErrBase + BadGlyph;
+	}
+    }
+    return client->noClientException;
+}
+
+typedef struct XGlyphElt8{
+    GlyphSet                glyphset;
+    _Xconst char            *chars;
+    int                     nchars;
+    int                     xOff;
+    int                     yOff;
+} XGlyphElt8;
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    GlyphSet	    gs;
+    PicturePtr      pSrc, pDst;
+    PictFormatPtr   pFormat;
+    GlyphListRec    listsLocal[NLOCALDELTA];
+    GlyphListPtr    lists, listsBase;
+    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
+    Glyph	    glyph;
+    GlyphPtr	    *glyphs, *glyphsBase;
+    xGlyphElt	    *elt;
+    CARD8	    *buffer, *end;
+    int		    nglyph;
+    int		    nlist;
+    int		    space;
+    int		    size;
+    int		    n;
+    
+    XGlyphElt8      *elements, *elementsBase;
+
+    REQUEST(xRenderCompositeGlyphsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityReadAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    nglyph = 0;
+    nlist = 0;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    buffer += 4;
+	}
+	else
+	{
+	    nlist++;
+	    nglyph += elt->len;
+	    space = size * elt->len;
+	    if (space & 3)
+		space += 4 - (space & 3);
+	    buffer += space;
+	}
+    }
+    if (nglyph <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+    if (nlist <= NLOCALDELTA)
+	listsBase = listsLocal;
+    else
+    {
+	listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+	if (!listsBase)
+	    return BadAlloc;
+    }
+
+    elementsBase = xalloc(nlist * sizeof(XGlyphElt8));
+    if (!elementsBase)
+      return BadAlloc;
+
+    buffer = (CARD8 *) (stuff + 1);
+    glyphs = glyphsBase;
+    lists = listsBase;
+    elements = elementsBase;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+            #ifdef DEBUG
+            fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+                        size);
+            #endif
+
+	    if (buffer + sizeof (GlyphSet) < end)
+	    {
+                memcpy(&gs, buffer, sizeof(GlyphSet));
+		glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+								 gs,
+								 GlyphSetType,
+								 SecurityReadAccess);
+		if (!glyphSet)
+		{
+		    client->errorValue = gs;
+		    if (glyphsBase != glyphsLocal)
+			DEALLOCATE_LOCAL (glyphsBase);
+		    if (listsBase != listsLocal)
+			DEALLOCATE_LOCAL (listsBase);
+		    return RenderErrBase + BadGlyphSet;
+		}
+	    }
+	    buffer += 4;
+	}
+	else
+	{
+	    lists->xOff = elt->deltax;
+	    lists->yOff = elt->deltay;
+	    lists->format = glyphSet->format;
+	    lists->len = 0;
+
+            if (glyphSet -> remoteID == 0)
+            {
+              #ifdef TEST
+              fprintf(stderr, "ProcRenderCompositeGlyphs: Going to reconnect glyphset at [%p].\n",
+                          (void *) glyphSet);
+              #endif
+
+              nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
+            }
+
+            elements -> glyphset = glyphSet -> remoteID;
+            elements -> chars = (char *) buffer;
+            elements -> nchars = elt->len;
+            elements -> xOff = elt->deltax;
+            elements -> yOff = elt->deltay;
+	    n = elt->len;
+	    while (n--)
+	    {
+		if (buffer + size <= end)
+		{
+		    switch (size) {
+		    case 1:
+			glyph = *((CARD8 *)buffer); break;
+		    case 2:
+			glyph = *((CARD16 *)buffer); break;
+		    case 4:
+		    default:
+			glyph = *((CARD32 *)buffer); break;
+		    }
+		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
+		    {
+			lists->len++;
+			glyphs++;
+		    }
+		}
+		buffer += size;
+	    }
+	    space = size * elt->len;
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	    lists++;
+            elements++;
+	}
+    }
+    if (buffer > end)
+	return BadLength;
+
+    /*
+     * We need to know the glyphs extents to synchronize
+     * the drawables involved in the composite text ope-
+     * ration. Also we need to synchronize only the back-
+     * ground of the text we are going to render, so the
+     * operations on the framebuffer must be executed
+     * after the X requests.
+     */
+
+    nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+    miGlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
+
+    nxagentGlyphs(stuff -> op,
+                  pSrc,
+                  pDst,
+                  pFormat,
+                  stuff -> xSrc,
+                  stuff -> ySrc,
+                  nlist,
+                  elementsBase,
+                  size,
+                  glyphsBase);
+
+    if (nxagentCompositePredicate(pSrc, pDst) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
+                  "source at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pDst);
+      #endif
+
+      CompositeGlyphs(stuff -> op,
+                      pSrc,
+                      pDst,
+                      pFormat,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      nlist,
+                      listsBase,
+                      glyphsBase);
+    }
+
+    xfree(nxagentGlyphsExtents);
+    nxagentGlyphsExtents = NullBox;
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    if (listsBase != listsLocal)
+	DEALLOCATE_LOCAL (listsBase);
+    
+    xfree(elementsBase);
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+    PicturePtr	    pDst;
+    int             things;
+    REQUEST(xRenderFillRectanglesReq);
+    
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    
+    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+    
+    CompositeRects (stuff->op,
+		    pDst,
+		    &stuff->color,
+		    things,
+		    (xRectangle *) &stuff[1]);
+
+    ValidatePicture (pDst);
+    nxagentCompositeRects(stuff -> op,
+                          pDst,
+                          &stuff -> color,
+                          things,
+                          (xRectangle *) &stuff[1]);
+    
+    return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+    unsigned char   mask;
+    
+    if (screenInfo.bitmapBitOrder == LSBFirst)
+	mask = (1 << (x & 7));
+    else
+	mask = (0x80 >> (x & 7));
+    /* XXX assumes byte order is host byte order */
+    line += (x >> 3);
+    if (bit)
+	*line |= mask;
+    else
+	*line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+    {  1,  3,  },
+    {  4,  2,  },
+};
+
+#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateCursorReq);
+    PicturePtr	    pSrc;
+    ScreenPtr	    pScreen;
+    unsigned short  width, height;
+    CARD32	    *argbbits, *argb;
+    unsigned char   *srcbits, *srcline;
+    unsigned char   *mskbits, *mskline;
+    int		    stride;
+    int		    x, y;
+    int		    nbytes_mono;
+    CursorMetricRec cm;
+    CursorPtr	    pCursor;
+    CARD32	    twocolor[3];
+    int		    ncolor;
+
+    RealizeCursorProcPtr saveRealizeCursor;
+
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pSrc->pDrawable)
+        return BadDrawable;
+    pScreen = pSrc->pDrawable->pScreen;
+    width = pSrc->pDrawable->width;
+    height = pSrc->pDrawable->height;
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+    argbbits = xalloc (width * height * sizeof (CARD32));
+    if (!argbbits)
+	return (BadAlloc);
+    
+    stride = BitmapBytePad(width);
+    nbytes_mono = stride*height;
+    srcbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!srcbits)
+    {
+	xfree (argbbits);
+	return (BadAlloc);
+    }
+    mskbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!mskbits)
+    {
+	xfree(argbbits);
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+    bzero ((char *) mskbits, nbytes_mono);
+    bzero ((char *) srcbits, nbytes_mono);
+
+    if (pSrc->format == PICT_a8r8g8b8)
+    {
+	(*pScreen->GetImage) (pSrc->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+    }
+    else
+    {
+	PixmapPtr	pPixmap;
+	PicturePtr	pPicture;
+	PictFormatPtr	pFormat;
+	int		error;
+
+	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+	if (!pFormat)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadImplementation);
+	}
+	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+	if (!pPixmap)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadAlloc);
+	}
+	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, 
+				  client, &error);
+	if (!pPicture)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return error;
+	}
+	(*pScreen->DestroyPixmap) (pPixmap);
+	CompositePicture (PictOpSrc,
+			  pSrc, 0, pPicture,
+			  0, 0, 0, 0, 0, 0, width, height);
+	(*pScreen->GetImage) (pPicture->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+	FreePicture (pPicture, 0);
+    }
+    /*
+     * Check whether the cursor can be directly supported by 
+     * the core cursor code
+     */
+    ncolor = 0;
+    argb = argbbits;
+    for (y = 0; ncolor <= 2 && y < height; y++)
+    {
+	for (x = 0; ncolor <= 2 && x < width; x++)
+	{
+	    CARD32  p = *argb++;
+	    CARD32  a = (p >> 24);
+
+	    if (a == 0)	    /* transparent */
+		continue;
+	    if (a == 0xff)  /* opaque */
+	    {
+		int n;
+		for (n = 0; n < ncolor; n++)
+		    if (p == twocolor[n])
+			break;
+		if (n == ncolor)
+		    twocolor[ncolor++] = p;
+	    }
+	    else
+		ncolor = 3;
+	}
+    }
+    
+    /*
+     * Convert argb image to two plane cursor
+     */
+    srcline = srcbits;
+    mskline = mskbits;
+    argb = argbbits;
+    for (y = 0; y < height; y++)
+    {
+	for (x = 0; x < width; x++)
+	{
+	    CARD32  p = *argb++;
+
+	    if (ncolor <= 2)
+	    {
+		CARD32	a = ((p >> 24));
+
+		SetBit (mskline, x, a != 0);
+		SetBit (srcline, x, a != 0 && p == twocolor[0]);
+	    }
+	    else
+	    {
+		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+		/* Set mask from dithered alpha value */
+		SetBit(mskline, x, a > d);
+		/* Set src from dithered intensity value */
+		SetBit(srcline, x, a > d && i <= d);
+	    }
+	}
+	srcline += stride;
+	mskline += stride;
+    }
+    /*
+     * Dither to white and black if the cursor has more than two colors
+     */
+    if (ncolor > 2)
+    {
+	twocolor[0] = 0xff000000;
+	twocolor[1] = 0xffffffff;
+    }
+    else
+    {
+	xfree (argbbits);
+	argbbits = 0;
+    }
+    
+#define GetByte(p,s)	(((p) >> (s)) & 0xff)
+#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
+    
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+
+    /*
+     * This cursor uses RENDER, so we make sure
+     * that it is allocated in a way that allows
+     * the mi and dix layers to handle it but we
+     * later create it on the server by mirror-
+     * ing the RENDER operation we got from the
+     * client.
+     */
+
+    saveRealizeCursor = pScreen -> RealizeCursor;
+
+    pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
+
+    pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+			       GetColor(twocolor[0], 16),
+			       GetColor(twocolor[0], 8),
+			       GetColor(twocolor[0], 0),
+			       GetColor(twocolor[1], 16),
+			       GetColor(twocolor[1], 8),
+			       GetColor(twocolor[1], 0));
+
+    pScreen -> RealizeCursor = saveRealizeCursor;
+
+    /*
+     * Store into the private data members the
+     * information needed to recreate it at
+     * reconnection. This is done in two steps
+     * as in the first step we don't have the
+     * picture info.
+     */
+
+    if (pCursor == NULL)
+    {
+      return BadAlloc;
+    }
+
+    nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
+
+    nxagentRenderRealizeCursor(pScreen, pCursor);
+
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return (client->noClientException);
+    return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    PicturePtr	pPicture;
+    int		result;
+
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+
+    nxagentSetPictureTransform(pPicture, &stuff->transform);
+    
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+    REQUEST (xRenderQueryFiltersReq);
+    DrawablePtr			pDrawable;
+    xRenderQueryFiltersReply	*reply;
+    int				nbytesName;
+    int				nnames;
+    ScreenPtr			pScreen;
+    PictureScreenPtr		ps;
+    int				i, j;
+    int				len;
+    int				total_bytes;
+    INT16			*aliases;
+    char			*names;
+
+    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+    
+    pScreen = pDrawable->pScreen;
+    nbytesName = 0;
+    nnames = 0;
+    ps = GetPictureScreenIfSet(pScreen);
+    if (ps)
+    {
+	for (i = 0; i < ps->nfilters; i++)
+	    nbytesName += 1 + strlen (ps->filters[i].name);
+	for (i = 0; i < ps->nfilterAliases; i++)
+	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+	nnames = ps->nfilters + ps->nfilterAliases;
+    }
+    len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+    reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+    if (!reply)
+	return BadAlloc;
+    aliases = (INT16 *) (reply + 1);
+    names = (char *) (aliases + ((nnames + 1) & ~1));
+    
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = len;
+    reply->numAliases = nnames;
+    reply->numFilters = nnames;
+    if (ps)
+    {
+
+	/* fill in alias values */
+	for (i = 0; i < ps->nfilters; i++)
+	    aliases[i] = FilterAliasNone;
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    for (j = 0; j < ps->nfilters; j++)
+		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+		    break;
+	    if (j == ps->nfilters)
+	    {
+		for (j = 0; j < ps->nfilterAliases; j++)
+		    if (ps->filterAliases[i].filter_id == 
+			ps->filterAliases[j].alias_id)
+		    {
+			break;
+		    }
+		if (j == ps->nfilterAliases)
+		    j = FilterAliasNone;
+		else
+		    j = j + ps->nfilters;
+	    }
+	    aliases[i + ps->nfilters] = j;
+	}
+
+	/* fill in filter names */
+	for (i = 0; i < ps->nfilters; i++)
+	{
+	    j = strlen (ps->filters[i].name);
+	    *names++ = j;
+	    strncpy (names, ps->filters[i].name, j);
+	    names += j;
+	}
+	
+	/* fill in filter alias names */
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    j = strlen (ps->filterAliases[i].alias);
+	    *names++ = j;
+	    strncpy (names, ps->filterAliases[i].alias, j);
+	    names += j;
+	}
+    }
+
+    if (client->swapped)
+    {
+	register int n;
+
+	for (i = 0; i < (int)reply->numAliases; i++)
+	{
+	    swaps (&aliases[i], n);
+	}
+    	swaps(&reply->sequenceNumber, n);
+    	swapl(&reply->length, n);
+	swapl(&reply->numAliases, n);
+	swapl(&reply->numFilters, n);
+    }
+    WriteToClient(client, total_bytes, (char *) reply);
+    xfree (reply);
+    
+    return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST (xRenderSetPictureFilterReq);
+    PicturePtr	pPicture;
+    int		result;
+    xFixed	*params;
+    int		nparams;
+    char	*name;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    name = (char *) (stuff + 1);
+    params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+
+    nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
+
+    return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateAnimCursorReq);
+    CursorPtr	    *cursors;
+    CARD32	    *deltas;
+    CursorPtr	    pCursor;
+    int		    ncursor;
+    xAnimCursorElt  *elt;
+    int		    i;
+    int		    ret;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    if (client->req_len & 1)
+	return BadLength;
+    ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+    cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+    if (!cursors)
+	return BadAlloc;
+    deltas = (CARD32 *) (cursors + ncursor);
+    elt = (xAnimCursorElt *) (stuff + 1);
+    for (i = 0; i < ncursor; i++)
+    {
+	cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+						       RT_CURSOR, SecurityReadAccess);
+	if (!cursors[i])
+	{
+	    xfree (cursors);
+	    client->errorValue = elt->cursor;
+	    return BadCursor;
+	}
+	deltas[i] = elt->delay;
+	elt++;
+    }
+    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+    xfree (cursors);
+    if (ret != Success)
+	return ret;
+
+    nxagentAnimCursorBits = pCursor -> bits;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+      pCursor -> devPriv[i] = NULL;
+    }
+
+    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+static int
+ProcRenderAddTraps (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pPicture;
+    REQUEST(xRenderAddTrapsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pPicture->pDrawable)
+        return BadDrawable;
+    ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+    if (ntraps % sizeof (xTrap))
+	return BadLength;
+    ntraps /= sizeof (xTrap);
+    if (ntraps)
+	AddTraps (pPicture,
+		  stuff->xOff, stuff->yOff,
+		  ntraps, (xTrap *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    error = 0;
+    REQUEST(xRenderCreateSolidFillReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateLinearGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+                                            stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateRadialGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+                                            stuff->inner_radius, stuff->outer_radius,
+                                            stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateConicalGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+                                             stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        #ifdef TEST
+        fprintf(stderr, "ProcRenderDispatch: Request [%s] OPCODE#%d.\n",
+                    nxagentRenderRequestLiteral[stuff->data], stuff->data);
+        #endif
+
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*ProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->majorVersion, n);
+    swapl(&stuff->minorVersion, n);
+    return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictFormatsReq);
+    swaps(&stuff->length, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreatePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->format, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderChangePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCompositeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->mask, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xMask, n);
+    swaps(&stuff->yMask, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderScaleReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->colorScale, n);
+    swapl(&stuff->alphaScale, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriStripReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriFanReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderReferenceGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->existing, n);
+    return (*ProcRenderVector[stuff->renderReqType])  (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+    register int n;
+    register unsigned int i;
+    CARD32  *gids;
+    void    *end;
+    xGlyphInfo *gi;
+    REQUEST(xRenderAddGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    swapl(&stuff->nglyphs, n);
+    if (stuff->nglyphs & 0xe0000000)
+	return BadLength;
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+	return BadLength;
+    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+	return BadLength;
+    for (i = 0; i < stuff->nglyphs; i++)
+    {
+	swapl (&gids[i], n);
+	swaps (&gi[i].width, n);
+	swaps (&gi[i].height, n);
+	swaps (&gi[i].x, n);
+	swaps (&gi[i].y, n);
+	swaps (&gi[i].xOff, n);
+	swaps (&gi[i].yOff, n);
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+    register int n;
+    xGlyphElt	*elt;
+    CARD8	*buffer;
+    CARD8	*end;
+    int		space;
+    int		i;
+    int		size;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+    
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->maskFormat, n);
+    swapl(&stuff->glyphset, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	swaps (&elt->deltax, n);
+	swaps (&elt->deltay, n);
+	
+	i = elt->len;
+	if (i == 0xff)
+	{
+	    swapl (buffer, n);
+	    buffer += 4;
+	}
+	else
+	{
+	    space = size * i;
+	    switch (size) {
+	    case 1:
+		buffer += i;
+		break;
+	    case 2:
+		while (i--)
+		{
+		    swaps (buffer, n);
+		    buffer += 2;
+		}
+		break;
+	    case 4:
+		while (i--)
+		{
+		    swapl (buffer, n);
+		    buffer += 4;
+		}
+		break;
+	    }
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	}
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFillRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    swaps(&stuff->color.alpha, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateCursorReq);
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    swapl(&stuff->src, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureTransformReq);
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->transform.matrix11, n);
+    swapl(&stuff->transform.matrix12, n);
+    swapl(&stuff->transform.matrix13, n);
+    swapl(&stuff->transform.matrix21, n);
+    swapl(&stuff->transform.matrix22, n);
+    swapl(&stuff->transform.matrix23, n);
+    swapl(&stuff->transform.matrix31, n);
+    swapl(&stuff->transform.matrix32, n);
+    swapl(&stuff->transform.matrix33, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderQueryFiltersReq);
+    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderSetPictureFilterReq);
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->nbytes, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateAnimCursorReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddTraps (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderAddTrapsReq);
+    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->xOff, n);
+    swaps(&stuff->yOff, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateSolidFillReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swaps(&stuff->color.alpha, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int n)
+{
+    int i;
+    CARD32 *stops;
+    CARD16 *colors;
+    stops = (CARD32 *)(stuff);
+    for (i = 0; i < n; ++i) {
+        swapl(stops, n);
+        ++stops;
+    }
+    colors = (CARD16 *)(stops);
+    for (i = 0; i < 4*n; ++i) {
+        swaps(stops, n);
+        ++stops;
+    }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateLinearGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->p1.x, n);
+    swapl(&stuff->p1.y, n);
+    swapl(&stuff->p2.x, n);
+    swapl(&stuff->p2.y, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateRadialGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->inner.x, n);
+    swapl(&stuff->inner.y, n);
+    swapl(&stuff->outer.x, n);
+    swapl(&stuff->outer.y, n);
+    swapl(&stuff->inner_radius, n);
+    swapl(&stuff->outer_radius, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateConicalGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->center.x, n);
+    swapl(&stuff->center.y, n);
+    swapl(&stuff->angle, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+    
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*SProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+int	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long	XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+    REQUEST(xRenderCreatePictureReq);
+    PanoramiXRes    *refDraw, *newPict;
+    int		    result = Success, j;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+    if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+    if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+    newPict->type = XRT_PICTURE;
+    newPict->info[0].id = stuff->pid;
+    
+    if (refDraw->type == XRT_WINDOW &&
+	stuff->drawable == WindowTable[0]->drawable.id)
+    {
+	newPict->u.pict.root = TRUE;
+    }
+    else
+	newPict->u.pict.root = FALSE;
+
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPict->info[j].id = FakeClientID(client->index);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->pid = newPict->info[j].id;
+	stuff->drawable = refDraw->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+	if(result != Success) break;
+    }
+
+    if (result == Success)
+	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+    else 
+	xfree(newPict);
+
+    return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+    PanoramiXRes    *pict;
+    int		    result = Success, j;
+    REQUEST(xRenderChangePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureFilterReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+    PanoramiXRes *pict;
+    int         result = Success, j;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    client->errorValue = stuff->picture;
+
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+		       RenderErrBase + BadPicture);
+    
+
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->picture = pict->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+	if(result != Success) break;
+    }
+
+    /* Since ProcRenderFreePicture is using FreeResource, it will free
+	our resource for us on the last pass through the loop above */
+ 
+    return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+    PanoramiXRes	*src, *msk, *dst;
+    int			result = Success, j;
+    xRenderCompositeReq	orig;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess, 
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess, 
+		      RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    
+    orig = *stuff;
+    
+    FOR_NSCREENS_FORWARD(j) {
+	stuff->src = src->info[j].id;
+	if (src->u.pict.root)
+	{
+	    stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+	    stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+	}
+	stuff->dst = dst->info[j].id;
+	if (dst->u.pict.root)
+	{
+	    stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+	    stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+	}
+	if (msk)
+	{
+	    stuff->mask = msk->info[j].id;
+	    if (msk->u.pict.root)
+	    {
+		stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+		stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+	    }
+	}
+	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+	if(result != Success) break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+    PanoramiXRes    *src, *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderCompositeGlyphsReq);
+    xGlyphElt	    origElt, *elt;
+    INT16	    xSrc, ySrc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+				 sizeof (xGlyphElt)))
+    {
+	elt = (xGlyphElt *) (stuff + 1);
+	origElt = *elt;
+	xSrc = stuff->xSrc;
+	ySrc = stuff->ySrc;
+	FOR_NSCREENS_FORWARD(j) {
+	    stuff->src = src->info[j].id;
+	    if (src->u.pict.root)
+	    {
+		stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+		stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+	    }
+	    stuff->dst = dst->info[j].id;
+	    if (dst->u.pict.root)
+	    {
+		elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+		elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+	    if(result != Success) break;
+	}
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+    PanoramiXRes    *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderFillRectanglesReq);
+    char	    *extra;
+    int		    extra_len;
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root)
+	    {
+		int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+		    xRectangle	*rects = (xRectangle *) (stuff + 1);
+		    int		i = extra_len / sizeof (xRectangle);
+
+		    while (i--)
+		    {
+			rects->x -= x_off;
+			rects->y -= y_off;
+			rects++;
+		    }
+		}
+	    }
+	    stuff->dst = dst->info[j].id;
+	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTrapezoids(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTrapezoidsReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xTrapezoid  *trap = (xTrapezoid *) (stuff + 1);
+		    int         i = extra_len / sizeof (xTrapezoid);
+
+		    while (i--) {
+			trap->top -= y_off;
+			trap->bottom -= y_off;
+			trap->left.p1.x -= x_off;
+			trap->left.p1.y -= y_off;
+			trap->left.p2.x -= x_off;
+			trap->left.p2.y -= y_off;
+			trap->right.p1.x -= x_off;
+			trap->right.p1.y -= y_off;
+			trap->right.p2.x -= x_off;
+			trap->right.p2.y -= y_off;
+			trap++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriangles(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTrianglesReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xTriangle  *tri = (xTriangle *) (stuff + 1);
+		    int         i = extra_len / sizeof (xTriangle);
+
+		    while (i--) {
+			tri->p1.x -= x_off;
+			tri->p1.y -= y_off;
+			tri->p2.x -= x_off;
+			tri->p2.y -= y_off;
+			tri->p3.x -= x_off;
+			tri->p3.y -= y_off;
+			tri++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriStrip(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTriStripReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
+		    int         i = extra_len / sizeof (xPointFixed);
+
+		    while (i--) {
+			fixed->x -= x_off;
+			fixed->y -= y_off;
+			fixed++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriFan(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTriFanReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
+		    int         i = extra_len / sizeof (xPointFixed);
+
+		    while (i--) {
+			fixed->x -= x_off;
+			fixed->y -= y_off;
+			fixed++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+#if 0 /* Not implemented yet */
+
+static int
+PanoramiXRenderColorTrapezoids(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderColorTrapezoidsReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
+    
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+			....; 
+		}
+	    }
+	    
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderColorTriangles(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderColorTrianglesReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
+    
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+			....; 
+		}
+	    }
+	    
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+#endif
+
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+    PanoramiXRes    *picture;
+    int		    result = Success, j;
+    REQUEST(xRenderAddTrapsReq);
+    char	    *extra;
+    int		    extra_len;
+    INT16    	    x_off, y_off;
+
+    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+    VERIFY_XIN_PICTURE (picture, stuff->picture, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	x_off = stuff->xOff;
+	y_off = stuff->yOff;
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    stuff->picture = picture->info[j].id;
+	    
+	    if (picture->u.pict.root)
+	    {
+		stuff->xOff = x_off + panoramiXdataPtr[j].x;
+		stuff->yOff = y_off + panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+    int	    i;
+    
+    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+    for (i = 0; i < RenderNumberRequests; i++)
+	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+    /*
+     * Stuff in Xinerama aware request processing hooks
+     */
+    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+    ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
+    ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
+    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+
+    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
+    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
+    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
+    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+    int	    i;
+    for (i = 0; i < RenderNumberRequests; i++)
+	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif	/* PANORAMIX */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
new file mode 100644
index 000000000..00c55cde7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -0,0 +1,3799 @@
+/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.12 2005/08/28 19:47:39 ajax Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.27tsi Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, Inc.
+ */
+
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/render.h>
+#include <X11/extensions/renderproto.h>
+#include <X11/Xfuncproto.h>
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+#include "NXpicturestr.h"
+#include "NXglyphstr.h"
+
+#include "Trap.h"
+
+#include "Render.h"
+#include "Pixmaps.h"
+#include "Options.h"
+#include "Screen.h"
+#include "Cursor.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+/*
+ * From NXmiglyph.c.
+ */
+
+void miGlyphExtents(int nlist, GlyphListPtr list,
+                        GlyphPtr *glyphs, BoxPtr extents);
+
+/*
+ * From NXmitrap.c.
+ */
+
+void miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+/*
+ * Functions from Render.c.
+ */
+
+int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
+void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
+int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
+int  nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
+void nxagentChangePicture(PicturePtr, Mask);
+int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
+void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
+                          INT16, INT16, INT16, INT16, CARD16, CARD16);
+void nxagentCompositeRects(CARD8, PicturePtr, xRenderColor *, int, xRectangle *);
+void nxagentCreateGlyphSet(GlyphSetPtr glyphSet);
+void nxagentReferenceGlyphSet(GlyphSetPtr glyphSet);
+void nxagentFreeGlyphs(GlyphSetPtr glyphSet, CARD32 *gids, int nglyph);
+void nxagentFreeGlyphSet(GlyphSetPtr glyphSet);
+void nxagentSetPictureTransform(PicturePtr pPicture, pointer transform);
+void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
+                                 pointer params, int nparams);
+void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
+                           INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
+
+/*
+ * The void pointer is actually a XGlyphElt8.
+ */
+
+void nxagentGlyphs(CARD8, PicturePtr, PicturePtr, PictFormatPtr,
+                       INT16, INT16, int, void *, int, GlyphPtr *);
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    ProcRenderQueryVersion,
+    ProcRenderQueryPictFormats,
+    ProcRenderQueryPictIndexValues,
+    ProcRenderQueryDithers,
+    ProcRenderCreatePicture,
+    ProcRenderChangePicture,
+    ProcRenderSetPictureClipRectangles,
+    ProcRenderFreePicture,
+    ProcRenderComposite,
+    ProcRenderScale,
+    ProcRenderTrapezoids,
+    ProcRenderTriangles,
+    ProcRenderTriStrip,
+    ProcRenderTriFan,
+    ProcRenderColorTrapezoids,
+    ProcRenderColorTriangles,
+    ProcRenderTransform,
+    ProcRenderCreateGlyphSet,
+    ProcRenderReferenceGlyphSet,
+    ProcRenderFreeGlyphSet,
+    ProcRenderAddGlyphs,
+    ProcRenderAddGlyphsFromPicture,
+    ProcRenderFreeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderFillRectangles,
+    ProcRenderCreateCursor,
+    ProcRenderSetPictureTransform,
+    ProcRenderQueryFilters,
+    ProcRenderSetPictureFilter,
+    ProcRenderCreateAnimCursor,
+    ProcRenderAddTraps,
+    ProcRenderCreateSolidFill,
+    ProcRenderCreateLinearGradient,
+    ProcRenderCreateRadialGradient,
+    ProcRenderCreateConicalGradient
+};
+
+int	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    SProcRenderQueryVersion,
+    SProcRenderQueryPictFormats,
+    SProcRenderQueryPictIndexValues,
+    SProcRenderQueryDithers,
+    SProcRenderCreatePicture,
+    SProcRenderChangePicture,
+    SProcRenderSetPictureClipRectangles,
+    SProcRenderFreePicture,
+    SProcRenderComposite,
+    SProcRenderScale,
+    SProcRenderTrapezoids,
+    SProcRenderTriangles,
+    SProcRenderTriStrip,
+    SProcRenderTriFan,
+    SProcRenderColorTrapezoids,
+    SProcRenderColorTriangles,
+    SProcRenderTransform,
+    SProcRenderCreateGlyphSet,
+    SProcRenderReferenceGlyphSet,
+    SProcRenderFreeGlyphSet,
+    SProcRenderAddGlyphs,
+    SProcRenderAddGlyphsFromPicture,
+    SProcRenderFreeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderFillRectangles,
+    SProcRenderCreateCursor,
+    SProcRenderSetPictureTransform,
+    SProcRenderQueryFilters,
+    SProcRenderSetPictureFilter,
+    SProcRenderCreateAnimCursor,
+    SProcRenderAddTraps,
+    SProcRenderCreateSolidFill,
+    SProcRenderCreateLinearGradient,
+    SProcRenderCreateRadialGradient,
+    SProcRenderCreateConicalGradient
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+    
+#if 0
+static CARD8	RenderReqCode;
+#endif
+int	RenderErrBase;
+int	RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+    int	    major_version;
+    int	    minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient)    ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr	*list,
+		      pointer		closure,
+		      pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
+
+    pRenderClient->major_version = 0;
+    pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+    ExtensionEntry *extEntry;
+
+    if (!PictureType)
+	return;
+    if (!PictureFinishInit ())
+	return;
+    RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+    if (!AllocateClientPrivate (RenderClientPrivateIndex, 
+				sizeof (RenderClientRec)))
+	return;
+    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+	return;
+
+    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+			     ProcRenderDispatch, SProcRenderDispatch,
+			     RenderResetProc, StandardMinorOpcode);
+    if (!extEntry)
+	return;
+#if 0
+    RenderReqCode = (CARD8) extEntry->base;
+#endif
+    RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+    ResetPicturePrivateIndex();
+    ResetGlyphSetPrivateIndex();
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+    RenderClientPtr pRenderClient = GetRenderClient (client);
+    xRenderQueryVersionReply rep;
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    pRenderClient->major_version = stuff->majorVersion;
+    pRenderClient->minor_version = stuff->minorVersion;
+
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = nxagentRenderVersionMajor;
+    rep.minorVersion = nxagentRenderVersionMinor;
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.majorVersion, n);
+	swapl(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    DepthPtr    pDepth;
+    int		d, v;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = pScreen->allowedDepths + d;
+	for (v = 0; v < pDepth->numVids; v++)
+	{
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+	}
+    }
+    return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+    VisualPtr	pVisual;
+    int		v;
+
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = pScreen->visuals + v;
+	if (pVisual->vid == vid)
+	    return pVisual;
+    }
+    return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+    RenderClientPtr		    pRenderClient = GetRenderClient (client);
+    xRenderQueryPictFormatsReply    *reply;
+    xPictScreen			    *pictScreen;
+    xPictDepth			    *pictDepth;
+    xPictVisual			    *pictVisual;
+    xPictFormInfo		    *pictForm;
+    CARD32			    *pictSubpixel;
+    ScreenPtr			    pScreen;
+    VisualPtr			    pVisual;
+    DepthPtr			    pDepth;
+    int				    v, d;
+    PictureScreenPtr		    ps;
+    PictFormatPtr		    pFormat;
+    int				    nformat;
+    int				    ndepth;
+    int				    nvisual;
+    int				    rlength;
+    int				    s;
+    int				    n;
+    int				    numScreens;
+    int				    numSubpixel;
+
+    extern int                      nxagentAlphaEnabled;
+/*    REQUEST(xRenderQueryPictFormatsReq); */
+
+    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+    numScreens = screenInfo.numScreens;
+#endif
+    ndepth = nformat = nvisual = 0;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pDepth = pScreen->allowedDepths + d;
+	    ++ndepth;
+
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+		    ++nvisual;
+	    }
+	}
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    nformat += ps->nformats;
+    }
+    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+	numSubpixel = 0;
+    else
+	numSubpixel = numScreens;
+    
+    rlength = (sizeof (xRenderQueryPictFormatsReply) +
+	       nformat * sizeof (xPictFormInfo) +
+	       numScreens * sizeof (xPictScreen) +
+	       ndepth * sizeof (xPictDepth) +
+	       nvisual * sizeof (xPictVisual) +
+	       numSubpixel * sizeof (CARD32));
+    reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numFormats = nformat;
+    reply->numScreens = numScreens;
+    reply->numDepths = ndepth;
+    reply->numVisuals = nvisual;
+    reply->numSubpixel = numSubpixel;
+    
+    pictForm = (xPictFormInfo *) (reply + 1);
+    
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	{
+	    for (nformat = 0, pFormat = ps->formats; 
+		 nformat < ps->nformats;
+		 nformat++, pFormat++)
+	    {
+		pictForm->id = pFormat->id;
+		pictForm->type = pFormat->type;
+		pictForm->depth = pFormat->depth;
+		pictForm->direct.red = pFormat->direct.red;
+		pictForm->direct.redMask = pFormat->direct.redMask;
+		pictForm->direct.green = pFormat->direct.green;
+		pictForm->direct.greenMask = pFormat->direct.greenMask;
+		pictForm->direct.blue = pFormat->direct.blue;
+		pictForm->direct.blueMask = pFormat->direct.blueMask;
+		pictForm->direct.alpha = nxagentAlphaEnabled ? pFormat->direct.alpha : 0;
+		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+		    pictForm->colormap = pFormat->index.pColormap->mid;
+		else
+		    pictForm->colormap = None;
+		if (client->swapped)
+		{
+		    swapl (&pictForm->id, n);
+		    swaps (&pictForm->direct.red, n);
+		    swaps (&pictForm->direct.redMask, n);
+		    swaps (&pictForm->direct.green, n);
+		    swaps (&pictForm->direct.greenMask, n);
+		    swaps (&pictForm->direct.blue, n);
+		    swaps (&pictForm->direct.blueMask, n);
+		    swaps (&pictForm->direct.alpha, n);
+		    swaps (&pictForm->direct.alphaMask, n);
+		    swapl (&pictForm->colormap, n);
+		}
+		pictForm++;
+	    }
+	}
+    }
+    
+    pictScreen = (xPictScreen *) pictForm;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	pictDepth = (xPictDepth *) (pictScreen + 1);
+	ndepth = 0;
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pictVisual = (xPictVisual *) (pictDepth + 1);
+	    pDepth = pScreen->allowedDepths + d;
+
+	    nvisual = 0;
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && (pFormat = PictureMatchVisual (pScreen, 
+							      pDepth->depth, 
+							      pVisual)))
+		{
+		    pictVisual->visual = pVisual->vid;
+		    pictVisual->format = pFormat->id;
+		    if (client->swapped)
+		    {
+			swapl (&pictVisual->visual, n);
+			swapl (&pictVisual->format, n);
+		    }
+		    pictVisual++;
+		    nvisual++;
+		}
+	    }
+	    pictDepth->depth = pDepth->depth;
+	    pictDepth->nPictVisuals = nvisual;
+	    if (client->swapped)
+	    {
+		swaps (&pictDepth->nPictVisuals, n);
+	    }
+	    ndepth++;
+	    pictDepth = (xPictDepth *) pictVisual;
+	}
+	pictScreen->nDepth = ndepth;
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    pictScreen->fallback = ps->fallback->id;
+	else
+	    pictScreen->fallback = 0;
+	if (client->swapped)
+	{
+	    swapl (&pictScreen->nDepth, n);
+	    swapl (&pictScreen->fallback, n);
+	}
+	pictScreen = (xPictScreen *) pictDepth;
+    }
+    pictSubpixel = (CARD32 *) pictScreen;
+    
+    for (s = 0; s < numSubpixel; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    *pictSubpixel = ps->subpixel;
+	else
+	    *pictSubpixel = SubPixelUnknown;
+	if (client->swapped)
+	{
+	    swapl (pictSubpixel, n);
+	}
+	++pictSubpixel;
+    }
+    
+    if (client->swapped)
+    {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numFormats, n);
+	swapl (&reply->numScreens, n);
+	swapl (&reply->numDepths, n);
+	swapl (&reply->numVisuals, n);
+	swapl (&reply->numSubpixel, n);
+    }
+    WriteToClient(client, rlength, (char *) reply);
+    xfree (reply);
+    return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    PictFormatPtr   pFormat;
+    int		    num;
+    int		    rlength;
+    int		    i, n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    xRenderQueryPictIndexValuesReply *reply;
+    xIndexValue	    *values;
+
+    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->type != PictTypeIndexed)
+    {
+	client->errorValue = stuff->format;
+	return BadMatch;
+    }
+    num = pFormat->index.nvalues;
+    rlength = (sizeof (xRenderQueryPictIndexValuesReply) + 
+	       num * sizeof(xIndexValue));
+    reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numIndexValues = num;
+
+    values = (xIndexValue *) (reply + 1);
+    
+    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+    
+    if (client->swapped)
+    {
+	for (i = 0; i < num; i++)
+	{
+	    swapl (&values[i].pixel, n);
+	    swaps (&values[i].red, n);
+	    swaps (&values[i].green, n);
+	    swaps (&values[i].blue, n);
+	    swaps (&values[i].alpha, n);
+	}
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numIndexValues, n);
+    }
+
+    WriteToClient(client, rlength, (char *) reply);
+    xfree(reply);
+    return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    int		    len;
+    int		    error;
+    REQUEST(xRenderCreatePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+			     SecurityWriteAccess);
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->depth != pDrawable->depth)
+	return BadMatch;
+    len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    pPicture = CreatePicture (stuff->pid,
+			      pDrawable,
+			      pFormat,
+			      stuff->mask,
+			      (XID *) (stuff + 1),
+			      client,
+			      &error);
+    if (!pPicture)
+	return error;
+    nxagentCreatePicture(pPicture, stuff -> mask);
+
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    REQUEST(xRenderChangePictureReq);
+    int len;
+    int error;
+
+    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+
+    len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    error = ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+			  (DevUnion *) 0, client);
+    
+    nxagentChangePicture(pPicture, stuff->mask);
+
+    return error;
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    PicturePtr	    pPicture;
+    int		    nr;
+    int		    result;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pPicture->pDrawable)
+        return BadDrawable;
+
+    /*
+     * The original code used sizeof(xRenderChangePictureReq).
+     * This was harmless, as both structures have the same size.
+     *
+     * nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+     */
+    nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq);
+    if (nr & 4)
+	return BadLength;
+    nr >>= 3;
+    result = SetPictureClipRects (pPicture, 
+				  stuff->xOrigin, stuff->yOrigin,
+				  nr, (xRectangle *) &stuff[1]);
+    nxagentChangePictureClip (pPicture,
+                              CT_NONE,
+                              nr,
+                              (xRectangle *) &stuff[1],
+                              (int)stuff -> xOrigin,
+                              (int)stuff -> yOrigin);
+
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+    PicturePtr	pPicture;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+		    RenderErrBase + BadPicture);
+
+    nxagentDestroyPicture(pPicture);
+
+    FreeResource (stuff->picture, RT_NONE);
+    return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+	return TRUE;
+    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+	return TRUE;
+    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+	return TRUE;
+    return FALSE;
+}
+
+/*
+ * Check if both pictures have drawables which are
+ * virtual pixmaps. See the corresponding define
+ * in NXpicture.c
+ */
+
+#define NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+#define nxagentCompositePredicate(pSrc, pDst)  TRUE
+
+#else
+
+/*
+ * This is still under development. The final
+ * goal is to let pictures point to the real
+ * pixmaps instead of pointing to virtuals.
+ */
+
+int nxagentCompositePredicate(PicturePtr pSrc, PicturePtr pDst)
+{
+  PixmapPtr pPixmap1;
+  PixmapPtr pPixmap2;
+
+  pPixmap1 = (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pSrc -> pDrawable) : NULL);
+
+  pPixmap2 = (pDst -> pDrawable -> type == DRAWABLE_PIXMAP ?
+                 ((PixmapPtr) pDst -> pDrawable) : NULL);
+
+  if (pPixmap1 == NULL || pPixmap2 == NULL)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 0.\n");
+    #endif
+
+    return FALSE;
+  }
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentCompositePredicate: Case 1.\n");
+    #endif
+
+    if (nxagentPixmapIsVirtual(pPixmap1) == 1 &&
+            nxagentPixmapIsVirtual(pPixmap2) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCompositePredicate: Case 2.\n");
+      #endif
+
+      return TRUE;
+    }
+  }
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCompositePredicate: Case 3.\n");
+  #endif
+
+  return FALSE;
+}
+
+#endif
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+    PicturePtr	pSrc, pMask, pDst;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
+		  RenderErrBase + BadPicture);
+    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
+
+    ValidatePicture (pSrc);
+    if (pMask)
+        ValidatePicture (pMask);
+    ValidatePicture (pDst);
+
+    #ifdef NXAGENT_PICTURE_ALWAYS_POINTS_TO_VIRTUAL
+
+    if (nxagentCompositePredicate(pSrc, pDst))
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pMask, (void *) pDst);
+      #endif
+
+    CompositePicture (stuff->op,
+		      pSrc,
+		      pMask,
+		      pDst,
+		      stuff->xSrc,
+		      stuff->ySrc,
+		      stuff->xMask,
+		      stuff->yMask,
+		      stuff->xDst,
+		      stuff->yDst,
+		      stuff->width,
+		      stuff->height);
+    }
+
+    #else
+
+    if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+            pDst -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                (!pMask || pMask -> pDrawable -> type == DRAWABLE_PIXMAP))
+    {
+      PixmapPtr pVirtualPixmapSrc;
+      PixmapPtr pVirtualPixmapDst;
+      PixmapPtr pVirtualPixmapMask;
+
+      PicturePtr pVirtualPictureSrc;
+      PicturePtr pVirtualPictureDst;
+      PicturePtr pVirtualPictureMask;
+
+      pVirtualPixmapSrc  = (PixmapPtr) pSrc  -> pDrawable;
+      pVirtualPictureSrc = nxagentPixmapPriv(pVirtualPixmapSrc) -> pPicture;
+
+      pVirtualPixmapDst  = (PixmapPtr) pDst  -> pDrawable;
+      pVirtualPictureDst = nxagentPixmapPriv(pVirtualPixmapDst) -> pPicture;
+
+      if (pMask)
+      {
+        pVirtualPixmapMask  = (PixmapPtr) pMask  -> pDrawable;
+        pVirtualPictureMask = nxagentPixmapPriv(pVirtualPixmapMask) -> pPicture;
+      }
+      else
+      {
+        pVirtualPixmapMask  = NULL;
+        pVirtualPictureMask = NULL;
+      }
+
+      if (pVirtualPictureSrc && pVirtualPictureDst)
+      {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderComposite: Going to composite with "
+                  "source at [%p] mask at [%p] and destination at [%p].\n",
+                      (void *) pVirtualPixmapSrc, (void *) pVirtualPixmapMask,
+                          (void *) pVirtualPixmapDst);
+      #endif
+
+      CompositePicture (stuff->op,
+                        pVirtualPictureSrc,
+                        pVirtualPictureMask,
+                        pVirtualPictureDst,
+                        stuff->xSrc,
+                        stuff->ySrc,
+                        stuff->xMask,
+                        stuff->yMask,
+                        stuff->xDst,
+                        stuff->yDst,
+                        stuff->width,
+                        stuff->height);
+      }
+    }
+
+    #endif
+
+    nxagentComposite (stuff -> op,
+                      pSrc,
+                      pMask,
+                      pDst,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      stuff -> xMask,
+                      stuff -> yMask,
+                      stuff -> xDst,
+                      stuff -> yDst,
+                      stuff -> width,
+                      stuff -> height);
+
+    return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+    if (ntraps % sizeof (xTrapezoid))
+	return BadLength;
+    ntraps /= sizeof (xTrapezoid);
+    if (ntraps)
+    {
+      if (pFormat != NULL)
+      {
+        nxagentTrapezoidExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+        miTrapezoidBounds (ntraps, (xTrapezoid *) &stuff[1], nxagentTrapezoidExtents);
+      }
+
+      if (nxagentCompositePredicate(pSrc, pDst) == 1)
+      {
+	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+			     stuff->xSrc, stuff->ySrc,
+			     ntraps, (xTrapezoid *) &stuff[1]);
+      }
+
+      nxagentTrapezoids (stuff->op, pSrc, pDst, pFormat,
+                             stuff->xSrc, stuff->ySrc,
+                                 ntraps, (xTrapezoid *) &stuff[1]);
+
+      if (nxagentTrapezoidExtents != NullBox)
+      {
+        xfree(nxagentTrapezoidExtents);
+
+        nxagentTrapezoidExtents = NullBox;
+      }
+    }
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+    int		ntris;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+    if (ntris % sizeof (xTriangle))
+	return BadLength;
+    ntris /= sizeof (xTriangle);
+    if (ntris)
+	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+			    stuff->xSrc, stuff->ySrc,
+			    ntris, (xTriangle *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+			   stuff->xSrc, stuff->ySrc,
+			   npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+			 stuff->xSrc, stuff->ySrc,
+			 npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr	    glyphSet;
+    PictFormatPtr   format;
+    int		    f;
+    REQUEST(xRenderCreateGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+    format = (PictFormatPtr) SecurityLookupIDByType (client,
+						     stuff->format,
+						     PictFormatType,
+						     SecurityReadAccess);
+    if (!format)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    switch (format->depth) {
+    case 1:
+	f = GlyphFormat1;
+	break;
+    case 4:
+	f = GlyphFormat4;
+	break;
+    case 8:
+	f = GlyphFormat8;
+	break;
+    case 16:
+	f = GlyphFormat16;
+	break;
+    case 32:
+	f = GlyphFormat32;
+	break;
+    default:
+	return BadMatch;
+    }
+    if (format->type != PictTypeDirect)
+	return BadMatch;
+    glyphSet = AllocateGlyphSet (f, format);
+    if (!glyphSet)
+	return BadAlloc;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+
+    nxagentCreateGlyphSet(glyphSet);
+
+    return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderReferenceGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->existing,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->existing;
+	return RenderErrBase + BadGlyphSet;
+    }
+    glyphSet->refcnt++;
+
+    nxagentReferenceGlyphSet(glyphSet);
+
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return client->noClientException;
+}
+
+#define NLOCALDELTA	64
+#define NLOCALGLYPH	256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderFreeGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityDestroyAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nxagentFreeGlyphSet(glyphSet);
+
+    FreeResource (stuff->glyphset, RT_NONE);
+    return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+    Glyph	id;
+    GlyphPtr    glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderAddGlyphsReq);
+    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
+    GlyphNewPtr	    glyphsBase, glyphs;
+    GlyphPtr	    glyph = NULL;
+    int		    remain, nglyphs;
+    CARD32	    *gids;
+    xGlyphInfo	    *gi;
+    CARD8	    *bits;
+    int		    size;
+    int		    err = BadAlloc;
+
+    int             totSizeImages;
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nglyphs = stuff->nglyphs;
+    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
+	    return BadAlloc;
+
+    if (nglyphs <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+
+    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+    glyphs = glyphsBase;
+
+    totSizeImages = 0;
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + nglyphs);
+    bits = (CARD8 *) (gi + nglyphs);
+    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+
+    while (remain >= 0 && nglyphs)
+    {
+	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+	if (!glyph)
+	{
+	    err = BadAlloc;
+	    goto bail;
+	}
+	
+	glyphs->glyph = glyph;
+	glyphs->id = *gids;	
+	
+	size = glyph->size - sizeof (xGlyphInfo);
+	if (remain < size)
+	    break;
+	memcpy ((CARD8 *) (glyph + 1), bits, size);
+	
+	if (size & 3)
+	    size += 4 - (size & 3);
+	bits += size;
+	totSizeImages += size;
+	remain -= size;
+	gi++;
+	gids++;
+	glyphs++;
+	nglyphs--;
+    }
+
+    if (nglyphs || remain)
+    {
+	err = BadLength;
+	goto bail;
+    }
+    nglyphs = stuff->nglyphs;
+    if (!ResizeGlyphSet (glyphSet, nglyphs))
+    {
+	err = BadAlloc;
+	goto bail;
+    }
+    glyphs = glyphsBase;
+    while (nglyphs--) {
+	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+	glyphs++;
+    }
+
+    if (glyphsBase != glyphsLocal)
+	Xfree (glyphsBase);
+    return client->noClientException;
+bail:
+    while (glyphs != glyphsBase)
+    {
+	--glyphs;
+	xfree (glyphs->glyph);
+    }
+    if (glyphsBase != glyphsLocal)
+	Xfree (glyphsBase);
+    return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+    REQUEST(xRenderFreeGlyphsReq);
+    GlyphSetPtr     glyphSet;
+    int		    nglyph;
+    CARD32	    *gids;
+    CARD32	    glyph;
+
+    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+    gids = (CARD32 *) (stuff + 1);
+
+    nxagentFreeGlyphs(glyphSet, gids, nglyph);
+
+    while (nglyph-- > 0)
+    {
+	glyph = *gids++;
+	if (!DeleteGlyph (glyphSet, glyph))
+	{
+	    client->errorValue = glyph;
+	    return RenderErrBase + BadGlyph;
+	}
+    }
+    return client->noClientException;
+}
+
+typedef struct XGlyphElt8{
+    GlyphSet                glyphset;
+    _Xconst char            *chars;
+    int                     nchars;
+    int                     xOff;
+    int                     yOff;
+} XGlyphElt8;
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    GlyphSet	    gs;
+    PicturePtr      pSrc, pDst;
+    PictFormatPtr   pFormat;
+    GlyphListRec    listsLocal[NLOCALDELTA];
+    GlyphListPtr    lists, listsBase;
+    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
+    Glyph	    glyph;
+    GlyphPtr	    *glyphs, *glyphsBase;
+    xGlyphElt	    *elt;
+    CARD8	    *buffer, *end;
+    int		    nglyph;
+    int		    nlist;
+    int		    space;
+    int		    size;
+    int		    n;
+    
+    XGlyphElt8      *elements, *elementsBase;
+
+    REQUEST(xRenderCompositeGlyphsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityReadAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    nglyph = 0;
+    nlist = 0;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    buffer += 4;
+	}
+	else
+	{
+	    nlist++;
+	    nglyph += elt->len;
+	    space = size * elt->len;
+	    if (space & 3)
+		space += 4 - (space & 3);
+	    buffer += space;
+	}
+    }
+    if (nglyph <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+    if (nlist <= NLOCALDELTA)
+	listsBase = listsLocal;
+    else
+    {
+	listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+	if (!listsBase)
+	    return BadAlloc;
+    }
+
+    elementsBase = xalloc(nlist * sizeof(XGlyphElt8));
+    if (!elementsBase)
+      return BadAlloc;
+
+    buffer = (CARD8 *) (stuff + 1);
+    glyphs = glyphsBase;
+    lists = listsBase;
+    elements = elementsBase;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+            #ifdef DEBUG
+            fprintf(stderr, "ProcRenderCompositeGlyphs: Glyphset change with base size [%d].\n",
+                        size);
+            #endif
+
+	    if (buffer + sizeof (GlyphSet) < end)
+	    {
+                memcpy(&gs, buffer, sizeof(GlyphSet));
+		glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+								 gs,
+								 GlyphSetType,
+								 SecurityReadAccess);
+		if (!glyphSet)
+		{
+		    client->errorValue = gs;
+		    if (glyphsBase != glyphsLocal)
+			DEALLOCATE_LOCAL (glyphsBase);
+		    if (listsBase != listsLocal)
+			DEALLOCATE_LOCAL (listsBase);
+		    return RenderErrBase + BadGlyphSet;
+		}
+	    }
+	    buffer += 4;
+	}
+	else
+	{
+	    lists->xOff = elt->deltax;
+	    lists->yOff = elt->deltay;
+	    lists->format = glyphSet->format;
+	    lists->len = 0;
+
+            if (glyphSet -> remoteID == 0)
+            {
+              #ifdef TEST
+              fprintf(stderr, "ProcRenderCompositeGlyphs: Going to reconnect glyphset at [%p].\n",
+                          (void *) glyphSet);
+              #endif
+
+              nxagentReconnectGlyphSet(glyphSet, (XID) 0, (void*) NULL);
+            }
+
+            elements -> glyphset = glyphSet -> remoteID;
+            elements -> chars = (char *) buffer;
+            elements -> nchars = elt->len;
+            elements -> xOff = elt->deltax;
+            elements -> yOff = elt->deltay;
+	    n = elt->len;
+	    while (n--)
+	    {
+		if (buffer + size <= end)
+		{
+		    switch (size) {
+		    case 1:
+			glyph = *((CARD8 *)buffer); break;
+		    case 2:
+			glyph = *((CARD16 *)buffer); break;
+		    case 4:
+		    default:
+			glyph = *((CARD32 *)buffer); break;
+		    }
+		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
+		    {
+			lists->len++;
+			glyphs++;
+		    }
+		}
+		buffer += size;
+	    }
+	    space = size * elt->len;
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	    lists++;
+            elements++;
+	}
+    }
+    if (buffer > end)
+	return BadLength;
+
+    /*
+     * We need to know the glyphs extents to synchronize
+     * the drawables involved in the composite text ope-
+     * ration. Also we need to synchronize only the back-
+     * ground of the text we are going to render, so the
+     * operations on the framebuffer must be executed
+     * after the X requests.
+     */
+
+    nxagentGlyphsExtents = (BoxPtr) xalloc(sizeof(BoxRec));
+
+    miGlyphExtents(nlist, listsBase, glyphsBase, nxagentGlyphsExtents);
+
+    nxagentGlyphs(stuff -> op,
+                  pSrc,
+                  pDst,
+                  pFormat,
+                  stuff -> xSrc,
+                  stuff -> ySrc,
+                  nlist,
+                  elementsBase,
+                  size,
+                  glyphsBase);
+
+    if (nxagentCompositePredicate(pSrc, pDst) == 1)
+    {
+      #ifdef TEST
+      fprintf(stderr, "ProcRenderCompositeGlyphs: Going to composite glyphs with "
+                  "source at [%p] and destination at [%p].\n",
+                      (void *) pSrc, (void *) pDst);
+      #endif
+
+      CompositeGlyphs(stuff -> op,
+                      pSrc,
+                      pDst,
+                      pFormat,
+                      stuff -> xSrc,
+                      stuff -> ySrc,
+                      nlist,
+                      listsBase,
+                      glyphsBase);
+    }
+
+    xfree(nxagentGlyphsExtents);
+    nxagentGlyphsExtents = NullBox;
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    if (listsBase != listsLocal)
+	DEALLOCATE_LOCAL (listsBase);
+    
+    xfree(elementsBase);
+
+    return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+    PicturePtr	    pDst;
+    int             things;
+    REQUEST(xRenderFillRectanglesReq);
+    
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    
+    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+    
+    CompositeRects (stuff->op,
+		    pDst,
+		    &stuff->color,
+		    things,
+		    (xRectangle *) &stuff[1]);
+
+    ValidatePicture (pDst);
+    nxagentCompositeRects(stuff -> op,
+                          pDst,
+                          &stuff -> color,
+                          things,
+                          (xRectangle *) &stuff[1]);
+    
+    return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+    unsigned char   mask;
+    
+    if (screenInfo.bitmapBitOrder == LSBFirst)
+	mask = (1 << (x & 7));
+    else
+	mask = (0x80 >> (x & 7));
+    /* XXX assumes byte order is host byte order */
+    line += (x >> 3);
+    if (bit)
+	*line |= mask;
+    else
+	*line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+    {  1,  3,  },
+    {  4,  2,  },
+};
+
+#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateCursorReq);
+    PicturePtr	    pSrc;
+    ScreenPtr	    pScreen;
+    unsigned short  width, height;
+    CARD32	    *argbbits, *argb;
+    unsigned char   *srcbits, *srcline;
+    unsigned char   *mskbits, *mskline;
+    int		    stride;
+    int		    x, y;
+    int		    nbytes_mono;
+    CursorMetricRec cm;
+    CursorPtr	    pCursor;
+    CARD32	    twocolor[3];
+    int		    ncolor;
+
+    RealizeCursorProcPtr saveRealizeCursor;
+
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pSrc->pDrawable)
+        return BadDrawable;
+    pScreen = pSrc->pDrawable->pScreen;
+    width = pSrc->pDrawable->width;
+    height = pSrc->pDrawable->height;
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+    argbbits = xalloc (width * height * sizeof (CARD32));
+    if (!argbbits)
+	return (BadAlloc);
+    
+    stride = BitmapBytePad(width);
+    nbytes_mono = stride*height;
+    srcbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!srcbits)
+    {
+	xfree (argbbits);
+	return (BadAlloc);
+    }
+    mskbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!mskbits)
+    {
+	xfree(argbbits);
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+    bzero ((char *) mskbits, nbytes_mono);
+    bzero ((char *) srcbits, nbytes_mono);
+
+    if (pSrc->format == PICT_a8r8g8b8)
+    {
+	(*pScreen->GetImage) (pSrc->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+    }
+    else
+    {
+	PixmapPtr	pPixmap;
+	PicturePtr	pPicture;
+	PictFormatPtr	pFormat;
+	int		error;
+
+	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+	if (!pFormat)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadImplementation);
+	}
+	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+	if (!pPixmap)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadAlloc);
+	}
+	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, 
+				  client, &error);
+	if (!pPicture)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return error;
+	}
+	(*pScreen->DestroyPixmap) (pPixmap);
+	CompositePicture (PictOpSrc,
+			  pSrc, 0, pPicture,
+			  0, 0, 0, 0, 0, 0, width, height);
+	(*pScreen->GetImage) (pPicture->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+	FreePicture (pPicture, 0);
+    }
+    /*
+     * Check whether the cursor can be directly supported by 
+     * the core cursor code
+     */
+    ncolor = 0;
+    argb = argbbits;
+    for (y = 0; ncolor <= 2 && y < height; y++)
+    {
+	for (x = 0; ncolor <= 2 && x < width; x++)
+	{
+	    CARD32  p = *argb++;
+	    CARD32  a = (p >> 24);
+
+	    if (a == 0)	    /* transparent */
+		continue;
+	    if (a == 0xff)  /* opaque */
+	    {
+		int n;
+		for (n = 0; n < ncolor; n++)
+		    if (p == twocolor[n])
+			break;
+		if (n == ncolor)
+		    twocolor[ncolor++] = p;
+	    }
+	    else
+		ncolor = 3;
+	}
+    }
+    
+    /*
+     * Convert argb image to two plane cursor
+     */
+    srcline = srcbits;
+    mskline = mskbits;
+    argb = argbbits;
+    for (y = 0; y < height; y++)
+    {
+	for (x = 0; x < width; x++)
+	{
+	    CARD32  p = *argb++;
+
+	    if (ncolor <= 2)
+	    {
+		CARD32	a = ((p >> 24));
+
+		SetBit (mskline, x, a != 0);
+		SetBit (srcline, x, a != 0 && p == twocolor[0]);
+	    }
+	    else
+	    {
+		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+		/* Set mask from dithered alpha value */
+		SetBit(mskline, x, a > d);
+		/* Set src from dithered intensity value */
+		SetBit(srcline, x, a > d && i <= d);
+	    }
+	}
+	srcline += stride;
+	mskline += stride;
+    }
+    /*
+     * Dither to white and black if the cursor has more than two colors
+     */
+    if (ncolor > 2)
+    {
+	twocolor[0] = 0xff000000;
+	twocolor[1] = 0xffffffff;
+    }
+    else
+    {
+	xfree (argbbits);
+	argbbits = 0;
+    }
+    
+#define GetByte(p,s)	(((p) >> (s)) & 0xff)
+#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
+    
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+
+    /*
+     * This cursor uses RENDER, so we make sure
+     * that it is allocated in a way that allows
+     * the mi and dix layers to handle it but we
+     * later create it on the server by mirror-
+     * ing the RENDER operation we got from the
+     * client.
+     */
+
+    saveRealizeCursor = pScreen -> RealizeCursor;
+
+    pScreen -> RealizeCursor = nxagentCursorSaveRenderInfo;
+
+    pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+			       GetColor(twocolor[0], 16),
+			       GetColor(twocolor[0], 8),
+			       GetColor(twocolor[0], 0),
+			       GetColor(twocolor[1], 16),
+			       GetColor(twocolor[1], 8),
+			       GetColor(twocolor[1], 0));
+
+    pScreen -> RealizeCursor = saveRealizeCursor;
+
+    /*
+     * Store into the private data members the
+     * information needed to recreate it at
+     * reconnection. This is done in two steps
+     * as in the first step we don't have the
+     * picture info.
+     */
+
+    if (pCursor == NULL)
+    {
+      return BadAlloc;
+    }
+
+    nxagentCursorPostSaveRenderInfo(pCursor, pScreen, pSrc, stuff -> x, stuff -> y);
+
+    nxagentRenderRealizeCursor(pScreen, pCursor);
+
+    if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return (client->noClientException);
+    return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    PicturePtr	pPicture;
+    int		result;
+
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+
+    nxagentSetPictureTransform(pPicture, &stuff->transform);
+    
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+    REQUEST (xRenderQueryFiltersReq);
+    DrawablePtr			pDrawable;
+    xRenderQueryFiltersReply	*reply;
+    int				nbytesName;
+    int				nnames;
+    ScreenPtr			pScreen;
+    PictureScreenPtr		ps;
+    int				i, j;
+    int				len;
+    int				total_bytes;
+    INT16			*aliases;
+    char			*names;
+
+    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+    
+    pScreen = pDrawable->pScreen;
+    nbytesName = 0;
+    nnames = 0;
+    ps = GetPictureScreenIfSet(pScreen);
+    if (ps)
+    {
+	for (i = 0; i < ps->nfilters; i++)
+	    nbytesName += 1 + strlen (ps->filters[i].name);
+	for (i = 0; i < ps->nfilterAliases; i++)
+	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+	nnames = ps->nfilters + ps->nfilterAliases;
+    }
+    len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+    reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+    if (!reply)
+	return BadAlloc;
+    aliases = (INT16 *) (reply + 1);
+    names = (char *) (aliases + ((nnames + 1) & ~1));
+    
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = len;
+    reply->numAliases = nnames;
+    reply->numFilters = nnames;
+    if (ps)
+    {
+
+	/* fill in alias values */
+	for (i = 0; i < ps->nfilters; i++)
+	    aliases[i] = FilterAliasNone;
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    for (j = 0; j < ps->nfilters; j++)
+		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+		    break;
+	    if (j == ps->nfilters)
+	    {
+		for (j = 0; j < ps->nfilterAliases; j++)
+		    if (ps->filterAliases[i].filter_id == 
+			ps->filterAliases[j].alias_id)
+		    {
+			break;
+		    }
+		if (j == ps->nfilterAliases)
+		    j = FilterAliasNone;
+		else
+		    j = j + ps->nfilters;
+	    }
+	    aliases[i + ps->nfilters] = j;
+	}
+
+	/* fill in filter names */
+	for (i = 0; i < ps->nfilters; i++)
+	{
+	    j = strlen (ps->filters[i].name);
+	    *names++ = j;
+	    strncpy (names, ps->filters[i].name, j);
+	    names += j;
+	}
+	
+	/* fill in filter alias names */
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    j = strlen (ps->filterAliases[i].alias);
+	    *names++ = j;
+	    strncpy (names, ps->filterAliases[i].alias, j);
+	    names += j;
+	}
+    }
+
+    if (client->swapped)
+    {
+	register int n;
+
+	for (i = 0; i < (int)reply->numAliases; i++)
+	{
+	    swaps (&aliases[i], n);
+	}
+    	swaps(&reply->sequenceNumber, n);
+    	swapl(&reply->length, n);
+	swapl(&reply->numAliases, n);
+	swapl(&reply->numFilters, n);
+    }
+    WriteToClient(client, total_bytes, (char *) reply);
+    xfree (reply);
+    
+    return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST (xRenderSetPictureFilterReq);
+    PicturePtr	pPicture;
+    int		result;
+    xFixed	*params;
+    int		nparams;
+    char	*name;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    name = (char *) (stuff + 1);
+    params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+
+    nxagentSetPictureFilter(pPicture, name, stuff->nbytes, params, nparams);
+
+    return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateAnimCursorReq);
+    CursorPtr	    *cursors;
+    CARD32	    *deltas;
+    CursorPtr	    pCursor;
+    int		    ncursor;
+    xAnimCursorElt  *elt;
+    int		    i;
+    int		    ret;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    if (client->req_len & 1)
+	return BadLength;
+    ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+    cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+    if (!cursors)
+	return BadAlloc;
+    deltas = (CARD32 *) (cursors + ncursor);
+    elt = (xAnimCursorElt *) (stuff + 1);
+    for (i = 0; i < ncursor; i++)
+    {
+	cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+						       RT_CURSOR, SecurityReadAccess);
+	if (!cursors[i])
+	{
+	    xfree (cursors);
+	    client->errorValue = elt->cursor;
+	    return BadCursor;
+	}
+	deltas[i] = elt->delay;
+	elt++;
+    }
+    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+    xfree (cursors);
+    if (ret != Success)
+	return ret;
+
+    nxagentAnimCursorBits = pCursor -> bits;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+      pCursor -> devPriv[i] = NULL;
+    }
+
+    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+static int
+ProcRenderAddTraps (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pPicture;
+    REQUEST(xRenderAddTrapsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pPicture->pDrawable)
+        return BadDrawable;
+    ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+    if (ntraps % sizeof (xTrap))
+	return BadLength;
+    ntraps /= sizeof (xTrap);
+    if (ntraps)
+	AddTraps (pPicture,
+		  stuff->xOff, stuff->yOff,
+		  ntraps, (xTrap *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    error = 0;
+    REQUEST(xRenderCreateSolidFillReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateLinearGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+                                            stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateRadialGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+                                            stuff->inner_radius, stuff->outer_radius,
+                                            stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateConicalGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+                                             stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        #ifdef TEST
+        fprintf(stderr, "ProcRenderDispatch: Request [%s] OPCODE#%d.\n",
+                    nxagentRenderRequestLiteral[stuff->data], stuff->data);
+        #endif
+
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*ProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->majorVersion, n);
+    swapl(&stuff->minorVersion, n);
+    return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictFormatsReq);
+    swaps(&stuff->length, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreatePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->format, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderChangePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCompositeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->mask, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xMask, n);
+    swaps(&stuff->yMask, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderScaleReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->colorScale, n);
+    swapl(&stuff->alphaScale, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriStripReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriFanReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderReferenceGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->existing, n);
+    return (*ProcRenderVector[stuff->renderReqType])  (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+    register int n;
+    register unsigned int i;
+    CARD32  *gids;
+    void    *end;
+    xGlyphInfo *gi;
+    REQUEST(xRenderAddGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    swapl(&stuff->nglyphs, n);
+    if (stuff->nglyphs & 0xe0000000)
+	return BadLength;
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+	return BadLength;
+    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+	return BadLength;
+    for (i = 0; i < stuff->nglyphs; i++)
+    {
+	swapl (&gids[i], n);
+	swaps (&gi[i].width, n);
+	swaps (&gi[i].height, n);
+	swaps (&gi[i].x, n);
+	swaps (&gi[i].y, n);
+	swaps (&gi[i].xOff, n);
+	swaps (&gi[i].yOff, n);
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+    register int n;
+    xGlyphElt	*elt;
+    CARD8	*buffer;
+    CARD8	*end;
+    int		space;
+    int		i;
+    int		size;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+    
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->maskFormat, n);
+    swapl(&stuff->glyphset, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	swaps (&elt->deltax, n);
+	swaps (&elt->deltay, n);
+	
+	i = elt->len;
+	if (i == 0xff)
+	{
+	    swapl (buffer, n);
+	    buffer += 4;
+	}
+	else
+	{
+	    space = size * i;
+	    switch (size) {
+	    case 1:
+		buffer += i;
+		break;
+	    case 2:
+		while (i--)
+		{
+		    swaps (buffer, n);
+		    buffer += 2;
+		}
+		break;
+	    case 4:
+		while (i--)
+		{
+		    swapl (buffer, n);
+		    buffer += 4;
+		}
+		break;
+	    }
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	}
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFillRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    swaps(&stuff->color.alpha, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateCursorReq);
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    swapl(&stuff->src, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureTransformReq);
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->transform.matrix11, n);
+    swapl(&stuff->transform.matrix12, n);
+    swapl(&stuff->transform.matrix13, n);
+    swapl(&stuff->transform.matrix21, n);
+    swapl(&stuff->transform.matrix22, n);
+    swapl(&stuff->transform.matrix23, n);
+    swapl(&stuff->transform.matrix31, n);
+    swapl(&stuff->transform.matrix32, n);
+    swapl(&stuff->transform.matrix33, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderQueryFiltersReq);
+    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderSetPictureFilterReq);
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->nbytes, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateAnimCursorReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddTraps (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderAddTrapsReq);
+    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->xOff, n);
+    swaps(&stuff->yOff, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateSolidFillReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swaps(&stuff->color.alpha, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int n)
+{
+    int i;
+    CARD32 *stops;
+    CARD16 *colors;
+    stops = (CARD32 *)(stuff);
+    for (i = 0; i < n; ++i) {
+        swapl(stops, n);
+        ++stops;
+    }
+    colors = (CARD16 *)(stops);
+    for (i = 0; i < 4*n; ++i) {
+        swaps(stops, n);
+        ++stops;
+    }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateLinearGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->p1.x, n);
+    swapl(&stuff->p1.y, n);
+    swapl(&stuff->p2.x, n);
+    swapl(&stuff->p2.y, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateRadialGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->inner.x, n);
+    swapl(&stuff->inner.y, n);
+    swapl(&stuff->outer.x, n);
+    swapl(&stuff->outer.y, n);
+    swapl(&stuff->inner_radius, n);
+    swapl(&stuff->outer_radius, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateConicalGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->center.x, n);
+    swapl(&stuff->center.y, n);
+    swapl(&stuff->angle, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+    int result;
+
+    REQUEST(xReq);
+    
+    /*
+     * Let the client fail if we are
+     * hiding the RENDER extension.
+     */
+    
+    if (nxagentRenderTrap)
+    {
+        return BadRequest;
+    }
+
+    if (stuff->data < RenderNumberRequests)
+    {
+        /*
+         * Set the nxagentGCTrap flag while
+         * dispatching a render operation to
+         * avoid reentrancy in GCOps.c.
+         */
+
+        nxagentGCTrap = 1;
+
+        result = (*SProcRenderVector[stuff->data]) (client);
+
+        nxagentGCTrap = 0;
+
+        return result;
+    }
+    else
+	return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+int	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long	XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+    REQUEST(xRenderCreatePictureReq);
+    PanoramiXRes    *refDraw, *newPict;
+    int		    result = Success, j;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+    if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+    if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+    newPict->type = XRT_PICTURE;
+    newPict->info[0].id = stuff->pid;
+    
+    if (refDraw->type == XRT_WINDOW &&
+	stuff->drawable == WindowTable[0]->drawable.id)
+    {
+	newPict->u.pict.root = TRUE;
+    }
+    else
+	newPict->u.pict.root = FALSE;
+
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPict->info[j].id = FakeClientID(client->index);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->pid = newPict->info[j].id;
+	stuff->drawable = refDraw->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+	if(result != Success) break;
+    }
+
+    if (result == Success)
+	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+    else 
+	xfree(newPict);
+
+    return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+    PanoramiXRes    *pict;
+    int		    result = Success, j;
+    REQUEST(xRenderChangePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureFilterReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+    PanoramiXRes *pict;
+    int         result = Success, j;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    client->errorValue = stuff->picture;
+
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+		       RenderErrBase + BadPicture);
+    
+
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->picture = pict->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+	if(result != Success) break;
+    }
+
+    /* Since ProcRenderFreePicture is using FreeResource, it will free
+	our resource for us on the last pass through the loop above */
+ 
+    return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+    PanoramiXRes	*src, *msk, *dst;
+    int			result = Success, j;
+    xRenderCompositeReq	orig;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess, 
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess, 
+		      RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    
+    orig = *stuff;
+    
+    FOR_NSCREENS_FORWARD(j) {
+	stuff->src = src->info[j].id;
+	if (src->u.pict.root)
+	{
+	    stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+	    stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+	}
+	stuff->dst = dst->info[j].id;
+	if (dst->u.pict.root)
+	{
+	    stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+	    stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+	}
+	if (msk)
+	{
+	    stuff->mask = msk->info[j].id;
+	    if (msk->u.pict.root)
+	    {
+		stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+		stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+	    }
+	}
+	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+	if(result != Success) break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+    PanoramiXRes    *src, *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderCompositeGlyphsReq);
+    xGlyphElt	    origElt, *elt;
+    INT16	    xSrc, ySrc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+				 sizeof (xGlyphElt)))
+    {
+	elt = (xGlyphElt *) (stuff + 1);
+	origElt = *elt;
+	xSrc = stuff->xSrc;
+	ySrc = stuff->ySrc;
+	FOR_NSCREENS_FORWARD(j) {
+	    stuff->src = src->info[j].id;
+	    if (src->u.pict.root)
+	    {
+		stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+		stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+	    }
+	    stuff->dst = dst->info[j].id;
+	    if (dst->u.pict.root)
+	    {
+		elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+		elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+	    if(result != Success) break;
+	}
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+    PanoramiXRes    *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderFillRectanglesReq);
+    char	    *extra;
+    int		    extra_len;
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root)
+	    {
+		int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+		    xRectangle	*rects = (xRectangle *) (stuff + 1);
+		    int		i = extra_len / sizeof (xRectangle);
+
+		    while (i--)
+		    {
+			rects->x -= x_off;
+			rects->y -= y_off;
+			rects++;
+		    }
+		}
+	    }
+	    stuff->dst = dst->info[j].id;
+	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTrapezoids(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTrapezoidsReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xTrapezoid  *trap = (xTrapezoid *) (stuff + 1);
+		    int         i = extra_len / sizeof (xTrapezoid);
+
+		    while (i--) {
+			trap->top -= y_off;
+			trap->bottom -= y_off;
+			trap->left.p1.x -= x_off;
+			trap->left.p1.y -= y_off;
+			trap->left.p2.x -= x_off;
+			trap->left.p2.y -= y_off;
+			trap->right.p1.x -= x_off;
+			trap->right.p1.y -= y_off;
+			trap->right.p2.x -= x_off;
+			trap->right.p2.y -= y_off;
+			trap++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriangles(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTrianglesReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xTriangle  *tri = (xTriangle *) (stuff + 1);
+		    int         i = extra_len / sizeof (xTriangle);
+
+		    while (i--) {
+			tri->p1.x -= x_off;
+			tri->p1.y -= y_off;
+			tri->p2.x -= x_off;
+			tri->p2.y -= y_off;
+			tri->p3.x -= x_off;
+			tri->p3.y -= y_off;
+			tri++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriStrip(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTriStripReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
+		    int         i = extra_len / sizeof (xPointFixed);
+
+		    while (i--) {
+			fixed->x -= x_off;
+			fixed->y -= y_off;
+			fixed++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriFan(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTriFanReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
+		    int         i = extra_len / sizeof (xPointFixed);
+
+		    while (i--) {
+			fixed->x -= x_off;
+			fixed->y -= y_off;
+			fixed++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+#if 0 /* Not implemented yet */
+
+static int
+PanoramiXRenderColorTrapezoids(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderColorTrapezoidsReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
+    
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+			....; 
+		}
+	    }
+	    
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderColorTriangles(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderColorTrianglesReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
+    
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+			....; 
+		}
+	    }
+	    
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+#endif
+
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+    PanoramiXRes    *picture;
+    int		    result = Success, j;
+    REQUEST(xRenderAddTrapsReq);
+    char	    *extra;
+    int		    extra_len;
+    INT16    	    x_off, y_off;
+
+    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+    VERIFY_XIN_PICTURE (picture, stuff->picture, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	x_off = stuff->xOff;
+	y_off = stuff->yOff;
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    stuff->picture = picture->info[j].id;
+	    
+	    if (picture->u.pict.root)
+	    {
+		stuff->xOff = x_off + panoramiXdataPtr[j].x;
+		stuff->yOff = y_off + panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+    int	    i;
+    
+    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+    for (i = 0; i < RenderNumberRequests; i++)
+	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+    /*
+     * Stuff in Xinerama aware request processing hooks
+     */
+    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+    ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
+    ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
+    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+
+    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
+    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
+    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
+    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+    int	    i;
+    for (i = 0; i < RenderNumberRequests; i++)
+	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif	/* PANORAMIX */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
new file mode 100644
index 000000000..d2759ab10
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
@@ -0,0 +1,3306 @@
+/* $XdotOrg: xc/programs/Xserver/render/render.c,v 1.12 2005/08/28 19:47:39 ajax Exp $ */
+/*
+ * $XFree86: xc/programs/Xserver/render/render.c,v 1.27tsi Exp $
+ *
+ * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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:  Keith Packard, SuSE, 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 "colormapst.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include <X11/extensions/render.h>
+#include <X11/extensions/renderproto.h>
+#include "picturestr.h"
+#include "glyphstr.h"
+#include <X11/Xfuncproto.h>
+#include "cursorstr.h"
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
+static int ProcRenderQueryVersion (ClientPtr pClient);
+static int ProcRenderQueryPictFormats (ClientPtr pClient);
+static int ProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int ProcRenderQueryDithers (ClientPtr pClient);
+static int ProcRenderCreatePicture (ClientPtr pClient);
+static int ProcRenderChangePicture (ClientPtr pClient);
+static int ProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int ProcRenderFreePicture (ClientPtr pClient);
+static int ProcRenderComposite (ClientPtr pClient);
+static int ProcRenderScale (ClientPtr pClient);
+static int ProcRenderTrapezoids (ClientPtr pClient);
+static int ProcRenderTriangles (ClientPtr pClient);
+static int ProcRenderTriStrip (ClientPtr pClient);
+static int ProcRenderTriFan (ClientPtr pClient);
+static int ProcRenderColorTrapezoids (ClientPtr pClient);
+static int ProcRenderColorTriangles (ClientPtr pClient);
+static int ProcRenderTransform (ClientPtr pClient);
+static int ProcRenderCreateGlyphSet (ClientPtr pClient);
+static int ProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int ProcRenderFreeGlyphSet (ClientPtr pClient);
+static int ProcRenderAddGlyphs (ClientPtr pClient);
+static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int ProcRenderFreeGlyphs (ClientPtr pClient);
+static int ProcRenderCompositeGlyphs (ClientPtr pClient);
+static int ProcRenderFillRectangles (ClientPtr pClient);
+static int ProcRenderCreateCursor (ClientPtr pClient);
+static int ProcRenderSetPictureTransform (ClientPtr pClient);
+static int ProcRenderQueryFilters (ClientPtr pClient);
+static int ProcRenderSetPictureFilter (ClientPtr pClient);
+static int ProcRenderCreateAnimCursor (ClientPtr pClient);
+static int ProcRenderAddTraps (ClientPtr pClient);
+static int ProcRenderCreateSolidFill (ClientPtr pClient);
+static int ProcRenderCreateLinearGradient (ClientPtr pClient);
+static int ProcRenderCreateRadialGradient (ClientPtr pClient);
+static int ProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int ProcRenderDispatch (ClientPtr pClient);
+
+static int SProcRenderQueryVersion (ClientPtr pClient);
+static int SProcRenderQueryPictFormats (ClientPtr pClient);
+static int SProcRenderQueryPictIndexValues (ClientPtr pClient);
+static int SProcRenderQueryDithers (ClientPtr pClient);
+static int SProcRenderCreatePicture (ClientPtr pClient);
+static int SProcRenderChangePicture (ClientPtr pClient);
+static int SProcRenderSetPictureClipRectangles (ClientPtr pClient);
+static int SProcRenderFreePicture (ClientPtr pClient);
+static int SProcRenderComposite (ClientPtr pClient);
+static int SProcRenderScale (ClientPtr pClient);
+static int SProcRenderTrapezoids (ClientPtr pClient);
+static int SProcRenderTriangles (ClientPtr pClient);
+static int SProcRenderTriStrip (ClientPtr pClient);
+static int SProcRenderTriFan (ClientPtr pClient);
+static int SProcRenderColorTrapezoids (ClientPtr pClient);
+static int SProcRenderColorTriangles (ClientPtr pClient);
+static int SProcRenderTransform (ClientPtr pClient);
+static int SProcRenderCreateGlyphSet (ClientPtr pClient);
+static int SProcRenderReferenceGlyphSet (ClientPtr pClient);
+static int SProcRenderFreeGlyphSet (ClientPtr pClient);
+static int SProcRenderAddGlyphs (ClientPtr pClient);
+static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient);
+static int SProcRenderFreeGlyphs (ClientPtr pClient);
+static int SProcRenderCompositeGlyphs (ClientPtr pClient);
+static int SProcRenderFillRectangles (ClientPtr pClient);
+static int SProcRenderCreateCursor (ClientPtr pClient);
+static int SProcRenderSetPictureTransform (ClientPtr pClient);
+static int SProcRenderQueryFilters (ClientPtr pClient);
+static int SProcRenderSetPictureFilter (ClientPtr pClient);
+static int SProcRenderCreateAnimCursor (ClientPtr pClient);
+static int SProcRenderAddTraps (ClientPtr pClient);
+static int SProcRenderCreateSolidFill (ClientPtr pClient);
+static int SProcRenderCreateLinearGradient (ClientPtr pClient);
+static int SProcRenderCreateRadialGradient (ClientPtr pClient);
+static int SProcRenderCreateConicalGradient (ClientPtr pClient);
+
+static int SProcRenderDispatch (ClientPtr pClient);
+
+int	(*ProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    ProcRenderQueryVersion,
+    ProcRenderQueryPictFormats,
+    ProcRenderQueryPictIndexValues,
+    ProcRenderQueryDithers,
+    ProcRenderCreatePicture,
+    ProcRenderChangePicture,
+    ProcRenderSetPictureClipRectangles,
+    ProcRenderFreePicture,
+    ProcRenderComposite,
+    ProcRenderScale,
+    ProcRenderTrapezoids,
+    ProcRenderTriangles,
+    ProcRenderTriStrip,
+    ProcRenderTriFan,
+    ProcRenderColorTrapezoids,
+    ProcRenderColorTriangles,
+    ProcRenderTransform,
+    ProcRenderCreateGlyphSet,
+    ProcRenderReferenceGlyphSet,
+    ProcRenderFreeGlyphSet,
+    ProcRenderAddGlyphs,
+    ProcRenderAddGlyphsFromPicture,
+    ProcRenderFreeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderCompositeGlyphs,
+    ProcRenderFillRectangles,
+    ProcRenderCreateCursor,
+    ProcRenderSetPictureTransform,
+    ProcRenderQueryFilters,
+    ProcRenderSetPictureFilter,
+    ProcRenderCreateAnimCursor,
+    ProcRenderAddTraps,
+    ProcRenderCreateSolidFill,
+    ProcRenderCreateLinearGradient,
+    ProcRenderCreateRadialGradient,
+    ProcRenderCreateConicalGradient
+};
+
+int	(*SProcRenderVector[RenderNumberRequests])(ClientPtr) = {
+    SProcRenderQueryVersion,
+    SProcRenderQueryPictFormats,
+    SProcRenderQueryPictIndexValues,
+    SProcRenderQueryDithers,
+    SProcRenderCreatePicture,
+    SProcRenderChangePicture,
+    SProcRenderSetPictureClipRectangles,
+    SProcRenderFreePicture,
+    SProcRenderComposite,
+    SProcRenderScale,
+    SProcRenderTrapezoids,
+    SProcRenderTriangles,
+    SProcRenderTriStrip,
+    SProcRenderTriFan,
+    SProcRenderColorTrapezoids,
+    SProcRenderColorTriangles,
+    SProcRenderTransform,
+    SProcRenderCreateGlyphSet,
+    SProcRenderReferenceGlyphSet,
+    SProcRenderFreeGlyphSet,
+    SProcRenderAddGlyphs,
+    SProcRenderAddGlyphsFromPicture,
+    SProcRenderFreeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderCompositeGlyphs,
+    SProcRenderFillRectangles,
+    SProcRenderCreateCursor,
+    SProcRenderSetPictureTransform,
+    SProcRenderQueryFilters,
+    SProcRenderSetPictureFilter,
+    SProcRenderCreateAnimCursor,
+    SProcRenderAddTraps,
+    SProcRenderCreateSolidFill,
+    SProcRenderCreateLinearGradient,
+    SProcRenderCreateRadialGradient,
+    SProcRenderCreateConicalGradient
+};
+
+static void
+RenderResetProc (ExtensionEntry *extEntry);
+    
+#if 0
+static CARD8	RenderReqCode;
+#endif
+int	RenderErrBase;
+int	RenderClientPrivateIndex;
+
+typedef struct _RenderClient {
+    int	    major_version;
+    int	    minor_version;
+} RenderClientRec, *RenderClientPtr;
+
+#define GetRenderClient(pClient)    ((RenderClientPtr) (pClient)->devPrivates[RenderClientPrivateIndex].ptr)
+
+static void
+RenderClientCallback (CallbackListPtr	*list,
+		      pointer		closure,
+		      pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    RenderClientPtr	pRenderClient = GetRenderClient (pClient);
+
+    pRenderClient->major_version = 0;
+    pRenderClient->minor_version = 0;
+}
+
+void
+RenderExtensionInit (void)
+{
+    ExtensionEntry *extEntry;
+
+    if (!PictureType)
+	return;
+    if (!PictureFinishInit ())
+	return;
+    RenderClientPrivateIndex = AllocateClientPrivateIndex ();
+    if (!AllocateClientPrivate (RenderClientPrivateIndex, 
+				sizeof (RenderClientRec)))
+	return;
+    if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0))
+	return;
+
+    extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors,
+			     ProcRenderDispatch, SProcRenderDispatch,
+			     RenderResetProc, StandardMinorOpcode);
+    if (!extEntry)
+	return;
+#if 0
+    RenderReqCode = (CARD8) extEntry->base;
+#endif
+    RenderErrBase = extEntry->errorBase;
+}
+
+static void
+RenderResetProc (ExtensionEntry *extEntry)
+{
+    ResetPicturePrivateIndex();
+    ResetGlyphSetPrivateIndex();
+}
+
+static int
+ProcRenderQueryVersion (ClientPtr client)
+{
+    RenderClientPtr pRenderClient = GetRenderClient (client);
+    xRenderQueryVersionReply rep;
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    pRenderClient->major_version = stuff->majorVersion;
+    pRenderClient->minor_version = stuff->minorVersion;
+
+    REQUEST_SIZE_MATCH(xRenderQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.majorVersion = RENDER_MAJOR;
+    rep.minorVersion = RENDER_MINOR;
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.majorVersion, n);
+	swapl(&rep.minorVersion, n);
+    }
+    WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+#if 0
+static int
+VisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+    DepthPtr    pDepth;
+    int		d, v;
+
+    for (d = 0; d < pScreen->numDepths; d++)
+    {
+	pDepth = pScreen->allowedDepths + d;
+	for (v = 0; v < pDepth->numVids; v++)
+	{
+	    if (pDepth->vids[v] == pVisual->vid)
+		return pDepth->depth;
+	}
+    }
+    return 0;
+}
+#endif
+
+static VisualPtr
+findVisual (ScreenPtr pScreen, VisualID vid)
+{
+    VisualPtr	pVisual;
+    int		v;
+
+    for (v = 0; v < pScreen->numVisuals; v++)
+    {
+	pVisual = pScreen->visuals + v;
+	if (pVisual->vid == vid)
+	    return pVisual;
+    }
+    return 0;
+}
+
+extern char *ConnectionInfo;
+
+static int
+ProcRenderQueryPictFormats (ClientPtr client)
+{
+    RenderClientPtr		    pRenderClient = GetRenderClient (client);
+    xRenderQueryPictFormatsReply    *reply;
+    xPictScreen			    *pictScreen;
+    xPictDepth			    *pictDepth;
+    xPictVisual			    *pictVisual;
+    xPictFormInfo		    *pictForm;
+    CARD32			    *pictSubpixel;
+    ScreenPtr			    pScreen;
+    VisualPtr			    pVisual;
+    DepthPtr			    pDepth;
+    int				    v, d;
+    PictureScreenPtr		    ps;
+    PictFormatPtr		    pFormat;
+    int				    nformat;
+    int				    ndepth;
+    int				    nvisual;
+    int				    rlength;
+    int				    s;
+    int				    n;
+    int				    numScreens;
+    int				    numSubpixel;
+/*    REQUEST(xRenderQueryPictFormatsReq); */
+
+    REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq);
+
+#ifdef PANORAMIX
+    if (noPanoramiXExtension)
+	numScreens = screenInfo.numScreens;
+    else 
+        numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#else
+    numScreens = screenInfo.numScreens;
+#endif
+    ndepth = nformat = nvisual = 0;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pDepth = pScreen->allowedDepths + d;
+	    ++ndepth;
+
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual))
+		    ++nvisual;
+	    }
+	}
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    nformat += ps->nformats;
+    }
+    if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6)
+	numSubpixel = 0;
+    else
+	numSubpixel = numScreens;
+    
+    rlength = (sizeof (xRenderQueryPictFormatsReply) +
+	       nformat * sizeof (xPictFormInfo) +
+	       numScreens * sizeof (xPictScreen) +
+	       ndepth * sizeof (xPictDepth) +
+	       nvisual * sizeof (xPictVisual) +
+	       numSubpixel * sizeof (CARD32));
+    reply = (xRenderQueryPictFormatsReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numFormats = nformat;
+    reply->numScreens = numScreens;
+    reply->numDepths = ndepth;
+    reply->numVisuals = nvisual;
+    reply->numSubpixel = numSubpixel;
+    
+    pictForm = (xPictFormInfo *) (reply + 1);
+    
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	{
+	    for (nformat = 0, pFormat = ps->formats; 
+		 nformat < ps->nformats;
+		 nformat++, pFormat++)
+	    {
+		pictForm->id = pFormat->id;
+		pictForm->type = pFormat->type;
+		pictForm->depth = pFormat->depth;
+		pictForm->direct.red = pFormat->direct.red;
+		pictForm->direct.redMask = pFormat->direct.redMask;
+		pictForm->direct.green = pFormat->direct.green;
+		pictForm->direct.greenMask = pFormat->direct.greenMask;
+		pictForm->direct.blue = pFormat->direct.blue;
+		pictForm->direct.blueMask = pFormat->direct.blueMask;
+		pictForm->direct.alpha = pFormat->direct.alpha;
+		pictForm->direct.alphaMask = pFormat->direct.alphaMask;
+		if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap)
+		    pictForm->colormap = pFormat->index.pColormap->mid;
+		else
+		    pictForm->colormap = None;
+		if (client->swapped)
+		{
+		    swapl (&pictForm->id, n);
+		    swaps (&pictForm->direct.red, n);
+		    swaps (&pictForm->direct.redMask, n);
+		    swaps (&pictForm->direct.green, n);
+		    swaps (&pictForm->direct.greenMask, n);
+		    swaps (&pictForm->direct.blue, n);
+		    swaps (&pictForm->direct.blueMask, n);
+		    swaps (&pictForm->direct.alpha, n);
+		    swaps (&pictForm->direct.alphaMask, n);
+		    swapl (&pictForm->colormap, n);
+		}
+		pictForm++;
+	    }
+	}
+    }
+    
+    pictScreen = (xPictScreen *) pictForm;
+    for (s = 0; s < numScreens; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	pictDepth = (xPictDepth *) (pictScreen + 1);
+	ndepth = 0;
+	for (d = 0; d < pScreen->numDepths; d++)
+	{
+	    pictVisual = (xPictVisual *) (pictDepth + 1);
+	    pDepth = pScreen->allowedDepths + d;
+
+	    nvisual = 0;
+	    for (v = 0; v < pDepth->numVids; v++)
+	    {
+		pVisual = findVisual (pScreen, pDepth->vids[v]);
+		if (pVisual && (pFormat = PictureMatchVisual (pScreen, 
+							      pDepth->depth, 
+							      pVisual)))
+		{
+		    pictVisual->visual = pVisual->vid;
+		    pictVisual->format = pFormat->id;
+		    if (client->swapped)
+		    {
+			swapl (&pictVisual->visual, n);
+			swapl (&pictVisual->format, n);
+		    }
+		    pictVisual++;
+		    nvisual++;
+		}
+	    }
+	    pictDepth->depth = pDepth->depth;
+	    pictDepth->nPictVisuals = nvisual;
+	    if (client->swapped)
+	    {
+		swaps (&pictDepth->nPictVisuals, n);
+	    }
+	    ndepth++;
+	    pictDepth = (xPictDepth *) pictVisual;
+	}
+	pictScreen->nDepth = ndepth;
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    pictScreen->fallback = ps->fallback->id;
+	else
+	    pictScreen->fallback = 0;
+	if (client->swapped)
+	{
+	    swapl (&pictScreen->nDepth, n);
+	    swapl (&pictScreen->fallback, n);
+	}
+	pictScreen = (xPictScreen *) pictDepth;
+    }
+    pictSubpixel = (CARD32 *) pictScreen;
+    
+    for (s = 0; s < numSubpixel; s++)
+    {
+	pScreen = screenInfo.screens[s];
+	ps = GetPictureScreenIfSet(pScreen);
+	if (ps)
+	    *pictSubpixel = ps->subpixel;
+	else
+	    *pictSubpixel = SubPixelUnknown;
+	if (client->swapped)
+	{
+	    swapl (pictSubpixel, n);
+	}
+	++pictSubpixel;
+    }
+    
+    if (client->swapped)
+    {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numFormats, n);
+	swapl (&reply->numScreens, n);
+	swapl (&reply->numDepths, n);
+	swapl (&reply->numVisuals, n);
+	swapl (&reply->numSubpixel, n);
+    }
+    WriteToClient(client, rlength, (char *) reply);
+    xfree (reply);
+    return client->noClientException;
+}
+
+static int
+ProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    PictFormatPtr   pFormat;
+    int		    num;
+    int		    rlength;
+    int		    i, n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    xRenderQueryPictIndexValuesReply *reply;
+    xIndexValue	    *values;
+
+    REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq);
+
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->type != PictTypeIndexed)
+    {
+	client->errorValue = stuff->format;
+	return BadMatch;
+    }
+    num = pFormat->index.nvalues;
+    rlength = (sizeof (xRenderQueryPictIndexValuesReply) + 
+	       num * sizeof(xIndexValue));
+    reply = (xRenderQueryPictIndexValuesReply *) xalloc (rlength);
+    if (!reply)
+	return BadAlloc;
+
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+    reply->numIndexValues = num;
+
+    values = (xIndexValue *) (reply + 1);
+    
+    memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue));
+    
+    if (client->swapped)
+    {
+	for (i = 0; i < num; i++)
+	{
+	    swapl (&values[i].pixel, n);
+	    swaps (&values[i].red, n);
+	    swaps (&values[i].green, n);
+	    swaps (&values[i].blue, n);
+	    swaps (&values[i].alpha, n);
+	}
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+	swapl (&reply->numIndexValues, n);
+    }
+
+    WriteToClient(client, rlength, (char *) reply);
+    xfree(reply);
+    return (client->noClientException);
+}
+
+static int
+ProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreatePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    DrawablePtr	    pDrawable;
+    PictFormatPtr   pFormat;
+    int		    len;
+    int		    error;
+    REQUEST(xRenderCreatePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client,
+			     SecurityWriteAccess);
+    pFormat = (PictFormatPtr) SecurityLookupIDByType (client, 
+						      stuff->format,
+						      PictFormatType,
+						      SecurityReadAccess);
+    if (!pFormat)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    if (pFormat->depth != pDrawable->depth)
+	return BadMatch;
+    len = client->req_len - (sizeof(xRenderCreatePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    pPicture = CreatePicture (stuff->pid,
+			      pDrawable,
+			      pFormat,
+			      stuff->mask,
+			      (XID *) (stuff + 1),
+			      client,
+			      &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderChangePicture (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    REQUEST(xRenderChangePictureReq);
+    int len;
+
+    REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+
+    len = client->req_len - (sizeof(xRenderChangePictureReq) >> 2);
+    if (Ones(stuff->mask) != len)
+	return BadLength;
+    
+    return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1),
+			  (DevUnion *) 0, client);
+}
+
+static int
+ProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    PicturePtr	    pPicture;
+    int		    nr;
+    int		    result;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pPicture->pDrawable)
+        return BadDrawable;
+
+    nr = (client->req_len << 2) - sizeof(xRenderChangePictureReq);
+    if (nr & 4)
+	return BadLength;
+    nr >>= 3;
+    result = SetPictureClipRects (pPicture, 
+				  stuff->xOrigin, stuff->yOrigin,
+				  nr, (xRectangle *) &stuff[1]);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderFreePicture (ClientPtr client)
+{
+    PicturePtr	pPicture;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
+		    RenderErrBase + BadPicture);
+    FreeResource (stuff->picture, RT_NONE);
+    return(client->noClientException);
+}
+
+static Bool
+PictOpValid (CARD8 op)
+{
+    if (/*PictOpMinimum <= op && */ op <= PictOpMaximum)
+	return TRUE;
+    if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum)
+	return TRUE;
+    if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum)
+	return TRUE;
+    return FALSE;
+}
+
+static int
+ProcRenderComposite (ClientPtr client)
+{
+    PicturePtr	pSrc, pMask, pDst;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
+		  RenderErrBase + BadPicture);
+    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
+    CompositePicture (stuff->op,
+		      pSrc,
+		      pMask,
+		      pDst,
+		      stuff->xSrc,
+		      stuff->ySrc,
+		      stuff->xMask,
+		      stuff->yMask,
+		      stuff->xDst,
+		      stuff->yDst,
+		      stuff->width,
+		      stuff->height);
+    return Success;
+}
+
+static int
+ProcRenderScale (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTrapezoids (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+    if (ntraps % sizeof (xTrapezoid))
+	return BadLength;
+    ntraps /= sizeof (xTrapezoid);
+    if (ntraps)
+	CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat,
+			     stuff->xSrc, stuff->ySrc,
+			     ntraps, (xTrapezoid *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriangles (ClientPtr client)
+{
+    int		ntris;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+    if (ntris % sizeof (xTriangle))
+	return BadLength;
+    ntris /= sizeof (xTriangle);
+    if (ntris)
+	CompositeTriangles (stuff->op, pSrc, pDst, pFormat,
+			    stuff->xSrc, stuff->ySrc,
+			    ntris, (xTriangle *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriStrip (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriStrip (stuff->op, pSrc, pDst, pFormat,
+			   stuff->xSrc, stuff->ySrc,
+			   npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderTriFan (ClientPtr client)
+{
+    int		npoints;
+    PicturePtr	pSrc, pDst;
+    PictFormatPtr   pFormat;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+    npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq));
+    if (npoints & 4)
+	return(BadLength);
+    npoints >>= 3;
+    if (npoints >= 3)
+	CompositeTriFan (stuff->op, pSrc, pDst, pFormat,
+			 stuff->xSrc, stuff->ySrc,
+			 npoints, (xPointFixed *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int
+ProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderCreateGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr	    glyphSet;
+    PictFormatPtr   format;
+    int		    f;
+    REQUEST(xRenderCreateGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+    format = (PictFormatPtr) SecurityLookupIDByType (client,
+						     stuff->format,
+						     PictFormatType,
+						     SecurityReadAccess);
+    if (!format)
+    {
+	client->errorValue = stuff->format;
+	return RenderErrBase + BadPictFormat;
+    }
+    switch (format->depth) {
+    case 1:
+	f = GlyphFormat1;
+	break;
+    case 4:
+	f = GlyphFormat4;
+	break;
+    case 8:
+	f = GlyphFormat8;
+	break;
+    case 16:
+	f = GlyphFormat16;
+	break;
+    case 32:
+	f = GlyphFormat32;
+	break;
+    default:
+	return BadMatch;
+    }
+    if (format->type != PictTypeDirect)
+	return BadMatch;
+    glyphSet = AllocateGlyphSet (f, format);
+    if (!glyphSet)
+	return BadAlloc;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return Success;
+}
+
+static int
+ProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderReferenceGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq);
+
+    LEGAL_NEW_RESOURCE(stuff->gsid, client);
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->existing,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->existing;
+	return RenderErrBase + BadGlyphSet;
+    }
+    glyphSet->refcnt++;
+    if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet))
+	return BadAlloc;
+    return client->noClientException;
+}
+
+#define NLOCALDELTA	64
+#define NLOCALGLYPH	256
+
+static int
+ProcRenderFreeGlyphSet (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderFreeGlyphSetReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityDestroyAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    FreeResource (stuff->glyphset, RT_NONE);
+    return client->noClientException;
+}
+
+typedef struct _GlyphNew {
+    Glyph	id;
+    GlyphPtr    glyph;
+} GlyphNewRec, *GlyphNewPtr;
+
+static int
+ProcRenderAddGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    REQUEST(xRenderAddGlyphsReq);
+    GlyphNewRec	    glyphsLocal[NLOCALGLYPH];
+    GlyphNewPtr	    glyphsBase, glyphs;
+    GlyphPtr	    glyph;
+    int		    remain, nglyphs;
+    CARD32	    *gids;
+    xGlyphInfo	    *gi;
+    CARD8	    *bits;
+    int		    size;
+    int		    err = BadAlloc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    nglyphs = stuff->nglyphs;
+    if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec))
+	    return BadAlloc;
+
+    if (nglyphs <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+
+    remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq);
+
+    glyphs = glyphsBase;
+
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + nglyphs);
+    bits = (CARD8 *) (gi + nglyphs);
+    remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs;
+    while (remain >= 0 && nglyphs)
+    {
+	glyph = AllocateGlyph (gi, glyphSet->fdepth);
+	if (!glyph)
+	{
+	    err = BadAlloc;
+	    goto bail;
+	}
+	
+	glyphs->glyph = glyph;
+	glyphs->id = *gids;	
+	
+	size = glyph->size - sizeof (xGlyphInfo);
+	if (remain < size)
+	    break;
+	memcpy ((CARD8 *) (glyph + 1), bits, size);
+	
+	if (size & 3)
+	    size += 4 - (size & 3);
+	bits += size;
+	remain -= size;
+	gi++;
+	gids++;
+	glyphs++;
+	nglyphs--;
+    }
+    if (nglyphs || remain)
+    {
+	err = BadLength;
+	goto bail;
+    }
+    nglyphs = stuff->nglyphs;
+    if (!ResizeGlyphSet (glyphSet, nglyphs))
+    {
+	err = BadAlloc;
+	goto bail;
+    }
+    glyphs = glyphsBase;
+    while (nglyphs--) {
+	AddGlyph (glyphSet, glyphs->glyph, glyphs->id);
+	glyphs++;
+    }
+
+    if (glyphsBase != glyphsLocal)
+	Xfree (glyphsBase);
+    return client->noClientException;
+bail:
+    while (glyphs != glyphsBase)
+    {
+	--glyphs;
+	xfree (glyphs->glyph);
+    }
+    if (glyphsBase != glyphsLocal)
+	Xfree (glyphsBase);
+    return err;
+}
+
+static int
+ProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+ProcRenderFreeGlyphs (ClientPtr client)
+{
+    REQUEST(xRenderFreeGlyphsReq);
+    GlyphSetPtr     glyphSet;
+    int		    nglyph;
+    CARD32	    *gids;
+    CARD32	    glyph;
+
+    REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq);
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityWriteAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+    nglyph = ((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)) >> 2;
+    gids = (CARD32 *) (stuff + 1);
+    while (nglyph-- > 0)
+    {
+	glyph = *gids++;
+	if (!DeleteGlyph (glyphSet, glyph))
+	{
+	    client->errorValue = glyph;
+	    return RenderErrBase + BadGlyph;
+	}
+    }
+    return client->noClientException;
+}
+
+static int
+ProcRenderCompositeGlyphs (ClientPtr client)
+{
+    GlyphSetPtr     glyphSet;
+    GlyphSet	    gs;
+    PicturePtr      pSrc, pDst;
+    PictFormatPtr   pFormat;
+    GlyphListRec    listsLocal[NLOCALDELTA];
+    GlyphListPtr    lists, listsBase;
+    GlyphPtr	    glyphsLocal[NLOCALGLYPH];
+    Glyph	    glyph;
+    GlyphPtr	    *glyphs, *glyphsBase;
+    xGlyphElt	    *elt;
+    CARD8	    *buffer, *end;
+    int		    nglyph;
+    int		    nlist;
+    int		    space;
+    int		    size;
+    int		    n;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess,
+		    RenderErrBase + BadPicture);
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen)
+	return BadMatch;
+    if (stuff->maskFormat)
+    {
+	pFormat = (PictFormatPtr) SecurityLookupIDByType (client,
+							  stuff->maskFormat,
+							  PictFormatType,
+							  SecurityReadAccess);
+	if (!pFormat)
+	{
+	    client->errorValue = stuff->maskFormat;
+	    return RenderErrBase + BadPictFormat;
+	}
+    }
+    else
+	pFormat = 0;
+
+    glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+						     stuff->glyphset,
+						     GlyphSetType,
+						     SecurityReadAccess);
+    if (!glyphSet)
+    {
+	client->errorValue = stuff->glyphset;
+	return RenderErrBase + BadGlyphSet;
+    }
+
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    nglyph = 0;
+    nlist = 0;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    buffer += 4;
+	}
+	else
+	{
+	    nlist++;
+	    nglyph += elt->len;
+	    space = size * elt->len;
+	    if (space & 3)
+		space += 4 - (space & 3);
+	    buffer += space;
+	}
+    }
+    if (nglyph <= NLOCALGLYPH)
+	glyphsBase = glyphsLocal;
+    else
+    {
+	glyphsBase = (GlyphPtr *) ALLOCATE_LOCAL (nglyph * sizeof (GlyphPtr));
+	if (!glyphsBase)
+	    return BadAlloc;
+    }
+    if (nlist <= NLOCALDELTA)
+	listsBase = listsLocal;
+    else
+    {
+	listsBase = (GlyphListPtr) ALLOCATE_LOCAL (nlist * sizeof (GlyphListRec));
+	if (!listsBase)
+	    return BadAlloc;
+    }
+    buffer = (CARD8 *) (stuff + 1);
+    glyphs = glyphsBase;
+    lists = listsBase;
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	if (elt->len == 0xff)
+	{
+	    if (buffer + sizeof (GlyphSet) < end)
+	    {
+                memcpy(&gs, buffer, sizeof(GlyphSet));
+		glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client,
+								 gs,
+								 GlyphSetType,
+								 SecurityReadAccess);
+		if (!glyphSet)
+		{
+		    client->errorValue = gs;
+		    if (glyphsBase != glyphsLocal)
+			DEALLOCATE_LOCAL (glyphsBase);
+		    if (listsBase != listsLocal)
+			DEALLOCATE_LOCAL (listsBase);
+		    return RenderErrBase + BadGlyphSet;
+		}
+	    }
+	    buffer += 4;
+	}
+	else
+	{
+	    lists->xOff = elt->deltax;
+	    lists->yOff = elt->deltay;
+	    lists->format = glyphSet->format;
+	    lists->len = 0;
+	    n = elt->len;
+	    while (n--)
+	    {
+		if (buffer + size <= end)
+		{
+		    switch (size) {
+		    case 1:
+			glyph = *((CARD8 *)buffer); break;
+		    case 2:
+			glyph = *((CARD16 *)buffer); break;
+		    case 4:
+		    default:
+			glyph = *((CARD32 *)buffer); break;
+		    }
+		    if ((*glyphs = FindGlyph (glyphSet, glyph)))
+		    {
+			lists->len++;
+			glyphs++;
+		    }
+		}
+		buffer += size;
+	    }
+	    space = size * elt->len;
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	    lists++;
+	}
+    }
+    if (buffer > end)
+	return BadLength;
+
+    CompositeGlyphs (stuff->op,
+		     pSrc,
+		     pDst,
+		     pFormat,
+		     stuff->xSrc,
+		     stuff->ySrc,
+		     nlist,
+		     listsBase,
+		     glyphsBase);
+
+    if (glyphsBase != glyphsLocal)
+	DEALLOCATE_LOCAL (glyphsBase);
+    if (listsBase != listsLocal)
+	DEALLOCATE_LOCAL (listsBase);
+    
+    return client->noClientException;
+}
+
+static int
+ProcRenderFillRectangles (ClientPtr client)
+{
+    PicturePtr	    pDst;
+    int             things;
+    REQUEST(xRenderFillRectanglesReq);
+    
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    if (!PictOpValid (stuff->op))
+    {
+	client->errorValue = stuff->op;
+	return BadValue;
+    }
+    VERIFY_PICTURE (pDst, stuff->dst, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pDst->pDrawable)
+        return BadDrawable;
+    
+    things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq);
+    if (things & 4)
+	return(BadLength);
+    things >>= 3;
+    
+    CompositeRects (stuff->op,
+		    pDst,
+		    &stuff->color,
+		    things,
+		    (xRectangle *) &stuff[1]);
+    
+    return client->noClientException;
+}
+
+static void
+SetBit (unsigned char *line, int x, int bit)
+{
+    unsigned char   mask;
+    
+    if (screenInfo.bitmapBitOrder == LSBFirst)
+	mask = (1 << (x & 7));
+    else
+	mask = (0x80 >> (x & 7));
+    /* XXX assumes byte order is host byte order */
+    line += (x >> 3);
+    if (bit)
+	*line |= mask;
+    else
+	*line &= ~mask;
+}
+
+#define DITHER_DIM 2
+
+static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = {
+    {  1,  3,  },
+    {  4,  2,  },
+};
+
+#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static int
+ProcRenderCreateCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateCursorReq);
+    PicturePtr	    pSrc;
+    ScreenPtr	    pScreen;
+    unsigned short  width, height;
+    CARD32	    *argbbits, *argb;
+    unsigned char   *srcbits, *srcline;
+    unsigned char   *mskbits, *mskline;
+    int		    stride;
+    int		    x, y;
+    int		    nbytes_mono;
+    CursorMetricRec cm;
+    CursorPtr	    pCursor;
+    CARD32	    twocolor[3];
+    int		    ncolor;
+
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    
+    VERIFY_PICTURE (pSrc, stuff->src, client, SecurityReadAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pSrc->pDrawable)
+        return BadDrawable;
+    pScreen = pSrc->pDrawable->pScreen;
+    width = pSrc->pDrawable->width;
+    height = pSrc->pDrawable->height;
+    if ( stuff->x > width 
+      || stuff->y > height )
+	return (BadMatch);
+    argbbits = xalloc (width * height * sizeof (CARD32));
+    if (!argbbits)
+	return (BadAlloc);
+    
+    stride = BitmapBytePad(width);
+    nbytes_mono = stride*height;
+    srcbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!srcbits)
+    {
+	xfree (argbbits);
+	return (BadAlloc);
+    }
+    mskbits = (unsigned char *)xalloc(nbytes_mono);
+    if (!mskbits)
+    {
+	xfree(argbbits);
+	xfree(srcbits);
+	return (BadAlloc);
+    }
+    bzero ((char *) mskbits, nbytes_mono);
+    bzero ((char *) srcbits, nbytes_mono);
+
+    if (pSrc->format == PICT_a8r8g8b8)
+    {
+	(*pScreen->GetImage) (pSrc->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+    }
+    else
+    {
+	PixmapPtr	pPixmap;
+	PicturePtr	pPicture;
+	PictFormatPtr	pFormat;
+	int		error;
+
+	pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+	if (!pFormat)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadImplementation);
+	}
+	pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32);
+	if (!pPixmap)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return (BadAlloc);
+	}
+	pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, 
+				  client, &error);
+	if (!pPicture)
+	{
+	    xfree (argbbits);
+	    xfree (srcbits);
+	    xfree (mskbits);
+	    return error;
+	}
+	(*pScreen->DestroyPixmap) (pPixmap);
+	CompositePicture (PictOpSrc,
+			  pSrc, 0, pPicture,
+			  0, 0, 0, 0, 0, 0, width, height);
+	(*pScreen->GetImage) (pPicture->pDrawable,
+			      0, 0, width, height, ZPixmap,
+			      0xffffffff, (pointer) argbbits);
+	FreePicture (pPicture, 0);
+    }
+    /*
+     * Check whether the cursor can be directly supported by 
+     * the core cursor code
+     */
+    ncolor = 0;
+    argb = argbbits;
+    for (y = 0; ncolor <= 2 && y < height; y++)
+    {
+	for (x = 0; ncolor <= 2 && x < width; x++)
+	{
+	    CARD32  p = *argb++;
+	    CARD32  a = (p >> 24);
+
+	    if (a == 0)	    /* transparent */
+		continue;
+	    if (a == 0xff)  /* opaque */
+	    {
+		int n;
+		for (n = 0; n < ncolor; n++)
+		    if (p == twocolor[n])
+			break;
+		if (n == ncolor)
+		    twocolor[ncolor++] = p;
+	    }
+	    else
+		ncolor = 3;
+	}
+    }
+    
+    /*
+     * Convert argb image to two plane cursor
+     */
+    srcline = srcbits;
+    mskline = mskbits;
+    argb = argbbits;
+    for (y = 0; y < height; y++)
+    {
+	for (x = 0; x < width; x++)
+	{
+	    CARD32  p = *argb++;
+
+	    if (ncolor <= 2)
+	    {
+		CARD32	a = ((p >> 24));
+
+		SetBit (mskline, x, a != 0);
+		SetBit (srcline, x, a != 0 && p == twocolor[0]);
+	    }
+	    else
+	    {
+		CARD32	a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+		CARD32	i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255;
+		CARD32	d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+		/* Set mask from dithered alpha value */
+		SetBit(mskline, x, a > d);
+		/* Set src from dithered intensity value */
+		SetBit(srcline, x, a > d && i <= d);
+	    }
+	}
+	srcline += stride;
+	mskline += stride;
+    }
+    /*
+     * Dither to white and black if the cursor has more than two colors
+     */
+    if (ncolor > 2)
+    {
+	twocolor[0] = 0xff000000;
+	twocolor[1] = 0xffffffff;
+    }
+    else
+    {
+	xfree (argbbits);
+	argbbits = 0;
+    }
+    
+#define GetByte(p,s)	(((p) >> (s)) & 0xff)
+#define GetColor(p,s)	(GetByte(p,s) | (GetByte(p,s) << 8))
+    
+    cm.width = width;
+    cm.height = height;
+    cm.xhot = stuff->x;
+    cm.yhot = stuff->y;
+    pCursor = AllocCursorARGB (srcbits, mskbits, argbbits, &cm,
+			       GetColor(twocolor[0], 16),
+			       GetColor(twocolor[0], 8),
+			       GetColor(twocolor[0], 0),
+			       GetColor(twocolor[1], 16),
+			       GetColor(twocolor[1], 8),
+			       GetColor(twocolor[1], 0));
+    if (pCursor && AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return (client->noClientException);
+    return BadAlloc;
+}
+
+static int
+ProcRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    PicturePtr	pPicture;
+    int		result;
+
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    result = SetPictureTransform (pPicture, (PictTransform *) &stuff->transform);
+    if (client->noClientException != Success)
+        return(client->noClientException);
+    else
+        return(result);
+}
+
+static int
+ProcRenderQueryFilters (ClientPtr client)
+{
+    REQUEST (xRenderQueryFiltersReq);
+    DrawablePtr			pDrawable;
+    xRenderQueryFiltersReply	*reply;
+    int				nbytesName;
+    int				nnames;
+    ScreenPtr			pScreen;
+    PictureScreenPtr		ps;
+    int				i, j;
+    int				len;
+    int				total_bytes;
+    INT16			*aliases;
+    char			*names;
+
+    REQUEST_SIZE_MATCH(xRenderQueryFiltersReq);
+    SECURITY_VERIFY_DRAWABLE(pDrawable, stuff->drawable, client, SecurityReadAccess);
+    
+    pScreen = pDrawable->pScreen;
+    nbytesName = 0;
+    nnames = 0;
+    ps = GetPictureScreenIfSet(pScreen);
+    if (ps)
+    {
+	for (i = 0; i < ps->nfilters; i++)
+	    nbytesName += 1 + strlen (ps->filters[i].name);
+	for (i = 0; i < ps->nfilterAliases; i++)
+	    nbytesName += 1 + strlen (ps->filterAliases[i].alias);
+	nnames = ps->nfilters + ps->nfilterAliases;
+    }
+    len = ((nnames + 1) >> 1) + ((nbytesName + 3) >> 2);
+    total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2);
+    reply = (xRenderQueryFiltersReply *) xalloc (total_bytes);
+    if (!reply)
+	return BadAlloc;
+    aliases = (INT16 *) (reply + 1);
+    names = (char *) (aliases + ((nnames + 1) & ~1));
+    
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = len;
+    reply->numAliases = nnames;
+    reply->numFilters = nnames;
+    if (ps)
+    {
+
+	/* fill in alias values */
+	for (i = 0; i < ps->nfilters; i++)
+	    aliases[i] = FilterAliasNone;
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    for (j = 0; j < ps->nfilters; j++)
+		if (ps->filterAliases[i].filter_id == ps->filters[j].id)
+		    break;
+	    if (j == ps->nfilters)
+	    {
+		for (j = 0; j < ps->nfilterAliases; j++)
+		    if (ps->filterAliases[i].filter_id == 
+			ps->filterAliases[j].alias_id)
+		    {
+			break;
+		    }
+		if (j == ps->nfilterAliases)
+		    j = FilterAliasNone;
+		else
+		    j = j + ps->nfilters;
+	    }
+	    aliases[i + ps->nfilters] = j;
+	}
+
+	/* fill in filter names */
+	for (i = 0; i < ps->nfilters; i++)
+	{
+	    j = strlen (ps->filters[i].name);
+	    *names++ = j;
+	    strncpy (names, ps->filters[i].name, j);
+	    names += j;
+	}
+	
+	/* fill in filter alias names */
+	for (i = 0; i < ps->nfilterAliases; i++)
+	{
+	    j = strlen (ps->filterAliases[i].alias);
+	    *names++ = j;
+	    strncpy (names, ps->filterAliases[i].alias, j);
+	    names += j;
+	}
+    }
+
+    if (client->swapped)
+    {
+	register int n;
+
+	for (i = 0; i < reply->numAliases; i++)
+	{
+	    swaps (&aliases[i], n);
+	}
+    	swaps(&reply->sequenceNumber, n);
+    	swapl(&reply->length, n);
+	swapl(&reply->numAliases, n);
+	swapl(&reply->numFilters, n);
+    }
+    WriteToClient(client, total_bytes, (char *) reply);
+    xfree (reply);
+    
+    return(client->noClientException);
+}
+
+static int
+ProcRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST (xRenderSetPictureFilterReq);
+    PicturePtr	pPicture;
+    int		result;
+    xFixed	*params;
+    int		nparams;
+    char	*name;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess,
+		    RenderErrBase + BadPicture);
+    name = (char *) (stuff + 1);
+    params = (xFixed *) (name + ((stuff->nbytes + 3) & ~3));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams);
+    return result;
+}
+
+static int
+ProcRenderCreateAnimCursor (ClientPtr client)
+{
+    REQUEST(xRenderCreateAnimCursorReq);
+    CursorPtr	    *cursors;
+    CARD32	    *deltas;
+    CursorPtr	    pCursor;
+    int		    ncursor;
+    xAnimCursorElt  *elt;
+    int		    i;
+    int		    ret;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq);
+    LEGAL_NEW_RESOURCE(stuff->cid, client);
+    if (client->req_len & 1)
+	return BadLength;
+    ncursor = (client->req_len - (SIZEOF(xRenderCreateAnimCursorReq) >> 2)) >> 1;
+    cursors = xalloc (ncursor * (sizeof (CursorPtr) + sizeof (CARD32)));
+    if (!cursors)
+	return BadAlloc;
+    deltas = (CARD32 *) (cursors + ncursor);
+    elt = (xAnimCursorElt *) (stuff + 1);
+    for (i = 0; i < ncursor; i++)
+    {
+	cursors[i] = (CursorPtr)SecurityLookupIDByType(client, elt->cursor,
+						       RT_CURSOR, SecurityReadAccess);
+	if (!cursors[i])
+	{
+	    xfree (cursors);
+	    client->errorValue = elt->cursor;
+	    return BadCursor;
+	}
+	deltas[i] = elt->delay;
+	elt++;
+    }
+    ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor);
+    xfree (cursors);
+    if (ret != Success)
+	return ret;
+    
+    if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor))
+	return client->noClientException;
+    return BadAlloc;
+}
+
+static int
+ProcRenderAddTraps (ClientPtr client)
+{
+    int		ntraps;
+    PicturePtr	pPicture;
+    REQUEST(xRenderAddTrapsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq);
+    VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityWriteAccess, 
+		    RenderErrBase + BadPicture);
+    if (!pPicture->pDrawable)
+        return BadDrawable;
+    ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+    if (ntraps % sizeof (xTrap))
+	return BadLength;
+    ntraps /= sizeof (xTrap);
+    if (ntraps)
+	AddTraps (pPicture,
+		  stuff->xOff, stuff->yOff,
+		  ntraps, (xTrap *) &stuff[1]);
+    return client->noClientException;
+}
+
+static int ProcRenderCreateSolidFill(ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    error = 0;
+    REQUEST(xRenderCreateSolidFillReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateLinearGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateLinearGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2,
+                                            stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateRadialGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateRadialGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer,
+                                            stuff->inner_radius, stuff->outer_radius,
+                                            stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+static int ProcRenderCreateConicalGradient (ClientPtr client)
+{
+    PicturePtr	    pPicture;
+    int		    len;
+    int		    error = 0;
+    xFixed          *stops;
+    xRenderColor   *colors;
+    REQUEST(xRenderCreateConicalGradientReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq);
+
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    stops = (xFixed *)(stuff + 1);
+    colors = (xRenderColor *)(stops + stuff->nStops);
+
+    pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle,
+                                             stuff->nStops, stops, colors, &error);
+    if (!pPicture)
+	return error;
+    if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
+	return BadAlloc;
+    return Success;
+}
+
+
+static int
+ProcRenderDispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+    
+    if (stuff->data < RenderNumberRequests)
+	return (*ProcRenderVector[stuff->data]) (client);
+    else
+	return BadRequest;
+}
+
+static int
+SProcRenderQueryVersion (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->majorVersion, n);
+    swapl(&stuff->minorVersion, n);
+    return (*ProcRenderVector[stuff->renderReqType])(client);
+}
+
+static int
+SProcRenderQueryPictFormats (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictFormatsReq);
+    swaps(&stuff->length, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryPictIndexValues (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderQueryPictIndexValuesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryDithers (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreatePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreatePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->format, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderChangePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderChangePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->mask, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderSetPictureClipRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFreePicture (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreePictureReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderComposite (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCompositeReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->mask, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xMask, n);
+    swaps(&stuff->yMask, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderScale (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderScaleReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->colorScale, n);
+    swapl(&stuff->alphaScale, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    swaps(&stuff->xDst, n);
+    swaps(&stuff->yDst, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTrapezoids (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrapezoidsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTrianglesReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriStrip (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriStripReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriStripReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderTriFan (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderTriFanReq);
+
+    REQUEST_AT_LEAST_SIZE(xRenderTriFanReq);
+    swaps (&stuff->length, n);
+    swapl (&stuff->src, n);
+    swapl (&stuff->dst, n);
+    swapl (&stuff->maskFormat, n);
+    swaps (&stuff->xSrc, n);
+    swaps (&stuff->ySrc, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderColorTrapezoids (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderColorTriangles (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderTransform (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderCreateGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->format, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderReferenceGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderReferenceGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->gsid, n);
+    swapl(&stuff->existing, n);
+    return (*ProcRenderVector[stuff->renderReqType])  (client);
+}
+
+static int
+SProcRenderFreeGlyphSet (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphSetReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphs (ClientPtr client)
+{
+    register int n;
+    register int i;
+    CARD32  *gids;
+    void    *end;
+    xGlyphInfo *gi;
+    REQUEST(xRenderAddGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    swapl(&stuff->nglyphs, n);
+    if (stuff->nglyphs & 0xe0000000)
+	return BadLength;
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    gids = (CARD32 *) (stuff + 1);
+    gi = (xGlyphInfo *) (gids + stuff->nglyphs);
+    if ((char *) end - (char *) (gids + stuff->nglyphs) < 0)
+	return BadLength;
+    if ((char *) end - (char *) (gi + stuff->nglyphs) < 0)
+	return BadLength;
+    for (i = 0; i < stuff->nglyphs; i++)
+    {
+	swapl (&gids[i], n);
+	swaps (&gi[i].width, n);
+	swaps (&gi[i].height, n);
+	swaps (&gi[i].x, n);
+	swaps (&gi[i].y, n);
+	swaps (&gi[i].xOff, n);
+	swaps (&gi[i].yOff, n);
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddGlyphsFromPicture (ClientPtr client)
+{
+    return BadImplementation;
+}
+
+static int
+SProcRenderFreeGlyphs (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFreeGlyphsReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->glyphset, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCompositeGlyphs (ClientPtr client)
+{
+    register int n;
+    xGlyphElt	*elt;
+    CARD8	*buffer;
+    CARD8	*end;
+    int		space;
+    int		i;
+    int		size;
+    
+    REQUEST(xRenderCompositeGlyphsReq);
+    
+    switch (stuff->renderReqType) {
+    default:			    size = 1; break;
+    case X_RenderCompositeGlyphs16: size = 2; break;
+    case X_RenderCompositeGlyphs32: size = 4; break;
+    }
+	    
+    swaps(&stuff->length, n);
+    swapl(&stuff->src, n);
+    swapl(&stuff->dst, n);
+    swapl(&stuff->maskFormat, n);
+    swapl(&stuff->glyphset, n);
+    swaps(&stuff->xSrc, n);
+    swaps(&stuff->ySrc, n);
+    buffer = (CARD8 *) (stuff + 1);
+    end = (CARD8 *) stuff + (client->req_len << 2);
+    while (buffer + sizeof (xGlyphElt) < end)
+    {
+	elt = (xGlyphElt *) buffer;
+	buffer += sizeof (xGlyphElt);
+	
+	swaps (&elt->deltax, n);
+	swaps (&elt->deltay, n);
+	
+	i = elt->len;
+	if (i == 0xff)
+	{
+	    swapl (buffer, n);
+	    buffer += 4;
+	}
+	else
+	{
+	    space = size * i;
+	    switch (size) {
+	    case 1:
+		buffer += i;
+		break;
+	    case 2:
+		while (i--)
+		{
+		    swaps (buffer, n);
+		    buffer += 2;
+		}
+		break;
+	    case 4:
+		while (i--)
+		{
+		    swapl (buffer, n);
+		    buffer += 4;
+		}
+		break;
+	    }
+	    if (space & 3)
+		buffer += 4 - (space & 3);
+	}
+    }
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderFillRectangles (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderFillRectanglesReq);
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    swaps(&stuff->length, n);
+    swapl(&stuff->dst, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    swaps(&stuff->color.alpha, n);
+    SwapRestS(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderCreateCursorReq);
+    REQUEST_SIZE_MATCH (xRenderCreateCursorReq);
+    
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    swapl(&stuff->src, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureTransform (ClientPtr client)
+{
+    register int n;
+    REQUEST(xRenderSetPictureTransformReq);
+    REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swapl(&stuff->transform.matrix11, n);
+    swapl(&stuff->transform.matrix12, n);
+    swapl(&stuff->transform.matrix13, n);
+    swapl(&stuff->transform.matrix21, n);
+    swapl(&stuff->transform.matrix22, n);
+    swapl(&stuff->transform.matrix23, n);
+    swapl(&stuff->transform.matrix31, n);
+    swapl(&stuff->transform.matrix32, n);
+    swapl(&stuff->transform.matrix33, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderQueryFilters (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderQueryFiltersReq);
+    REQUEST_SIZE_MATCH (xRenderQueryFiltersReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->drawable, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderSetPictureFilter (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderSetPictureFilterReq);
+    REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->nbytes, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+    
+static int
+SProcRenderCreateAnimCursor (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateAnimCursorReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->cid, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderAddTraps (ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderAddTrapsReq);
+    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->picture, n);
+    swaps(&stuff->xOff, n);
+    swaps(&stuff->yOff, n);
+    SwapRestL(stuff);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateSolidFill(ClientPtr client)
+{
+    register int n;
+    REQUEST (xRenderCreateSolidFillReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swaps(&stuff->color.alpha, n);
+    swaps(&stuff->color.red, n);
+    swaps(&stuff->color.green, n);
+    swaps(&stuff->color.blue, n);
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static void swapStops(void *stuff, int n)
+{
+    int i;
+    CARD32 *stops;
+    CARD16 *colors;
+    stops = (CARD32 *)(stuff);
+    for (i = 0; i < n; ++i) {
+        swapl(stops, n);
+        ++stops;
+    }
+    colors = (CARD16 *)(stops);
+    for (i = 0; i < 4*n; ++i) {
+        swaps(stops, n);
+        ++stops;
+    }
+}
+
+static int
+SProcRenderCreateLinearGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateLinearGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->p1.x, n);
+    swapl(&stuff->p1.y, n);
+    swapl(&stuff->p2.x, n);
+    swapl(&stuff->p2.y, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateRadialGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateRadialGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->inner.x, n);
+    swapl(&stuff->inner.y, n);
+    swapl(&stuff->outer.x, n);
+    swapl(&stuff->outer.y, n);
+    swapl(&stuff->inner_radius, n);
+    swapl(&stuff->outer_radius, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderCreateConicalGradient (ClientPtr client)
+{
+    register int n;
+    int len;
+    REQUEST (xRenderCreateConicalGradientReq);
+    REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->center.x, n);
+    swapl(&stuff->center.y, n);
+    swapl(&stuff->angle, n);
+    swapl(&stuff->nStops, n);
+
+    len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
+        return BadLength;
+
+    swapStops(stuff+1, stuff->nStops);
+
+    return (*ProcRenderVector[stuff->renderReqType]) (client);
+}
+
+static int
+SProcRenderDispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+    
+    if (stuff->data < RenderNumberRequests)
+	return (*SProcRenderVector[stuff->data]) (client);
+    else
+	return BadRequest;
+}
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err) {\
+    pPicture = SecurityLookupIDByType(client, pid, XRT_PICTURE, mode);\
+    if (!pPicture) { \
+	client->errorValue = pid; \
+	return err; \
+    } \
+}
+
+#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode, err) {\
+    if (pid == None) \
+	pPicture = 0; \
+    else { \
+	VERIFY_XIN_PICTURE(pPicture, pid, client, mode, err); \
+    } \
+} \
+
+int	    (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr);
+
+unsigned long	XRT_PICTURE;
+
+static int
+PanoramiXRenderCreatePicture (ClientPtr client)
+{
+    REQUEST(xRenderCreatePictureReq);
+    PanoramiXRes    *refDraw, *newPict;
+    int		    result = Success, j;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq);
+    if(!(refDraw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+    if(!(newPict = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+    newPict->type = XRT_PICTURE;
+    newPict->info[0].id = stuff->pid;
+    
+    if (refDraw->type == XRT_WINDOW &&
+	stuff->drawable == WindowTable[0]->drawable.id)
+    {
+	newPict->u.pict.root = TRUE;
+    }
+    else
+	newPict->u.pict.root = FALSE;
+
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPict->info[j].id = FakeClientID(client->index);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->pid = newPict->info[j].id;
+	stuff->drawable = refDraw->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client);
+	if(result != Success) break;
+    }
+
+    if (result == Success)
+	AddResource(newPict->info[0].id, XRT_PICTURE, newPict);
+    else 
+	xfree(newPict);
+
+    return (result);
+}
+
+static int
+PanoramiXRenderChangePicture (ClientPtr client)
+{
+    PanoramiXRes    *pict;
+    int		    result = Success, j;
+    REQUEST(xRenderChangePictureReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureClipRectangles (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureClipRectanglesReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureTransform (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureTransformReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderSetPictureFilter (ClientPtr client)
+{
+    REQUEST(xRenderSetPictureFilterReq);
+    int		    result = Success, j;
+    PanoramiXRes    *pict;
+
+    REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq);
+    
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityWriteAccess,
+		       RenderErrBase + BadPicture);
+    
+    FOR_NSCREENS_BACKWARD(j) {
+        stuff->picture = pict->info[j].id;
+        result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client);
+        if(result != Success) break;
+    }
+
+    return (result);
+}
+
+static int
+PanoramiXRenderFreePicture (ClientPtr client)
+{
+    PanoramiXRes *pict;
+    int         result = Success, j;
+    REQUEST(xRenderFreePictureReq);
+
+    REQUEST_SIZE_MATCH(xRenderFreePictureReq);
+
+    client->errorValue = stuff->picture;
+
+    VERIFY_XIN_PICTURE(pict, stuff->picture, client, SecurityDestroyAccess,
+		       RenderErrBase + BadPicture);
+    
+
+    FOR_NSCREENS_BACKWARD(j) {
+	stuff->picture = pict->info[j].id;
+	result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client);
+	if(result != Success) break;
+    }
+
+    /* Since ProcRenderFreePicture is using FreeResource, it will free
+	our resource for us on the last pass through the loop above */
+ 
+    return (result);
+}
+
+static int
+PanoramiXRenderComposite (ClientPtr client)
+{
+    PanoramiXRes	*src, *msk, *dst;
+    int			result = Success, j;
+    xRenderCompositeReq	orig;
+    REQUEST(xRenderCompositeReq);
+
+    REQUEST_SIZE_MATCH(xRenderCompositeReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess, 
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_ALPHA (msk, stuff->mask, client, SecurityReadAccess, 
+		      RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    
+    orig = *stuff;
+    
+    FOR_NSCREENS_FORWARD(j) {
+	stuff->src = src->info[j].id;
+	if (src->u.pict.root)
+	{
+	    stuff->xSrc = orig.xSrc - panoramiXdataPtr[j].x;
+	    stuff->ySrc = orig.ySrc - panoramiXdataPtr[j].y;
+	}
+	stuff->dst = dst->info[j].id;
+	if (dst->u.pict.root)
+	{
+	    stuff->xDst = orig.xDst - panoramiXdataPtr[j].x;
+	    stuff->yDst = orig.yDst - panoramiXdataPtr[j].y;
+	}
+	if (msk)
+	{
+	    stuff->mask = msk->info[j].id;
+	    if (msk->u.pict.root)
+	    {
+		stuff->xMask = orig.xMask - panoramiXdataPtr[j].x;
+		stuff->yMask = orig.yMask - panoramiXdataPtr[j].y;
+	    }
+	}
+	result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client);
+	if(result != Success) break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderCompositeGlyphs (ClientPtr client)
+{
+    PanoramiXRes    *src, *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderCompositeGlyphsReq);
+    xGlyphElt	    origElt, *elt;
+    INT16	    xSrc, ySrc;
+
+    REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq);
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) +
+				 sizeof (xGlyphElt)))
+    {
+	elt = (xGlyphElt *) (stuff + 1);
+	origElt = *elt;
+	xSrc = stuff->xSrc;
+	ySrc = stuff->ySrc;
+	FOR_NSCREENS_FORWARD(j) {
+	    stuff->src = src->info[j].id;
+	    if (src->u.pict.root)
+	    {
+		stuff->xSrc = xSrc - panoramiXdataPtr[j].x;
+		stuff->ySrc = ySrc - panoramiXdataPtr[j].y;
+	    }
+	    stuff->dst = dst->info[j].id;
+	    if (dst->u.pict.root)
+	    {
+		elt->deltax = origElt.deltax - panoramiXdataPtr[j].x;
+		elt->deltay = origElt.deltay - panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client);
+	    if(result != Success) break;
+	}
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderFillRectangles (ClientPtr client)
+{
+    PanoramiXRes    *dst;
+    int		    result = Success, j;
+    REQUEST(xRenderFillRectanglesReq);
+    char	    *extra;
+    int		    extra_len;
+
+    REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root)
+	    {
+		int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+		    xRectangle	*rects = (xRectangle *) (stuff + 1);
+		    int		i = extra_len / sizeof (xRectangle);
+
+		    while (i--)
+		    {
+			rects->x -= x_off;
+			rects->y -= y_off;
+			rects++;
+		    }
+		}
+	    }
+	    stuff->dst = dst->info[j].id;
+	    result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTrapezoids(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTrapezoidsReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xTrapezoid  *trap = (xTrapezoid *) (stuff + 1);
+		    int         i = extra_len / sizeof (xTrapezoid);
+
+		    while (i--) {
+			trap->top -= y_off;
+			trap->bottom -= y_off;
+			trap->left.p1.x -= x_off;
+			trap->left.p1.y -= y_off;
+			trap->left.p2.x -= x_off;
+			trap->left.p2.y -= y_off;
+			trap->right.p1.x -= x_off;
+			trap->right.p1.y -= y_off;
+			trap->right.p2.x -= x_off;
+			trap->right.p2.y -= y_off;
+			trap++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriangles(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTrianglesReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xTriangle  *tri = (xTriangle *) (stuff + 1);
+		    int         i = extra_len / sizeof (xTriangle);
+
+		    while (i--) {
+			tri->p1.x -= x_off;
+			tri->p1.y -= y_off;
+			tri->p2.x -= x_off;
+			tri->p2.y -= y_off;
+			tri->p3.x -= x_off;
+			tri->p3.y -= y_off;
+			tri++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriangles]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriStrip(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTriStripReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTriStripReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
+		    int         i = extra_len / sizeof (xPointFixed);
+
+		    while (i--) {
+			fixed->x -= x_off;
+			fixed->y -= y_off;
+			fixed++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderTriFan(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderTriFanReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderTriFanReq);
+    
+    VERIFY_XIN_PICTURE (src, stuff->src, client, SecurityReadAccess,
+			RenderErrBase + BadPicture);
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+                    xPointFixed  *fixed = (xPointFixed *) (stuff + 1);
+		    int         i = extra_len / sizeof (xPointFixed);
+
+		    while (i--) {
+			fixed->x -= x_off;
+			fixed->y -= y_off;
+			fixed++;
+		    }
+		}
+	    }
+	    
+            stuff->src = src->info[j].id;
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderTriFan]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+#if 0 /* Not implemented yet */
+
+static int
+PanoramiXRenderColorTrapezoids(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderColorTrapezoidsReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderColorTrapezoidsReq);
+    
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderColorTrapezoidsReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+			....; 
+		}
+	    }
+	    
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderColorTrapezoids]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+static int
+PanoramiXRenderColorTriangles(ClientPtr client)
+{
+    PanoramiXRes        *src, *dst;
+    int                 result = Success, j;
+    REQUEST(xRenderColorTrianglesReq);
+    char		*extra;
+    int			extra_len;
+    
+    REQUEST_AT_LEAST_SIZE (xRenderColorTrianglesReq);
+    
+    VERIFY_XIN_PICTURE (dst, stuff->dst, client, SecurityWriteAccess,
+			RenderErrBase + BadPicture);
+
+    extra_len = (client->req_len << 2) - sizeof (xRenderColorTrianglesReq);
+
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len))) {
+	memcpy (extra, stuff + 1, extra_len);
+
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    if (dst->u.pict.root) {
+                int x_off = panoramiXdataPtr[j].x;
+		int y_off = panoramiXdataPtr[j].y;
+
+		if(x_off || y_off) {
+			....; 
+		}
+	    }
+	    
+            stuff->dst = dst->info[j].id;
+	    result =
+		(*PanoramiXSaveRenderVector[X_RenderColorTriangles]) (client);
+
+	    if(result != Success) break;
+	}
+	
+        DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+#endif
+
+static int
+PanoramiXRenderAddTraps (ClientPtr client)
+{
+    PanoramiXRes    *picture;
+    int		    result = Success, j;
+    REQUEST(xRenderAddTrapsReq);
+    char	    *extra;
+    int		    extra_len;
+    INT16    	    x_off, y_off;
+
+    REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq);
+    VERIFY_XIN_PICTURE (picture, stuff->picture, client, SecurityWriteAccess, 
+			RenderErrBase + BadPicture);
+    extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq);
+    if (extra_len &&
+	(extra = (char *) ALLOCATE_LOCAL (extra_len)))
+    {
+	memcpy (extra, stuff + 1, extra_len);
+	x_off = stuff->xOff;
+	y_off = stuff->yOff;
+	FOR_NSCREENS_FORWARD(j) {
+	    if (j) memcpy (stuff + 1, extra, extra_len);
+	    stuff->picture = picture->info[j].id;
+	    
+	    if (picture->u.pict.root)
+	    {
+		stuff->xOff = x_off + panoramiXdataPtr[j].x;
+		stuff->yOff = y_off + panoramiXdataPtr[j].y;
+	    }
+	    result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client);
+	    if(result != Success) break;
+	}
+	DEALLOCATE_LOCAL(extra);
+    }
+
+    return result;
+}
+
+void
+PanoramiXRenderInit (void)
+{
+    int	    i;
+    
+    XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource);
+    for (i = 0; i < RenderNumberRequests; i++)
+	PanoramiXSaveRenderVector[i] = ProcRenderVector[i];
+    /*
+     * Stuff in Xinerama aware request processing hooks
+     */
+    ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture;
+    ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture;
+    ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform;
+    ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter;
+    ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles;
+    ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture;
+    ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite;
+    ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs;
+    ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles;
+
+    ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids;
+    ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles;
+    ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip;
+    ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan;
+    ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps;
+}
+
+void
+PanoramiXRenderReset (void)
+{
+    int	    i;
+    for (i = 0; i < RenderNumberRequests; i++)
+	ProcRenderVector[i] = PanoramiXSaveRenderVector[i];
+}
+
+#endif	/* PANORAMIX */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
new file mode 100644
index 000000000..9af5c4187
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -0,0 +1,1173 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/*	Routines to manage various kinds of resources:
+ *
+ *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ *	FakeClientID, AddResource, FreeResource, FreeClientResources,
+ *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/* 
+ *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ *	off-limits for client-visible resources.  The next 8 bits are
+ *      used as client ID, and the low 22 bits come from the client.
+ *	A resource ID is "hashed" by extracting and xoring subfields
+ *      (varying with the size of the hash table).
+ *
+ *      It is sometimes necessary for the server to create an ID that looks
+ *      like it belongs to a client.  This ID, however,  must not be one
+ *      the client actually can create, or we have the potential for conflict.
+ *      The 31st bit of the ID is reserved for the server's use for this
+ *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ *      resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h" 
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#endif
+
+static void RebuildTable(
+    int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+    struct _Resource	*next;
+    XID			id;
+    RESTYPE		type;
+    pointer		value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+    ResourcePtr *resources;
+    int		elements;
+    int		buckets;
+    int		hashsize;	/* log(2)(buckets) */
+    XID		fakeID;
+    XID		endFakeID;
+    XID		expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+    RESTYPE next = lastResourceType + 1;
+    DeleteType *funcs;
+
+    if (next & lastResourceClass)
+	return 0;
+    funcs = (DeleteType *)xrealloc(DeleteFuncs,
+				   (next + 1) * sizeof(DeleteType));
+    if (!funcs)
+	return 0;
+
+#ifdef XResExtension
+    {
+       Atom *newnames;
+       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+       if(!newnames)
+           return 0;
+       ResourceNames = newnames;
+       ResourceNames[next] = 0;
+    }
+#endif
+
+    lastResourceType = next;
+    DeleteFuncs = funcs;
+    DeleteFuncs[next] = deleteFunc;
+    return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+    RESTYPE next = lastResourceClass >> 1;
+
+    if (next & lastResourceType)
+	return 0;
+    lastResourceClass = next;
+    TypeMask = next - 1;
+    return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ *    When a new client is created, call this to allocate space
+ *    in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+    register int i, j;
+ 
+    if (client == serverClient)
+    {
+	lastResourceType = RT_LASTPREDEF;
+	lastResourceClass = RC_LASTPREDEF;
+	TypeMask = RC_LASTPREDEF - 1;
+	if (DeleteFuncs)
+	    xfree(DeleteFuncs);
+	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+					   sizeof(DeleteType));
+	if (!DeleteFuncs)
+	    return FALSE;
+	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+        if(ResourceNames)
+            xfree(ResourceNames);
+        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+        if(!ResourceNames)
+           return FALSE;
+#endif
+    }
+    clientTable[i = client->index].resources =
+	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+    if (!clientTable[i].resources)
+	return FALSE;
+    clientTable[i].buckets = INITBUCKETS;
+    clientTable[i].elements = 0;
+    clientTable[i].hashsize = INITHASHSIZE;
+    /* Many IDs allocated from the server client are visible to clients,
+     * so we don't use the SERVER_BIT for them, but we have to start
+     * past the magic value constants used in the protocol.  For normal
+     * clients, we can start from zero, with SERVER_BIT set.
+     */
+    clientTable[i].fakeID = client->clientAsMask |
+			    (client->index ? SERVER_BIT : SERVER_MINID);
+    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+    clientTable[i].expectID = client->clientAsMask;
+    for (j=0; j<INITBUCKETS; j++) 
+    {
+        clientTable[i].resources[j] = NullResource;
+    }
+    return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+    id &= RESOURCE_ID_MASK;
+    switch (clientTable[client].hashsize)
+    {
+	case 6:
+	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+	case 7:
+	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+	case 8:
+	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+	case 9:
+	    return ((int)(0x1FF & (id ^ (id>>9))));
+	case 10:
+	    return ((int)(0x3FF & (id ^ (id>>10))));
+	case 11:
+	    return ((int)(0x7FF & (id ^ (id>>11))));
+    }
+    return -1;
+}
+
+static XID
+AvailableID(
+    register int client,
+    register XID id,
+    register XID maxid,
+    register XID goodid)
+{
+    register ResourcePtr res;
+
+    if ((goodid >= id) && (goodid <= maxid))
+	return goodid;
+    for (; id <= maxid; id++)
+    {
+	res = clientTable[client].resources[Hash(client, id)];
+	while (res && (res->id != id))
+	    res = res->next;
+	if (!res)
+	    return id;
+    }
+    return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+    register XID id, maxid;
+    register ResourcePtr *resp;
+    register ResourcePtr res;
+    register int i;
+    XID goodid;
+
+    id = (Mask)client << CLIENTOFFSET;
+    if (server)
+	id |= client ? SERVER_BIT : SERVER_MINID;
+    maxid = id | RESOURCE_ID_MASK;
+    goodid = 0;
+    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+	 --i >= 0;)
+    {
+	for (res = *resp++; res; res = res->next)
+	{
+	    if ((res->id < id) || (res->id > maxid))
+		continue;
+	    if (((res->id - id) >= (maxid - res->id)) ?
+		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
+		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+		maxid = res->id - 1;
+	    else
+		id = res->id + 1;
+	}
+    }
+    if (id > maxid)
+	id = maxid = 0;
+    *minp = id;
+    *maxp = maxid;
+}
+
+/**
+ *  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ *  This function tries to find count unused XIDs for the given client.  It 
+ *  puts the IDs in the array pids and returns the number found, which should
+ *  almost always be the number requested.
+ *
+ *  The circumstances that lead to a call to this function are very rare.
+ *  Xlib must run out of IDs while trying to generate a request that wants
+ *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ *  No rocket science in the implementation; just iterate over all
+ *  possible IDs for the given client and pick the first count IDs
+ *  that aren't in use.  A more efficient algorithm could probably be
+ *  invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+    unsigned int found = 0;
+    XID id = pClient->clientAsMask;
+    XID maxid;
+
+    maxid = id | RESOURCE_ID_MASK;
+    while ( (found < count) && (id <= maxid) )
+    {
+	if (!LookupIDByClass(id, RC_ANY))
+	{
+	    pids[found++] = id;
+	}
+	id++;
+    }
+    return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+    XID id, maxid;
+
+    id = clientTable[client].fakeID++;
+    if (id != clientTable[client].endFakeID)
+	return id;
+    GetXIDRange(client, TRUE, &id, &maxid);
+    if (!id) {
+	if (!client)
+	    FatalError("FakeClientID: server internal ids exhausted\n");
+	MarkClientException(clients[client]);
+	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+	maxid = id | RESOURCE_ID_MASK;
+    }
+    clientTable[client].fakeID = id + 1;
+    clientTable[client].endFakeID = maxid + 1;
+    return id;
+}
+
+#ifdef NXAGENT_SERVER
+
+int nxagentFindClientResource(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  int i;
+
+  for (i = 0; i < clientTable[client].buckets; i++)
+  {
+    resources = clientTable[client].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == type && pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+                    "for client [%d].\n", (void *) value,
+                        pResource -> type, client);
+        #endif
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  RESTYPE internalType = 0;
+
+  int i;
+
+  if (type == RT_PIXMAP)
+  {
+    internalType = RT_NX_PIXMAP;
+  }
+  else if (type == RT_GC)
+  {
+    internalType = RT_NX_GC;
+  }
+  else if (type == RT_FONT)
+  {
+    internalType = RT_NX_FONT;
+  }
+  else
+  {
+    return 0;
+  }
+
+  if (client == serverClient -> index)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+                client);
+    #endif
+
+    return 0;
+  }
+
+  for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+  {
+    resources = clientTable[serverClient -> index].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == internalType &&
+              pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+                    "[%lu] for server client [%d].\n", (void *) value,
+                        (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+        #endif
+
+        FreeResource(pResource -> id, RT_NONE);
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+#endif
+
+Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+    int client;
+    register ClientResourceRec *rrec;
+    register ResourcePtr res, *head;
+
+    client = CLIENT_ID(id);
+    rrec = &clientTable[client];
+    if (!rrec->buckets)
+    {
+	ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+		(unsigned long)id, type, (unsigned long)value, client);
+        FatalError("client not in use\n");
+    }
+
+#ifdef NXAGENT_SERVER
+
+    nxagentSwitchResourceType(client, type, value);
+
+    #ifdef TEST
+    fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+                client, (unsigned long) type, (void *) value, (unsigned long) id);
+    #endif
+
+#endif
+
+    if ((rrec->elements >= 4*rrec->buckets) &&
+	(rrec->hashsize < MAXHASHSIZE))
+	RebuildTable(client);
+    head = &rrec->resources[Hash(client, id)];
+    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+    if (!res)
+    {
+	(*DeleteFuncs[type & TypeMask])(value, id);
+	return FALSE;
+    }
+    res->next = *head;
+    res->id = id;
+    res->type = type;
+    res->value = value;
+    *head = res;
+    rrec->elements++;
+    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+	rrec->expectID = id + 1;
+    return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+    register int j;
+    register ResourcePtr res, next;
+    ResourcePtr **tails, *resources;
+    register ResourcePtr **tptr, *rptr;
+
+    /*
+     * For now, preserve insertion order, since some ddx layers depend
+     * on resources being free in the opposite order they are added.
+     */
+
+    j = 2 * clientTable[client].buckets;
+    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+    if (!tails)
+	return;
+    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+    if (!resources)
+    {
+	DEALLOCATE_LOCAL(tails);
+	return;
+    }
+    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+    {
+	*rptr = NullResource;
+	*tptr = rptr;
+    }
+    clientTable[client].hashsize++;
+    for (j = clientTable[client].buckets,
+	 rptr = clientTable[client].resources;
+	 --j >= 0;
+	 rptr++)
+    {
+	for (res = *rptr; res; res = next)
+	{
+	    next = res->next;
+	    res->next = NullResource;
+	    tptr = &tails[Hash(client, res->id)];
+	    **tptr = res;
+	    *tptr = &res->next;
+	}
+    }
+    DEALLOCATE_LOCAL(tails);
+    clientTable[client].buckets *= 2;
+    xfree(clientTable[client].resources);
+    clientTable[client].resources = resources;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    register	int *eltptr;
+    int		elements;
+    Bool	gotOne = FALSE;
+
+#ifdef NXAGENT_SERVER
+
+    #ifdef TEST
+    fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
+    #endif
+
+#endif
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+	eltptr = &clientTable[cid].elements;
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id)
+	    {
+		RESTYPE rtype = res->type;
+		*prev = res->next;
+		elements = --*eltptr;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (rtype != skipDeleteFuncType)
+		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+		xfree(res);
+		if (*eltptr != elements)
+		    prev = head; /* prev may no longer be valid */
+		gotOne = TRUE;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+    if (!gotOne)
+	ErrorF("Freeing resource id=%lX which isn't there.\n",
+		   (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id && res->type == type)
+	    {
+		*prev = res->next;
+		if (type & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (!skipFree)
+		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+		xfree(res);
+		break;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+}
+
+/*
+ * Change the value associated with a resource id.  Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		res->value = value;
+		return TRUE;
+	    }
+    }
+    return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources.  If func adds new resources,
+ * func might or might not get called for them.  func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+    ClientPtr client,
+    RESTYPE type,
+    FindResType func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    #ifdef NXAGENT_SERVER
+    register ResourcePtr **resptr;
+    #endif
+
+    if (!client)
+	client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++) 
+    {
+        for (this = resources[i]; this; this = next)
+	{
+	    next = this->next;
+	    if (!type || this->type == type) {
+		elements = *eltptr;
+		(*func)(this->value, this->id, cdata);
+                #ifdef NXAGENT_SERVER
+                if (*resptr != resources)
+                   goto RestartLoop;
+                #endif
+		if (*eltptr != elements)
+		    next = resources[i]; /* start over */
+	    }
+	}
+    }
+}
+
+void
+FindAllClientResources(
+    ClientPtr client,
+    FindAllRes func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    #ifdef NXAGENT_SERVER
+    register ResourcePtr **resptr;
+    #endif
+
+    if (!client)
+        client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++)
+    {
+        for (this = resources[i]; this; this = next)
+        {
+            next = this->next;
+            elements = *eltptr;
+            (*func)(this->value, this->id, this->type, cdata);
+            #ifdef NXAGENT_SERVER
+            if (*resptr != resources)
+                goto RestartLoop;
+            #endif
+            if (*eltptr != elements)
+                next = resources[i]; /* start over */
+        }
+    }
+}
+
+
+pointer
+LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata
+){
+    ResourcePtr *resources;
+    ResourcePtr this;
+    int i;
+
+    #ifdef NXAGENT_SERVER
+    ResourcePtr **resptr;
+    Bool res;
+    #endif
+
+    if (!client)
+	client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    for (i = 0; i < clientTable[client->index].buckets; i++) {
+        for (this = resources[i]; this; this = this->next) {
+	    if (!type || this->type == type) {
+                #ifdef NXAGENT_SERVER
+                res = (*func)(this->value, this->id, cdata);
+
+                if (*resptr != resources)
+                    goto RestartLoop;
+
+                if (res)
+                    return this->value;
+                #else
+		if((*func)(this->value, this->id, cdata))
+		    return this->value;
+                #endif
+	    }
+	}
+    }
+    return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+    ResourcePtr *resources;
+    ResourcePtr this;
+    ResourcePtr *prev;
+    int j;
+
+    if (!client)
+	return;
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+	prev = &resources[j];
+        while ( (this = *prev) )
+	{
+	    RESTYPE rtype = this->type;
+	    if (rtype & RC_NEVERRETAIN)
+	    {
+		*prev = this->next;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(this->id);
+		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+		xfree(this);	    
+	    }
+	    else
+		prev = &this->next;
+	}
+    }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+    register ResourcePtr *resources;
+    register ResourcePtr this;
+    int j;
+
+    /* This routine shouldn't be called with a null client, but just in
+	case ... */
+
+    if (!client)
+	return;
+
+    HandleSaveSet(client);
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+        /* It may seem silly to update the head of this resource list as
+	we delete the members, since the entire list will be deleted any way, 
+	but there are some resource deletion functions "FreeClientPixels" for 
+	one which do a LookupID on another resource id (a Colormap id in this
+	case), so the resource list must be kept valid up to the point that
+	it is deleted, so every time we delete a resource, we must update the
+	head, just like in FreeResource. I hope that this doesn't slow down
+	mass deletion appreciably. PRH */
+
+	ResourcePtr *head;
+
+	head = &resources[j];
+
+        for (this = *head; this; this = *head)
+	{
+	    RESTYPE rtype = this->type;
+	    *head = this->next;
+	    if (rtype & RC_CACHED)
+		FlushClientCaches(this->id);
+	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+	    xfree(this);	    
+	}
+    }
+    xfree(clientTable[client->index].resources);
+    clientTable[client->index].resources = NULL;
+    clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+    int	i;
+
+    for (i = currentMaxClients; --i >= 0; ) 
+    {
+        if (clientTable[i].buckets) 
+	    FreeClientResources(clients[i]);
+    }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+    XID 	minid, maxid;
+
+	if (!noPanoramiXExtension) { 
+	    minid = client->clientAsMask | (client->index ? 
+			                    SERVER_BIT : SERVER_MINID);
+	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+            if ((id >= minid) && (id <= maxid))
+	        return TRUE;
+	}
+#endif /* PANORAMIX */
+	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+	    ((clientTable[client->index].expectID <= id) ||
+	     !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system.  They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+    int    cid;
+    register    ResourcePtr res;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert( (rtype & TypeMask) <= lastResourceType);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+    return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+    int    cid;
+    register ResourcePtr res = NULL;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert (classes >= lastResourceClass);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+    return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    return SecurityLookupIDByType(NullClient, id, rtype,
+				  SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    return SecurityLookupIDByClass(NullClient, id, classes,
+				   SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ *  LookupIDByType returns the object with the given id and type, else NULL.
+ */ 
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+/*
+ *  LookupIDByClass returns the object with the given id and any one of the
+ *  given classes, else NULL.
+ */ 
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
new file mode 100644
index 000000000..9af5c4187
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -0,0 +1,1173 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/*	Routines to manage various kinds of resources:
+ *
+ *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ *	FakeClientID, AddResource, FreeResource, FreeClientResources,
+ *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/* 
+ *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ *	off-limits for client-visible resources.  The next 8 bits are
+ *      used as client ID, and the low 22 bits come from the client.
+ *	A resource ID is "hashed" by extracting and xoring subfields
+ *      (varying with the size of the hash table).
+ *
+ *      It is sometimes necessary for the server to create an ID that looks
+ *      like it belongs to a client.  This ID, however,  must not be one
+ *      the client actually can create, or we have the potential for conflict.
+ *      The 31st bit of the ID is reserved for the server's use for this
+ *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ *      resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h" 
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#endif
+
+static void RebuildTable(
+    int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+    struct _Resource	*next;
+    XID			id;
+    RESTYPE		type;
+    pointer		value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+    ResourcePtr *resources;
+    int		elements;
+    int		buckets;
+    int		hashsize;	/* log(2)(buckets) */
+    XID		fakeID;
+    XID		endFakeID;
+    XID		expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+    RESTYPE next = lastResourceType + 1;
+    DeleteType *funcs;
+
+    if (next & lastResourceClass)
+	return 0;
+    funcs = (DeleteType *)xrealloc(DeleteFuncs,
+				   (next + 1) * sizeof(DeleteType));
+    if (!funcs)
+	return 0;
+
+#ifdef XResExtension
+    {
+       Atom *newnames;
+       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+       if(!newnames)
+           return 0;
+       ResourceNames = newnames;
+       ResourceNames[next] = 0;
+    }
+#endif
+
+    lastResourceType = next;
+    DeleteFuncs = funcs;
+    DeleteFuncs[next] = deleteFunc;
+    return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+    RESTYPE next = lastResourceClass >> 1;
+
+    if (next & lastResourceType)
+	return 0;
+    lastResourceClass = next;
+    TypeMask = next - 1;
+    return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ *    When a new client is created, call this to allocate space
+ *    in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+    register int i, j;
+ 
+    if (client == serverClient)
+    {
+	lastResourceType = RT_LASTPREDEF;
+	lastResourceClass = RC_LASTPREDEF;
+	TypeMask = RC_LASTPREDEF - 1;
+	if (DeleteFuncs)
+	    xfree(DeleteFuncs);
+	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+					   sizeof(DeleteType));
+	if (!DeleteFuncs)
+	    return FALSE;
+	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+        if(ResourceNames)
+            xfree(ResourceNames);
+        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+        if(!ResourceNames)
+           return FALSE;
+#endif
+    }
+    clientTable[i = client->index].resources =
+	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+    if (!clientTable[i].resources)
+	return FALSE;
+    clientTable[i].buckets = INITBUCKETS;
+    clientTable[i].elements = 0;
+    clientTable[i].hashsize = INITHASHSIZE;
+    /* Many IDs allocated from the server client are visible to clients,
+     * so we don't use the SERVER_BIT for them, but we have to start
+     * past the magic value constants used in the protocol.  For normal
+     * clients, we can start from zero, with SERVER_BIT set.
+     */
+    clientTable[i].fakeID = client->clientAsMask |
+			    (client->index ? SERVER_BIT : SERVER_MINID);
+    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+    clientTable[i].expectID = client->clientAsMask;
+    for (j=0; j<INITBUCKETS; j++) 
+    {
+        clientTable[i].resources[j] = NullResource;
+    }
+    return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+    id &= RESOURCE_ID_MASK;
+    switch (clientTable[client].hashsize)
+    {
+	case 6:
+	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+	case 7:
+	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+	case 8:
+	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+	case 9:
+	    return ((int)(0x1FF & (id ^ (id>>9))));
+	case 10:
+	    return ((int)(0x3FF & (id ^ (id>>10))));
+	case 11:
+	    return ((int)(0x7FF & (id ^ (id>>11))));
+    }
+    return -1;
+}
+
+static XID
+AvailableID(
+    register int client,
+    register XID id,
+    register XID maxid,
+    register XID goodid)
+{
+    register ResourcePtr res;
+
+    if ((goodid >= id) && (goodid <= maxid))
+	return goodid;
+    for (; id <= maxid; id++)
+    {
+	res = clientTable[client].resources[Hash(client, id)];
+	while (res && (res->id != id))
+	    res = res->next;
+	if (!res)
+	    return id;
+    }
+    return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+    register XID id, maxid;
+    register ResourcePtr *resp;
+    register ResourcePtr res;
+    register int i;
+    XID goodid;
+
+    id = (Mask)client << CLIENTOFFSET;
+    if (server)
+	id |= client ? SERVER_BIT : SERVER_MINID;
+    maxid = id | RESOURCE_ID_MASK;
+    goodid = 0;
+    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+	 --i >= 0;)
+    {
+	for (res = *resp++; res; res = res->next)
+	{
+	    if ((res->id < id) || (res->id > maxid))
+		continue;
+	    if (((res->id - id) >= (maxid - res->id)) ?
+		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
+		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+		maxid = res->id - 1;
+	    else
+		id = res->id + 1;
+	}
+    }
+    if (id > maxid)
+	id = maxid = 0;
+    *minp = id;
+    *maxp = maxid;
+}
+
+/**
+ *  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ *  This function tries to find count unused XIDs for the given client.  It 
+ *  puts the IDs in the array pids and returns the number found, which should
+ *  almost always be the number requested.
+ *
+ *  The circumstances that lead to a call to this function are very rare.
+ *  Xlib must run out of IDs while trying to generate a request that wants
+ *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ *  No rocket science in the implementation; just iterate over all
+ *  possible IDs for the given client and pick the first count IDs
+ *  that aren't in use.  A more efficient algorithm could probably be
+ *  invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+    unsigned int found = 0;
+    XID id = pClient->clientAsMask;
+    XID maxid;
+
+    maxid = id | RESOURCE_ID_MASK;
+    while ( (found < count) && (id <= maxid) )
+    {
+	if (!LookupIDByClass(id, RC_ANY))
+	{
+	    pids[found++] = id;
+	}
+	id++;
+    }
+    return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+    XID id, maxid;
+
+    id = clientTable[client].fakeID++;
+    if (id != clientTable[client].endFakeID)
+	return id;
+    GetXIDRange(client, TRUE, &id, &maxid);
+    if (!id) {
+	if (!client)
+	    FatalError("FakeClientID: server internal ids exhausted\n");
+	MarkClientException(clients[client]);
+	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+	maxid = id | RESOURCE_ID_MASK;
+    }
+    clientTable[client].fakeID = id + 1;
+    clientTable[client].endFakeID = maxid + 1;
+    return id;
+}
+
+#ifdef NXAGENT_SERVER
+
+int nxagentFindClientResource(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  int i;
+
+  for (i = 0; i < clientTable[client].buckets; i++)
+  {
+    resources = clientTable[client].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == type && pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+                    "for client [%d].\n", (void *) value,
+                        pResource -> type, client);
+        #endif
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  RESTYPE internalType = 0;
+
+  int i;
+
+  if (type == RT_PIXMAP)
+  {
+    internalType = RT_NX_PIXMAP;
+  }
+  else if (type == RT_GC)
+  {
+    internalType = RT_NX_GC;
+  }
+  else if (type == RT_FONT)
+  {
+    internalType = RT_NX_FONT;
+  }
+  else
+  {
+    return 0;
+  }
+
+  if (client == serverClient -> index)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+                client);
+    #endif
+
+    return 0;
+  }
+
+  for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+  {
+    resources = clientTable[serverClient -> index].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == internalType &&
+              pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+                    "[%lu] for server client [%d].\n", (void *) value,
+                        (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+        #endif
+
+        FreeResource(pResource -> id, RT_NONE);
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+#endif
+
+Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+    int client;
+    register ClientResourceRec *rrec;
+    register ResourcePtr res, *head;
+
+    client = CLIENT_ID(id);
+    rrec = &clientTable[client];
+    if (!rrec->buckets)
+    {
+	ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+		(unsigned long)id, type, (unsigned long)value, client);
+        FatalError("client not in use\n");
+    }
+
+#ifdef NXAGENT_SERVER
+
+    nxagentSwitchResourceType(client, type, value);
+
+    #ifdef TEST
+    fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+                client, (unsigned long) type, (void *) value, (unsigned long) id);
+    #endif
+
+#endif
+
+    if ((rrec->elements >= 4*rrec->buckets) &&
+	(rrec->hashsize < MAXHASHSIZE))
+	RebuildTable(client);
+    head = &rrec->resources[Hash(client, id)];
+    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+    if (!res)
+    {
+	(*DeleteFuncs[type & TypeMask])(value, id);
+	return FALSE;
+    }
+    res->next = *head;
+    res->id = id;
+    res->type = type;
+    res->value = value;
+    *head = res;
+    rrec->elements++;
+    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+	rrec->expectID = id + 1;
+    return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+    register int j;
+    register ResourcePtr res, next;
+    ResourcePtr **tails, *resources;
+    register ResourcePtr **tptr, *rptr;
+
+    /*
+     * For now, preserve insertion order, since some ddx layers depend
+     * on resources being free in the opposite order they are added.
+     */
+
+    j = 2 * clientTable[client].buckets;
+    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+    if (!tails)
+	return;
+    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+    if (!resources)
+    {
+	DEALLOCATE_LOCAL(tails);
+	return;
+    }
+    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+    {
+	*rptr = NullResource;
+	*tptr = rptr;
+    }
+    clientTable[client].hashsize++;
+    for (j = clientTable[client].buckets,
+	 rptr = clientTable[client].resources;
+	 --j >= 0;
+	 rptr++)
+    {
+	for (res = *rptr; res; res = next)
+	{
+	    next = res->next;
+	    res->next = NullResource;
+	    tptr = &tails[Hash(client, res->id)];
+	    **tptr = res;
+	    *tptr = &res->next;
+	}
+    }
+    DEALLOCATE_LOCAL(tails);
+    clientTable[client].buckets *= 2;
+    xfree(clientTable[client].resources);
+    clientTable[client].resources = resources;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    register	int *eltptr;
+    int		elements;
+    Bool	gotOne = FALSE;
+
+#ifdef NXAGENT_SERVER
+
+    #ifdef TEST
+    fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
+    #endif
+
+#endif
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+	eltptr = &clientTable[cid].elements;
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id)
+	    {
+		RESTYPE rtype = res->type;
+		*prev = res->next;
+		elements = --*eltptr;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (rtype != skipDeleteFuncType)
+		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+		xfree(res);
+		if (*eltptr != elements)
+		    prev = head; /* prev may no longer be valid */
+		gotOne = TRUE;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+    if (!gotOne)
+	ErrorF("Freeing resource id=%lX which isn't there.\n",
+		   (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id && res->type == type)
+	    {
+		*prev = res->next;
+		if (type & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (!skipFree)
+		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+		xfree(res);
+		break;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+}
+
+/*
+ * Change the value associated with a resource id.  Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		res->value = value;
+		return TRUE;
+	    }
+    }
+    return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources.  If func adds new resources,
+ * func might or might not get called for them.  func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+    ClientPtr client,
+    RESTYPE type,
+    FindResType func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    #ifdef NXAGENT_SERVER
+    register ResourcePtr **resptr;
+    #endif
+
+    if (!client)
+	client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++) 
+    {
+        for (this = resources[i]; this; this = next)
+	{
+	    next = this->next;
+	    if (!type || this->type == type) {
+		elements = *eltptr;
+		(*func)(this->value, this->id, cdata);
+                #ifdef NXAGENT_SERVER
+                if (*resptr != resources)
+                   goto RestartLoop;
+                #endif
+		if (*eltptr != elements)
+		    next = resources[i]; /* start over */
+	    }
+	}
+    }
+}
+
+void
+FindAllClientResources(
+    ClientPtr client,
+    FindAllRes func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    #ifdef NXAGENT_SERVER
+    register ResourcePtr **resptr;
+    #endif
+
+    if (!client)
+        client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++)
+    {
+        for (this = resources[i]; this; this = next)
+        {
+            next = this->next;
+            elements = *eltptr;
+            (*func)(this->value, this->id, this->type, cdata);
+            #ifdef NXAGENT_SERVER
+            if (*resptr != resources)
+                goto RestartLoop;
+            #endif
+            if (*eltptr != elements)
+                next = resources[i]; /* start over */
+        }
+    }
+}
+
+
+pointer
+LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata
+){
+    ResourcePtr *resources;
+    ResourcePtr this;
+    int i;
+
+    #ifdef NXAGENT_SERVER
+    ResourcePtr **resptr;
+    Bool res;
+    #endif
+
+    if (!client)
+	client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    for (i = 0; i < clientTable[client->index].buckets; i++) {
+        for (this = resources[i]; this; this = this->next) {
+	    if (!type || this->type == type) {
+                #ifdef NXAGENT_SERVER
+                res = (*func)(this->value, this->id, cdata);
+
+                if (*resptr != resources)
+                    goto RestartLoop;
+
+                if (res)
+                    return this->value;
+                #else
+		if((*func)(this->value, this->id, cdata))
+		    return this->value;
+                #endif
+	    }
+	}
+    }
+    return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+    ResourcePtr *resources;
+    ResourcePtr this;
+    ResourcePtr *prev;
+    int j;
+
+    if (!client)
+	return;
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+	prev = &resources[j];
+        while ( (this = *prev) )
+	{
+	    RESTYPE rtype = this->type;
+	    if (rtype & RC_NEVERRETAIN)
+	    {
+		*prev = this->next;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(this->id);
+		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+		xfree(this);	    
+	    }
+	    else
+		prev = &this->next;
+	}
+    }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+    register ResourcePtr *resources;
+    register ResourcePtr this;
+    int j;
+
+    /* This routine shouldn't be called with a null client, but just in
+	case ... */
+
+    if (!client)
+	return;
+
+    HandleSaveSet(client);
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+        /* It may seem silly to update the head of this resource list as
+	we delete the members, since the entire list will be deleted any way, 
+	but there are some resource deletion functions "FreeClientPixels" for 
+	one which do a LookupID on another resource id (a Colormap id in this
+	case), so the resource list must be kept valid up to the point that
+	it is deleted, so every time we delete a resource, we must update the
+	head, just like in FreeResource. I hope that this doesn't slow down
+	mass deletion appreciably. PRH */
+
+	ResourcePtr *head;
+
+	head = &resources[j];
+
+        for (this = *head; this; this = *head)
+	{
+	    RESTYPE rtype = this->type;
+	    *head = this->next;
+	    if (rtype & RC_CACHED)
+		FlushClientCaches(this->id);
+	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+	    xfree(this);	    
+	}
+    }
+    xfree(clientTable[client->index].resources);
+    clientTable[client->index].resources = NULL;
+    clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+    int	i;
+
+    for (i = currentMaxClients; --i >= 0; ) 
+    {
+        if (clientTable[i].buckets) 
+	    FreeClientResources(clients[i]);
+    }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+    XID 	minid, maxid;
+
+	if (!noPanoramiXExtension) { 
+	    minid = client->clientAsMask | (client->index ? 
+			                    SERVER_BIT : SERVER_MINID);
+	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+            if ((id >= minid) && (id <= maxid))
+	        return TRUE;
+	}
+#endif /* PANORAMIX */
+	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+	    ((clientTable[client->index].expectID <= id) ||
+	     !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system.  They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+    int    cid;
+    register    ResourcePtr res;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert( (rtype & TypeMask) <= lastResourceType);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+    return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+    int    cid;
+    register ResourcePtr res = NULL;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert (classes >= lastResourceClass);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+    return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    return SecurityLookupIDByType(NullClient, id, rtype,
+				  SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    return SecurityLookupIDByClass(NullClient, id, classes,
+				   SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ *  LookupIDByType returns the object with the given id and type, else NULL.
+ */ 
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+/*
+ *  LookupIDByClass returns the object with the given id and any one of the
+ *  given classes, else NULL.
+ */ 
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original
new file mode 100644
index 000000000..e12bc7b67
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.X.original
@@ -0,0 +1,954 @@
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/*	Routines to manage various kinds of resources:
+ *
+ *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ *	FakeClientID, AddResource, FreeResource, FreeClientResources,
+ *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/* 
+ *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ *	off-limits for client-visible resources.  The next 8 bits are
+ *      used as client ID, and the low 22 bits come from the client.
+ *	A resource ID is "hashed" by extracting and xoring subfields
+ *      (varying with the size of the hash table).
+ *
+ *      It is sometimes necessary for the server to create an ID that looks
+ *      like it belongs to a client.  This ID, however,  must not be one
+ *      the client actually can create, or we have the potential for conflict.
+ *      The 31st bit of the ID is reserved for the server's use for this
+ *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ *      resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h" 
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+static void RebuildTable(
+    int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+    struct _Resource	*next;
+    XID			id;
+    RESTYPE		type;
+    pointer		value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+    ResourcePtr *resources;
+    int		elements;
+    int		buckets;
+    int		hashsize;	/* log(2)(buckets) */
+    XID		fakeID;
+    XID		endFakeID;
+    XID		expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+    RESTYPE next = lastResourceType + 1;
+    DeleteType *funcs;
+
+    if (next & lastResourceClass)
+	return 0;
+    funcs = (DeleteType *)xrealloc(DeleteFuncs,
+				   (next + 1) * sizeof(DeleteType));
+    if (!funcs)
+	return 0;
+
+#ifdef XResExtension
+    {
+       Atom *newnames;
+       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+       if(!newnames)
+           return 0;
+       ResourceNames = newnames;
+       ResourceNames[next] = 0;
+    }
+#endif
+
+    lastResourceType = next;
+    DeleteFuncs = funcs;
+    DeleteFuncs[next] = deleteFunc;
+    return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+    RESTYPE next = lastResourceClass >> 1;
+
+    if (next & lastResourceType)
+	return 0;
+    lastResourceClass = next;
+    TypeMask = next - 1;
+    return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ *    When a new client is created, call this to allocate space
+ *    in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+    register int i, j;
+ 
+    if (client == serverClient)
+    {
+	lastResourceType = RT_LASTPREDEF;
+	lastResourceClass = RC_LASTPREDEF;
+	TypeMask = RC_LASTPREDEF - 1;
+	if (DeleteFuncs)
+	    xfree(DeleteFuncs);
+	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+					   sizeof(DeleteType));
+	if (!DeleteFuncs)
+	    return FALSE;
+	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+        if(ResourceNames)
+            xfree(ResourceNames);
+        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+        if(!ResourceNames)
+           return FALSE;
+#endif
+    }
+    clientTable[i = client->index].resources =
+	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+    if (!clientTable[i].resources)
+	return FALSE;
+    clientTable[i].buckets = INITBUCKETS;
+    clientTable[i].elements = 0;
+    clientTable[i].hashsize = INITHASHSIZE;
+    /* Many IDs allocated from the server client are visible to clients,
+     * so we don't use the SERVER_BIT for them, but we have to start
+     * past the magic value constants used in the protocol.  For normal
+     * clients, we can start from zero, with SERVER_BIT set.
+     */
+    clientTable[i].fakeID = client->clientAsMask |
+			    (client->index ? SERVER_BIT : SERVER_MINID);
+    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+    clientTable[i].expectID = client->clientAsMask;
+    for (j=0; j<INITBUCKETS; j++) 
+    {
+        clientTable[i].resources[j] = NullResource;
+    }
+    return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+    id &= RESOURCE_ID_MASK;
+    switch (clientTable[client].hashsize)
+    {
+	case 6:
+	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+	case 7:
+	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+	case 8:
+	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+	case 9:
+	    return ((int)(0x1FF & (id ^ (id>>9))));
+	case 10:
+	    return ((int)(0x3FF & (id ^ (id>>10))));
+	case 11:
+	    return ((int)(0x7FF & (id ^ (id>>11))));
+    }
+    return -1;
+}
+
+static XID
+AvailableID(
+    register int client,
+    register XID id,
+    register XID maxid,
+    register XID goodid)
+{
+    register ResourcePtr res;
+
+    if ((goodid >= id) && (goodid <= maxid))
+	return goodid;
+    for (; id <= maxid; id++)
+    {
+	res = clientTable[client].resources[Hash(client, id)];
+	while (res && (res->id != id))
+	    res = res->next;
+	if (!res)
+	    return id;
+    }
+    return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+    register XID id, maxid;
+    register ResourcePtr *resp;
+    register ResourcePtr res;
+    register int i;
+    XID goodid;
+
+    id = (Mask)client << CLIENTOFFSET;
+    if (server)
+	id |= client ? SERVER_BIT : SERVER_MINID;
+    maxid = id | RESOURCE_ID_MASK;
+    goodid = 0;
+    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+	 --i >= 0;)
+    {
+	for (res = *resp++; res; res = res->next)
+	{
+	    if ((res->id < id) || (res->id > maxid))
+		continue;
+	    if (((res->id - id) >= (maxid - res->id)) ?
+		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
+		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+		maxid = res->id - 1;
+	    else
+		id = res->id + 1;
+	}
+    }
+    if (id > maxid)
+	id = maxid = 0;
+    *minp = id;
+    *maxp = maxid;
+}
+
+/**
+ *  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ *  This function tries to find count unused XIDs for the given client.  It 
+ *  puts the IDs in the array pids and returns the number found, which should
+ *  almost always be the number requested.
+ *
+ *  The circumstances that lead to a call to this function are very rare.
+ *  Xlib must run out of IDs while trying to generate a request that wants
+ *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ *  No rocket science in the implementation; just iterate over all
+ *  possible IDs for the given client and pick the first count IDs
+ *  that aren't in use.  A more efficient algorithm could probably be
+ *  invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+    unsigned int found = 0;
+    XID id = pClient->clientAsMask;
+    XID maxid;
+
+    maxid = id | RESOURCE_ID_MASK;
+    while ( (found < count) && (id <= maxid) )
+    {
+	if (!LookupIDByClass(id, RC_ANY))
+	{
+	    pids[found++] = id;
+	}
+	id++;
+    }
+    return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+    XID id, maxid;
+
+    id = clientTable[client].fakeID++;
+    if (id != clientTable[client].endFakeID)
+	return id;
+    GetXIDRange(client, TRUE, &id, &maxid);
+    if (!id) {
+	if (!client)
+	    FatalError("FakeClientID: server internal ids exhausted\n");
+	MarkClientException(clients[client]);
+	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+	maxid = id | RESOURCE_ID_MASK;
+    }
+    clientTable[client].fakeID = id + 1;
+    clientTable[client].endFakeID = maxid + 1;
+    return id;
+}
+
+Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+    int client;
+    register ClientResourceRec *rrec;
+    register ResourcePtr res, *head;
+    	
+    client = CLIENT_ID(id);
+    rrec = &clientTable[client];
+    if (!rrec->buckets)
+    {
+	ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+		(unsigned long)id, type, (unsigned long)value, client);
+        FatalError("client not in use\n");
+    }
+    if ((rrec->elements >= 4*rrec->buckets) &&
+	(rrec->hashsize < MAXHASHSIZE))
+	RebuildTable(client);
+    head = &rrec->resources[Hash(client, id)];
+    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+    if (!res)
+    {
+	(*DeleteFuncs[type & TypeMask])(value, id);
+	return FALSE;
+    }
+    res->next = *head;
+    res->id = id;
+    res->type = type;
+    res->value = value;
+    *head = res;
+    rrec->elements++;
+    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+	rrec->expectID = id + 1;
+    return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+    register int j;
+    register ResourcePtr res, next;
+    ResourcePtr **tails, *resources;
+    register ResourcePtr **tptr, *rptr;
+
+    /*
+     * For now, preserve insertion order, since some ddx layers depend
+     * on resources being free in the opposite order they are added.
+     */
+
+    j = 2 * clientTable[client].buckets;
+    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+    if (!tails)
+	return;
+    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+    if (!resources)
+    {
+	DEALLOCATE_LOCAL(tails);
+	return;
+    }
+    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+    {
+	*rptr = NullResource;
+	*tptr = rptr;
+    }
+    clientTable[client].hashsize++;
+    for (j = clientTable[client].buckets,
+	 rptr = clientTable[client].resources;
+	 --j >= 0;
+	 rptr++)
+    {
+	for (res = *rptr; res; res = next)
+	{
+	    next = res->next;
+	    res->next = NullResource;
+	    tptr = &tails[Hash(client, res->id)];
+	    **tptr = res;
+	    *tptr = &res->next;
+	}
+    }
+    DEALLOCATE_LOCAL(tails);
+    clientTable[client].buckets *= 2;
+    xfree(clientTable[client].resources);
+    clientTable[client].resources = resources;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    register	int *eltptr;
+    int		elements;
+    Bool	gotOne = FALSE;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+	eltptr = &clientTable[cid].elements;
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id)
+	    {
+		RESTYPE rtype = res->type;
+		*prev = res->next;
+		elements = --*eltptr;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (rtype != skipDeleteFuncType)
+		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+		xfree(res);
+		if (*eltptr != elements)
+		    prev = head; /* prev may no longer be valid */
+		gotOne = TRUE;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+    if (!gotOne)
+	ErrorF("Freeing resource id=%lX which isn't there.\n",
+		   (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id && res->type == type)
+	    {
+		*prev = res->next;
+		if (type & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (!skipFree)
+		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+		xfree(res);
+		break;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+}
+
+/*
+ * Change the value associated with a resource id.  Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		res->value = value;
+		return TRUE;
+	    }
+    }
+    return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources.  If func adds new resources,
+ * func might or might not get called for them.  func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+    ClientPtr client,
+    RESTYPE type,
+    FindResType func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++) 
+    {
+        for (this = resources[i]; this; this = next)
+	{
+	    next = this->next;
+	    if (!type || this->type == type) {
+		elements = *eltptr;
+		(*func)(this->value, this->id, cdata);
+		if (*eltptr != elements)
+		    next = resources[i]; /* start over */
+	    }
+	}
+    }
+}
+
+void
+FindAllClientResources(
+    ClientPtr client,
+    FindAllRes func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    if (!client)
+        client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++)
+    {
+        for (this = resources[i]; this; this = next)
+        {
+            next = this->next;
+            elements = *eltptr;
+            (*func)(this->value, this->id, this->type, cdata);
+            if (*eltptr != elements)
+                next = resources[i]; /* start over */
+        }
+    }
+}
+
+
+pointer
+LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata
+){
+    ResourcePtr *resources;
+    ResourcePtr this;
+    int i;
+
+    if (!client)
+	client = serverClient;
+
+    resources = clientTable[client->index].resources;
+    for (i = 0; i < clientTable[client->index].buckets; i++) {
+        for (this = resources[i]; this; this = this->next) {
+	    if (!type || this->type == type) {
+		if((*func)(this->value, this->id, cdata))
+		    return this->value;
+	    }
+	}
+    }
+    return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+    ResourcePtr *resources;
+    ResourcePtr this;
+    ResourcePtr *prev;
+    int j;
+
+    if (!client)
+	return;
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+	prev = &resources[j];
+        while ( (this = *prev) )
+	{
+	    RESTYPE rtype = this->type;
+	    if (rtype & RC_NEVERRETAIN)
+	    {
+		*prev = this->next;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(this->id);
+		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+		xfree(this);	    
+	    }
+	    else
+		prev = &this->next;
+	}
+    }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+    register ResourcePtr *resources;
+    register ResourcePtr this;
+    int j;
+
+    /* This routine shouldn't be called with a null client, but just in
+	case ... */
+
+    if (!client)
+	return;
+
+    HandleSaveSet(client);
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+        /* It may seem silly to update the head of this resource list as
+	we delete the members, since the entire list will be deleted any way, 
+	but there are some resource deletion functions "FreeClientPixels" for 
+	one which do a LookupID on another resource id (a Colormap id in this
+	case), so the resource list must be kept valid up to the point that
+	it is deleted, so every time we delete a resource, we must update the
+	head, just like in FreeResource. I hope that this doesn't slow down
+	mass deletion appreciably. PRH */
+
+	ResourcePtr *head;
+
+	head = &resources[j];
+
+        for (this = *head; this; this = *head)
+	{
+	    RESTYPE rtype = this->type;
+	    *head = this->next;
+	    if (rtype & RC_CACHED)
+		FlushClientCaches(this->id);
+	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+	    xfree(this);	    
+	}
+    }
+    xfree(clientTable[client->index].resources);
+    clientTable[client->index].resources = NULL;
+    clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+    int	i;
+
+    for (i = currentMaxClients; --i >= 0; ) 
+    {
+        if (clientTable[i].buckets) 
+	    FreeClientResources(clients[i]);
+    }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+    XID 	minid, maxid;
+
+	if (!noPanoramiXExtension) { 
+	    minid = client->clientAsMask | (client->index ? 
+			                    SERVER_BIT : SERVER_MINID);
+	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+            if ((id >= minid) && (id <= maxid))
+	        return TRUE;
+	}
+#endif /* PANORAMIX */
+	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+	    ((clientTable[client->index].expectID <= id) ||
+	     !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system.  They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+    int    cid;
+    register    ResourcePtr res;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert( (rtype & TypeMask) <= lastResourceType);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+    return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+    int    cid;
+    register ResourcePtr res = NULL;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert (classes >= lastResourceClass);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+    return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    return SecurityLookupIDByType(NullClient, id, rtype,
+				  SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    return SecurityLookupIDByClass(NullClient, id, classes,
+				   SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ *  LookupIDByType returns the object with the given id and type, else NULL.
+ */ 
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+/*
+ *  LookupIDByClass returns the object with the given id and any one of the
+ *  given classes, else NULL.
+ */ 
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
new file mode 100644
index 000000000..3aecaf229
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -0,0 +1,1455 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */
+/************************************************************
+
+Copyright 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#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 "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "modinit.h"
+
+#include "Trap.h"
+#include "Agent.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
+                           unsigned int format, unsigned long planeMask, char *d);
+
+extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+                            int x, int y, int w, int h, int leftPad, int format,
+                                char *pImage);
+
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+    pointer		/* value */,
+    XID			/* shmseg */
+    );
+static void ShmResetProc(
+    ExtensionEntry *	/* extEntry */
+    );
+static void SShmCompletionEvent(
+    xShmCompletionEvent * /* from */,
+    xShmCompletionEvent * /* to */
+    );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int  shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+    shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+    if (!shmdesc) \
+    { \
+	client->errorValue = shmseg; \
+	return BadShmSegCode; \
+    } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+    VERIFY_SHMSEG(shmseg, shmdesc, client); \
+    if ((offset & 3) || (offset > shmdesc->size)) \
+    { \
+	client->errorValue = offset; \
+	return BadValue; \
+    } \
+    if (needwrite && !shmdesc->writable) \
+	return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+    if ((offset + len) > shmdesc->size) \
+    { \
+	return BadAccess; \
+    } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+    badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+    void (*oldHandler)();
+    int shmid = -1;
+
+    /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+    oldHandler = signal(SIGSYS, SigSysHandler);
+
+    badSysCall = FALSE;
+    shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+
+    if (shmid != -1)
+    {
+        /* Successful allocation - clean up */
+	shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+    }
+    else
+    {
+        /* Allocation failed */
+        badSysCall = TRUE;
+    }
+    signal(SIGSYS, oldHandler);
+    return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+void
+ShmExtensionInit(INITARGS)
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+    if (!CheckForShmSyscall())
+    {
+	ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+	return;
+    }
+#endif
+
+    if (nxagentOption(SharedMemory) == False)
+    {
+      return;
+    }
+
+    sharedPixmaps = xFalse;
+    pixmapFormat = 0;
+    {
+      sharedPixmaps = nxagentOption(SharedPixmaps);
+      pixmapFormat = shmPixFormat[0];
+      for (i = 0; i < screenInfo.numScreens; i++)
+      {
+	if (!shmFuncs[i])
+        {
+            #ifdef TEST
+            fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
+            #endif
+	    shmFuncs[i] = &miFuncs;
+        }
+	if (!shmFuncs[i]->CreatePixmap)
+	    sharedPixmaps = xFalse;
+	if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+	{
+	    sharedPixmaps = xFalse;
+	    pixmapFormat = 0;
+	}
+      }
+      if (!pixmapFormat)
+	pixmapFormat = ZPixmap;
+      if (sharedPixmaps)
+      {
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+	    screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+	}
+#ifdef PIXPRIV
+	shmPixmapPrivate = AllocatePixmapPrivateIndex();
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    if (!AllocatePixmapPrivate(screenInfo.screens[i],
+				       shmPixmapPrivate, 0))
+		return;
+	}
+#endif
+      }
+    }
+    ShmSegType = CreateNewResourceType(ShmDetachSegment);
+    if (ShmSegType &&
+	(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+				 ProcShmDispatch, SProcShmDispatch,
+				 ShmResetProc, StandardMinorOpcode)))
+    {
+	ShmReqCode = (unsigned char)extEntry->base;
+	ShmCompletionCode = extEntry->eventBase;
+	BadShmSegCode = extEntry->errorBase;
+	EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+    }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry	*extEntry;
+{
+    int i;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+	shmFuncs[i] = (ShmFuncsPtr)NULL;
+	shmPixFormat[i] = 0;
+    }
+}
+
+void
+ShmRegisterFuncs(
+    ScreenPtr pScreen,
+    ShmFuncsPtr funcs)
+{
+    shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(
+    ScreenPtr pScreen,
+    int format)
+{
+    shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	    pScreen = pPixmap->drawable.pScreen;
+    Bool	    ret;
+    if (pPixmap->refcnt == 1)
+    {
+	ShmDescPtr  shmdesc;
+#ifdef PIXPRIV
+	shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+	char	*base = (char *) pPixmap->devPrivate.ptr;
+	
+	if (base != (pointer) (pPixmap + 1))
+	{
+	    for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+	    {
+		if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+		    break;
+	    }
+	}
+	else
+	    shmdesc = 0;
+#endif
+	if (shmdesc)
+	    ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+    }
+    
+    pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+    ret = (*pScreen->DestroyPixmap) (pPixmap);
+    destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+    pScreen->DestroyPixmap = ShmDestroyPixmap;
+    return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+    ScreenPtr pScreen;
+{
+    #ifdef TEST
+    fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+    #endif
+    shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+    register ClientPtr client;
+{
+    xShmQueryVersionReply rep;
+    register int n;
+
+    REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.sharedPixmaps = sharedPixmaps;
+    rep.pixmapFormat = pixmapFormat;
+    rep.majorVersion = SHM_MAJOR_VERSION;
+    rep.minorVersion = SHM_MINOR_VERSION;
+    rep.uid = geteuid();
+    rep.gid = getegid();
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+	swaps(&rep.uid, n);
+	swaps(&rep.gid, n);
+    }
+    WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+    int uid, gid;
+    mode_t mask;
+
+    if (LocalClientCred(client, &uid, &gid) != -1) {
+	
+	/* User id 0 always gets access */
+	if (uid == 0) {
+	    return 0;
+	}
+	/* Check the owner */
+	if (perm->uid == uid || perm->cuid == uid) {
+	    mask = S_IRUSR;
+	    if (!readonly) {
+		mask |= S_IWUSR;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+	/* Check the group */
+	if (perm->gid == gid || perm->cgid == gid) {
+	    mask = S_IRGRP;
+	    if (!readonly) {
+		mask |= S_IWGRP;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+    }
+    /* Otherwise, check everyone else */
+    mask = S_IROTH;
+    if (!readonly) {
+	mask |= S_IWOTH;
+    }
+    return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+    register ClientPtr client;
+{
+    struct shmid_ds buf;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmAttachReq);
+
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+    if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+    {
+	client->errorValue = stuff->readOnly;
+        return(BadValue);
+    }
+    for (shmdesc = Shmsegs;
+	 shmdesc && (shmdesc->shmid != stuff->shmid);
+	 shmdesc = shmdesc->next)
+	;
+    if (shmdesc)
+    {
+	if (!stuff->readOnly && !shmdesc->writable)
+	    return BadAccess;
+	shmdesc->refcnt++;
+    }
+    else
+    {
+	shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+	if (!shmdesc)
+	    return BadAlloc;
+	shmdesc->addr = shmat(stuff->shmid, 0,
+			      stuff->readOnly ? SHM_RDONLY : 0);
+	if ((shmdesc->addr == ((char *)-1)) ||
+	    shmctl(stuff->shmid, IPC_STAT, &buf))
+	{
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	/* The attach was performed with root privs. We must
+	 * do manual checking of access rights for the credentials 
+	 * of the client */
+
+	if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+	    shmdt(shmdesc->addr);
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	shmdesc->shmid = stuff->shmid;
+	shmdesc->refcnt = 1;
+	shmdesc->writable = !stuff->readOnly;
+	shmdesc->size = buf.shm_segsz;
+	shmdesc->next = Shmsegs;
+	Shmsegs = shmdesc;
+    }
+    if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+	return BadAlloc;
+    return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+    pointer value; /* must conform to DeleteType */
+    XID shmseg;
+{
+    ShmDescPtr shmdesc = (ShmDescPtr)value;
+    ShmDescPtr *prev;
+
+    if (--shmdesc->refcnt)
+	return TRUE;
+    shmdt(shmdesc->addr);
+    for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+	;
+    *prev = shmdesc->next;
+    xfree(shmdesc);
+    return Success;
+}
+
+static int
+ProcShmDetach(client)
+    register ClientPtr client;
+{
+    ShmDescPtr shmdesc;
+    REQUEST(xShmDetachReq);
+
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+    FreeResource(stuff->shmseg, RT_NONE);
+    return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    PixmapPtr pmap;
+    GCPtr putGC;
+
+    nxagentShmTrap = 0;
+    putGC = GetScratchGC(depth, dst->pScreen);
+    if (!putGC)
+    {
+        nxagentShmTrap = 1;
+	return;
+    }
+    pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+    if (!pmap)
+    {
+        nxagentShmTrap = 1;
+	FreeScratchGC(putGC);
+	return;
+    }
+    ValidateGC((DrawablePtr)pmap, putGC);
+    (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+			    (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+    FreeScratchGC(putGC);
+    if (format == XYBitmap)
+	(void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				     dx, dy, 1L);
+    else
+	(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				    dx, dy);
+    (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+    nxagentShmTrap = 1;
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    int length;
+    char *newdata;
+    extern int nxagentImageLength(int, int, int, int, int);
+
+    #ifdef TEST
+    fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
+                (void *) dst, (void *) pGC, (void *) data);
+    #endif
+
+    if ((format == ZPixmap) || (depth == 1))
+    {
+	PixmapPtr pPixmap;
+
+	pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+		BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+	if (!pPixmap)
+	    return;
+	if (format == XYBitmap)
+	    (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+					 sx, sy, sw, sh, dx, dy, 1L);
+	else
+	    (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+					sx, sy, sw, sh, dx, dy);
+
+        /*
+         * We updated the internal framebuffer,
+         * now we want to go on the real X.
+         */
+
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
+                    " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
+                        " sh [%d] dx [%d].\n", depth, format, w, h,
+                            sx, sy, sw, sh, dx);
+        #endif
+
+        length = nxagentImageLength(sw, sh, format, 0, depth);
+
+        if ((newdata = xalloc(length)) != NULL)
+        {
+          fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
+          (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
+
+          xfree(newdata);
+        }
+        else
+        {
+          #ifdef WARNING
+          fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
+          #endif
+        }
+
+	FreeScratchPixmapHeader(pPixmap);
+    }
+    else
+    {
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
+        #endif
+	miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+		      data);
+    }
+}
+
+
+#ifdef PANORAMIX
+static int 
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+    int			 j, result = 0, orig_x, orig_y;
+    PanoramiXRes	*draw, *gc;
+    Bool		 sendEvent, isRoot;
+
+    REQUEST(xShmPutImageReq);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    orig_x = stuff->dstX;
+    orig_y = stuff->dstY;
+    sendEvent = stuff->sendEvent;
+    stuff->sendEvent = 0;
+    FOR_NSCREENS(j) {
+	if(!j) stuff->sendEvent = sendEvent;
+	stuff->drawable = draw->info[j].id;
+	stuff->gc = gc->info[j].id;
+	if (isRoot) {
+	    stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+	    stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+	}
+	result = ProcShmPutImage(client);
+	if(result != client->noClientException) break;
+    }
+    return(result);
+}
+
+static int 
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+    PanoramiXRes	*draw;
+    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	pDraw;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int         	i, x, y, w, h, format;
+    Mask		plane = 0, planemask;
+    long		lenPer = 0, length, widthBytesLine;
+    Bool		isRoot;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+
+    if (draw->type == XRT_PIXMAP)
+	return ProcShmGetImage(client);
+
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+    x = stuff->x;
+    y = stuff->y;
+    w = stuff->width;
+    h = stuff->height;
+    format = stuff->format;
+    planemask = stuff->planeMask;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    if(isRoot) {
+      if( /* check for being onscreen */
+	x < 0 || x + w > PanoramiXPixWidth ||
+	y < 0 || y + h > PanoramiXPixHeight )
+	    return(BadMatch);
+    } else {
+      if( /* check for being onscreen */
+	panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+	panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+        panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+	panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+	 /* check for being inside of border */
+       	x < - wBorderWidth((WindowPtr)pDraw) ||
+	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+	y < -wBorderWidth((WindowPtr)pDraw) ||
+	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+	    return(BadMatch);
+    }
+
+    drawables[0] = pDraw;
+    for(i = 1; i < PanoramiXNumScreens; i++)
+	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+    xgi.visual = wVisual(((WindowPtr)pDraw));
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+
+    if(format == ZPixmap) {
+	widthBytesLine = PixmapBytePad(w, pDraw->depth);
+	length = widthBytesLine * h;
+    } else {
+	widthBytesLine = PixmapBytePad(w, 1);
+	lenPer = widthBytesLine * h;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	length = lenPer * Ones(planemask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0) {/* nothing to do */ }
+    else if (format == ZPixmap) {
+	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+					shmdesc->addr + stuff->offset,
+					widthBytesLine, isRoot);
+    } else {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1) {
+	    if (planemask & plane) {
+		XineramaGetImageData(drawables, x, y, w, h, 
+				     format, plane, shmdesc->addr + length,
+				     widthBytesLine, isRoot);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+	register int n;
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(
+    register ClientPtr client)
+{
+    ScreenPtr pScreen = NULL;
+    PixmapPtr pMap = NULL;
+    DrawablePtr pDraw;
+    DepthPtr pDepth;
+    int i, j, result;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+    PanoramiXRes *newPix;
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+
+    if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+
+    newPix->type = XRT_PIXMAP;
+    newPix->u.pix.shared = TRUE;
+    newPix->info[0].id = stuff->pid;
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPix->info[j].id = FakeClientID(client->index);
+
+    result = (client->noClientException);
+
+    FOR_NSCREENS(j) {
+	pScreen = screenInfo.screens[j];
+
+	pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, 
+				stuff->width, stuff->height, stuff->depth,
+				shmdesc->addr + stuff->offset);
+
+	if (pMap) {
+#ifdef PIXPRIV
+            pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+            shmdesc->refcnt++;
+	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    pMap->drawable.id = newPix->info[j].id;
+	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
+		(*pScreen->DestroyPixmap)(pMap);
+		result = BadAlloc;
+		break;
+	    }
+	} else {
+	   result = BadAlloc;
+	   break;
+	}
+    }
+
+    if(result == BadAlloc) {
+	while(j--) {
+	    (*pScreen->DestroyPixmap)(pMap);
+	    FreeResource(newPix->info[j].id, RT_NONE);
+	}
+	xfree(newPix);
+    } else 
+	AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+    return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+    register ClientPtr client;
+{
+    register GCPtr pGC;
+    register DrawablePtr pDraw;
+    long length;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmPutImageReq);
+
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+    if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+	return BadValue;
+    if (stuff->format == XYBitmap)
+    {
+        if (stuff->depth != 1)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+	length *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
+    if (stuff->srcX > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcX;
+	return BadValue;
+    }
+    if (stuff->srcY > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcY;
+	return BadValue;
+    }
+    if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcWidth;
+	return BadValue;
+    }
+    if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcHeight;
+	return BadValue;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
+                "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
+                    stuff->srcY, stuff->totalWidth, stuff->totalHeight);
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
+    #endif
+
+    (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+                               pDraw, pGC, stuff->depth, stuff->format,
+                               stuff->totalWidth, stuff->totalHeight,
+                               stuff->srcX, stuff->srcY,
+                               stuff->srcWidth, stuff->srcHeight,
+                               stuff->dstX, stuff->dstY,
+                               shmdesc->addr + stuff->offset);
+
+    if (stuff->sendEvent)
+    {
+	xShmCompletionEvent ev;
+
+	ev.type = ShmCompletionCode;
+	ev.drawable = stuff->drawable;
+	ev.sequenceNumber = client->sequence;
+	ev.minorEvent = X_ShmPutImage;
+	ev.majorEvent = ShmReqCode;
+	ev.shmseg = stuff->shmseg;
+	ev.offset = stuff->offset;
+	WriteEventsToClient(client, 1, (xEvent *) &ev);
+    }
+
+    return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDraw;
+    long		lenPer = 0, length;
+    Mask		plane = 0;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int			n;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+    {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + stuff->x < 0 ||
+ 	 pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+         pDraw->y + stuff->y < 0 ||
+         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+         stuff->x + (int)stuff->width >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+         stuff->y + (int)stuff->height >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual(((WindowPtr)pDraw));
+    }
+    else
+    {
+	if (stuff->x < 0 ||
+	    stuff->x+(int)stuff->width > pDraw->width ||
+	    stuff->y < 0 ||
+	    stuff->y+(int)stuff->height > pDraw->height
+	    )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(stuff->format == ZPixmap)
+    {
+	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+    }
+    else 
+    {
+	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0)
+    {
+	/* nothing to do */
+    }
+    else if (stuff->format == ZPixmap)
+    {
+	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+				    stuff->width, stuff->height,
+				    stuff->format, stuff->planeMask,
+				    shmdesc->addr + stuff->offset);
+    }
+    else
+    {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1)
+	{
+	    if (stuff->planeMask & plane)
+	    {
+		(*pDraw->pScreen->GetImage)(pDraw,
+					    stuff->x, stuff->y,
+					    stuff->width, stuff->height,
+					    stuff->format, plane,
+					    shmdesc->addr + length);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+    ScreenPtr	pScreen;
+    int		width;
+    int		height;
+    int		depth;
+    char	*addr;
+{
+    register PixmapPtr pPixmap;
+
+    nxagentShmPixmapTrap = 1;
+
+    pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth);
+
+    if (!pPixmap)
+    {
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    #ifdef TEST
+    fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth);
+    #endif
+
+    if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) 
+    {
+      #ifdef WARNING
+      fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
+      #endif
+
+      (*pScreen->DestroyPixmap)(pPixmap);
+
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    nxagentShmPixmapTrap = 0;
+
+    return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    DepthPtr pDepth;
+    register int i;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+    pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+			    pDraw->pScreen, stuff->width,
+			    stuff->height, stuff->depth,
+			    shmdesc->addr + stuff->offset);
+    if (pMap)
+    {
+#ifdef PIXPRIV
+	pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+	shmdesc->refcnt++;
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	{
+	    return(client->noClientException);
+	}
+    }
+    return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+
+    if (stuff->data <= X_ShmCreatePixmap)
+    {
+      fprintf(stderr, "ProcShmDispatch: Request [%s] OPCODE#%d.\n",
+                  nxagentShmRequestLiteral[stuff->data], stuff->data);
+    }
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return ProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return ProcShmAttach(client);
+    case X_ShmDetach:
+	return ProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+        {
+           result = ProcPanoramiXShmPutImage(client);
+
+           nxagentShmTrap = 0;
+
+           return result;
+        }
+#endif
+
+        result = ProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmGetImage(client);
+#endif
+	return ProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmCreatePixmap(client);
+#endif
+	   return ProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static void
+SShmCompletionEvent(from, to)
+    xShmCompletionEvent *from, *to;
+{
+    to->type = from->type;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->drawable, to->drawable);
+    cpswaps(from->minorEvent, to->minorEvent);
+    to->majorEvent = from->majorEvent;
+    cpswapl(from->shmseg, to->shmseg);
+    cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+    register ClientPtr	client;
+{
+    register int n;
+    REQUEST(xShmQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmAttachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->shmid, n);
+    return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmDetachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    swapl(&stuff->shmseg, n);
+    return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmPutImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->gc, n);
+    swaps(&stuff->totalWidth, n);
+    swaps(&stuff->totalHeight, n);
+    swaps(&stuff->srcX, n);
+    swaps(&stuff->srcY, n);
+    swaps(&stuff->srcWidth, n);
+    swaps(&stuff->srcHeight, n);
+    swaps(&stuff->dstX, n);
+    swaps(&stuff->dstY, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmGetImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->planeMask, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmCreatePixmapReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return SProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return SProcShmAttach(client);
+    case X_ShmDetach:
+	return SProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+        result = SProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+	return SProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+	return SProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
new file mode 100644
index 000000000..3aecaf229
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -0,0 +1,1455 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */
+/************************************************************
+
+Copyright 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#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 "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "modinit.h"
+
+#include "Trap.h"
+#include "Agent.h"
+#include "Drawable.h"
+#include "Pixmaps.h"
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#ifdef TEST
+#include "Literals.h"
+#endif
+
+extern void fbGetImage(DrawablePtr pDrw, int x, int y, int w, int h,
+                           unsigned int format, unsigned long planeMask, char *d);
+
+extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+                            int x, int y, int w, int h, int leftPad, int format,
+                                char *pImage);
+
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+    pointer		/* value */,
+    XID			/* shmseg */
+    );
+static void ShmResetProc(
+    ExtensionEntry *	/* extEntry */
+    );
+static void SShmCompletionEvent(
+    xShmCompletionEvent * /* from */,
+    xShmCompletionEvent * /* to */
+    );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int  shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+    shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+    if (!shmdesc) \
+    { \
+	client->errorValue = shmseg; \
+	return BadShmSegCode; \
+    } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+    VERIFY_SHMSEG(shmseg, shmdesc, client); \
+    if ((offset & 3) || (offset > shmdesc->size)) \
+    { \
+	client->errorValue = offset; \
+	return BadValue; \
+    } \
+    if (needwrite && !shmdesc->writable) \
+	return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+    if ((offset + len) > shmdesc->size) \
+    { \
+	return BadAccess; \
+    } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+    badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+    void (*oldHandler)();
+    int shmid = -1;
+
+    /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+    oldHandler = signal(SIGSYS, SigSysHandler);
+
+    badSysCall = FALSE;
+    shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+
+    if (shmid != -1)
+    {
+        /* Successful allocation - clean up */
+	shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+    }
+    else
+    {
+        /* Allocation failed */
+        badSysCall = TRUE;
+    }
+    signal(SIGSYS, oldHandler);
+    return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+void
+ShmExtensionInit(INITARGS)
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+    if (!CheckForShmSyscall())
+    {
+	ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+	return;
+    }
+#endif
+
+    if (nxagentOption(SharedMemory) == False)
+    {
+      return;
+    }
+
+    sharedPixmaps = xFalse;
+    pixmapFormat = 0;
+    {
+      sharedPixmaps = nxagentOption(SharedPixmaps);
+      pixmapFormat = shmPixFormat[0];
+      for (i = 0; i < screenInfo.numScreens; i++)
+      {
+	if (!shmFuncs[i])
+        {
+            #ifdef TEST
+            fprintf(stderr, "ShmExtensionInit: Registering shmFuncs as miFuncs.\n");
+            #endif
+	    shmFuncs[i] = &miFuncs;
+        }
+	if (!shmFuncs[i]->CreatePixmap)
+	    sharedPixmaps = xFalse;
+	if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+	{
+	    sharedPixmaps = xFalse;
+	    pixmapFormat = 0;
+	}
+      }
+      if (!pixmapFormat)
+	pixmapFormat = ZPixmap;
+      if (sharedPixmaps)
+      {
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+	    screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+	}
+#ifdef PIXPRIV
+	shmPixmapPrivate = AllocatePixmapPrivateIndex();
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    if (!AllocatePixmapPrivate(screenInfo.screens[i],
+				       shmPixmapPrivate, 0))
+		return;
+	}
+#endif
+      }
+    }
+    ShmSegType = CreateNewResourceType(ShmDetachSegment);
+    if (ShmSegType &&
+	(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+				 ProcShmDispatch, SProcShmDispatch,
+				 ShmResetProc, StandardMinorOpcode)))
+    {
+	ShmReqCode = (unsigned char)extEntry->base;
+	ShmCompletionCode = extEntry->eventBase;
+	BadShmSegCode = extEntry->errorBase;
+	EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+    }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry	*extEntry;
+{
+    int i;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+	shmFuncs[i] = (ShmFuncsPtr)NULL;
+	shmPixFormat[i] = 0;
+    }
+}
+
+void
+ShmRegisterFuncs(
+    ScreenPtr pScreen,
+    ShmFuncsPtr funcs)
+{
+    shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(
+    ScreenPtr pScreen,
+    int format)
+{
+    shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	    pScreen = pPixmap->drawable.pScreen;
+    Bool	    ret;
+    if (pPixmap->refcnt == 1)
+    {
+	ShmDescPtr  shmdesc;
+#ifdef PIXPRIV
+	shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+	char	*base = (char *) pPixmap->devPrivate.ptr;
+	
+	if (base != (pointer) (pPixmap + 1))
+	{
+	    for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+	    {
+		if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+		    break;
+	    }
+	}
+	else
+	    shmdesc = 0;
+#endif
+	if (shmdesc)
+	    ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+    }
+    
+    pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+    ret = (*pScreen->DestroyPixmap) (pPixmap);
+    destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+    pScreen->DestroyPixmap = ShmDestroyPixmap;
+    return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+    ScreenPtr pScreen;
+{
+    #ifdef TEST
+    fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
+    #endif
+    shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+    register ClientPtr client;
+{
+    xShmQueryVersionReply rep;
+    register int n;
+
+    REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.sharedPixmaps = sharedPixmaps;
+    rep.pixmapFormat = pixmapFormat;
+    rep.majorVersion = SHM_MAJOR_VERSION;
+    rep.minorVersion = SHM_MINOR_VERSION;
+    rep.uid = geteuid();
+    rep.gid = getegid();
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+	swaps(&rep.uid, n);
+	swaps(&rep.gid, n);
+    }
+    WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+    int uid, gid;
+    mode_t mask;
+
+    if (LocalClientCred(client, &uid, &gid) != -1) {
+	
+	/* User id 0 always gets access */
+	if (uid == 0) {
+	    return 0;
+	}
+	/* Check the owner */
+	if (perm->uid == uid || perm->cuid == uid) {
+	    mask = S_IRUSR;
+	    if (!readonly) {
+		mask |= S_IWUSR;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+	/* Check the group */
+	if (perm->gid == gid || perm->cgid == gid) {
+	    mask = S_IRGRP;
+	    if (!readonly) {
+		mask |= S_IWGRP;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+    }
+    /* Otherwise, check everyone else */
+    mask = S_IROTH;
+    if (!readonly) {
+	mask |= S_IWOTH;
+    }
+    return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+    register ClientPtr client;
+{
+    struct shmid_ds buf;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmAttachReq);
+
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+    if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+    {
+	client->errorValue = stuff->readOnly;
+        return(BadValue);
+    }
+    for (shmdesc = Shmsegs;
+	 shmdesc && (shmdesc->shmid != stuff->shmid);
+	 shmdesc = shmdesc->next)
+	;
+    if (shmdesc)
+    {
+	if (!stuff->readOnly && !shmdesc->writable)
+	    return BadAccess;
+	shmdesc->refcnt++;
+    }
+    else
+    {
+	shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+	if (!shmdesc)
+	    return BadAlloc;
+	shmdesc->addr = shmat(stuff->shmid, 0,
+			      stuff->readOnly ? SHM_RDONLY : 0);
+	if ((shmdesc->addr == ((char *)-1)) ||
+	    shmctl(stuff->shmid, IPC_STAT, &buf))
+	{
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	/* The attach was performed with root privs. We must
+	 * do manual checking of access rights for the credentials 
+	 * of the client */
+
+	if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+	    shmdt(shmdesc->addr);
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	shmdesc->shmid = stuff->shmid;
+	shmdesc->refcnt = 1;
+	shmdesc->writable = !stuff->readOnly;
+	shmdesc->size = buf.shm_segsz;
+	shmdesc->next = Shmsegs;
+	Shmsegs = shmdesc;
+    }
+    if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+	return BadAlloc;
+    return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+    pointer value; /* must conform to DeleteType */
+    XID shmseg;
+{
+    ShmDescPtr shmdesc = (ShmDescPtr)value;
+    ShmDescPtr *prev;
+
+    if (--shmdesc->refcnt)
+	return TRUE;
+    shmdt(shmdesc->addr);
+    for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+	;
+    *prev = shmdesc->next;
+    xfree(shmdesc);
+    return Success;
+}
+
+static int
+ProcShmDetach(client)
+    register ClientPtr client;
+{
+    ShmDescPtr shmdesc;
+    REQUEST(xShmDetachReq);
+
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+    FreeResource(stuff->shmseg, RT_NONE);
+    return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    PixmapPtr pmap;
+    GCPtr putGC;
+
+    nxagentShmTrap = 0;
+    putGC = GetScratchGC(depth, dst->pScreen);
+    if (!putGC)
+    {
+        nxagentShmTrap = 1;
+	return;
+    }
+    pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+    if (!pmap)
+    {
+        nxagentShmTrap = 1;
+	FreeScratchGC(putGC);
+	return;
+    }
+    ValidateGC((DrawablePtr)pmap, putGC);
+    (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+			    (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+    FreeScratchGC(putGC);
+    if (format == XYBitmap)
+	(void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				     dx, dy, 1L);
+    else
+	(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				    dx, dy);
+    (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+    nxagentShmTrap = 1;
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    int length;
+    char *newdata;
+    extern int nxagentImageLength(int, int, int, int, int);
+
+    #ifdef TEST
+    fprintf(stderr, "fbShmPutImage: Called with drawable at [%p] GC at [%p] data at [%p].\n",
+                (void *) dst, (void *) pGC, (void *) data);
+    #endif
+
+    if ((format == ZPixmap) || (depth == 1))
+    {
+	PixmapPtr pPixmap;
+
+	pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+		BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+	if (!pPixmap)
+	    return;
+	if (format == XYBitmap)
+	    (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+					 sx, sy, sw, sh, dx, dy, 1L);
+	else
+	    (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+					sx, sy, sw, sh, dx, dy);
+
+        /*
+         * We updated the internal framebuffer,
+         * now we want to go on the real X.
+         */
+
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Realizing the PutImage with depth [%d] "
+                    " format [%d] w [%d] h [%d] sx [%d] sy [%d] sw [%d] "
+                        " sh [%d] dx [%d].\n", depth, format, w, h,
+                            sx, sy, sw, sh, dx);
+        #endif
+
+        length = nxagentImageLength(sw, sh, format, 0, depth);
+
+        if ((newdata = xalloc(length)) != NULL)
+        {
+          fbGetImage((DrawablePtr) pPixmap, sx, sy, sw, sh, format, AllPlanes, newdata);
+          (*pGC->ops->PutImage)(dst, pGC, depth, dx, dy, sw, sh, 0, format, newdata);
+
+          xfree(newdata);
+        }
+        else
+        {
+          #ifdef WARNING
+          fprintf(stderr, "fbShmPutImage: WARNING! Data allocation failed.\n");
+          #endif
+        }
+
+	FreeScratchPixmapHeader(pPixmap);
+    }
+    else
+    {
+        #ifdef TEST
+        fprintf(stderr, "fbShmPutImage: Calling miShmPutImage().\n");
+        #endif
+	miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+		      data);
+    }
+}
+
+
+#ifdef PANORAMIX
+static int 
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+    int			 j, result = 0, orig_x, orig_y;
+    PanoramiXRes	*draw, *gc;
+    Bool		 sendEvent, isRoot;
+
+    REQUEST(xShmPutImageReq);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    orig_x = stuff->dstX;
+    orig_y = stuff->dstY;
+    sendEvent = stuff->sendEvent;
+    stuff->sendEvent = 0;
+    FOR_NSCREENS(j) {
+	if(!j) stuff->sendEvent = sendEvent;
+	stuff->drawable = draw->info[j].id;
+	stuff->gc = gc->info[j].id;
+	if (isRoot) {
+	    stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+	    stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+	}
+	result = ProcShmPutImage(client);
+	if(result != client->noClientException) break;
+    }
+    return(result);
+}
+
+static int 
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+    PanoramiXRes	*draw;
+    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	pDraw;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int         	i, x, y, w, h, format;
+    Mask		plane = 0, planemask;
+    long		lenPer = 0, length, widthBytesLine;
+    Bool		isRoot;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+
+    if (draw->type == XRT_PIXMAP)
+	return ProcShmGetImage(client);
+
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+    x = stuff->x;
+    y = stuff->y;
+    w = stuff->width;
+    h = stuff->height;
+    format = stuff->format;
+    planemask = stuff->planeMask;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    if(isRoot) {
+      if( /* check for being onscreen */
+	x < 0 || x + w > PanoramiXPixWidth ||
+	y < 0 || y + h > PanoramiXPixHeight )
+	    return(BadMatch);
+    } else {
+      if( /* check for being onscreen */
+	panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+	panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+        panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+	panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+	 /* check for being inside of border */
+       	x < - wBorderWidth((WindowPtr)pDraw) ||
+	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+	y < -wBorderWidth((WindowPtr)pDraw) ||
+	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+	    return(BadMatch);
+    }
+
+    drawables[0] = pDraw;
+    for(i = 1; i < PanoramiXNumScreens; i++)
+	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+    xgi.visual = wVisual(((WindowPtr)pDraw));
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+
+    if(format == ZPixmap) {
+	widthBytesLine = PixmapBytePad(w, pDraw->depth);
+	length = widthBytesLine * h;
+    } else {
+	widthBytesLine = PixmapBytePad(w, 1);
+	lenPer = widthBytesLine * h;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	length = lenPer * Ones(planemask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0) {/* nothing to do */ }
+    else if (format == ZPixmap) {
+	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+					shmdesc->addr + stuff->offset,
+					widthBytesLine, isRoot);
+    } else {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1) {
+	    if (planemask & plane) {
+		XineramaGetImageData(drawables, x, y, w, h, 
+				     format, plane, shmdesc->addr + length,
+				     widthBytesLine, isRoot);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+	register int n;
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(
+    register ClientPtr client)
+{
+    ScreenPtr pScreen = NULL;
+    PixmapPtr pMap = NULL;
+    DrawablePtr pDraw;
+    DepthPtr pDepth;
+    int i, j, result;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+    PanoramiXRes *newPix;
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+
+    if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+
+    newPix->type = XRT_PIXMAP;
+    newPix->u.pix.shared = TRUE;
+    newPix->info[0].id = stuff->pid;
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPix->info[j].id = FakeClientID(client->index);
+
+    result = (client->noClientException);
+
+    FOR_NSCREENS(j) {
+	pScreen = screenInfo.screens[j];
+
+	pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, 
+				stuff->width, stuff->height, stuff->depth,
+				shmdesc->addr + stuff->offset);
+
+	if (pMap) {
+#ifdef PIXPRIV
+            pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+            shmdesc->refcnt++;
+	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    pMap->drawable.id = newPix->info[j].id;
+	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
+		(*pScreen->DestroyPixmap)(pMap);
+		result = BadAlloc;
+		break;
+	    }
+	} else {
+	   result = BadAlloc;
+	   break;
+	}
+    }
+
+    if(result == BadAlloc) {
+	while(j--) {
+	    (*pScreen->DestroyPixmap)(pMap);
+	    FreeResource(newPix->info[j].id, RT_NONE);
+	}
+	xfree(newPix);
+    } else 
+	AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+    return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+    register ClientPtr client;
+{
+    register GCPtr pGC;
+    register DrawablePtr pDraw;
+    long length;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmPutImageReq);
+
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+    if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+	return BadValue;
+    if (stuff->format == XYBitmap)
+    {
+        if (stuff->depth != 1)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+	length *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
+    if (stuff->srcX > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcX;
+	return BadValue;
+    }
+    if (stuff->srcY > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcY;
+	return BadValue;
+    }
+    if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcWidth;
+	return BadValue;
+    }
+    if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcHeight;
+	return BadValue;
+    }
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Format [%d] srcX [%d] srcY [%d], "
+                "totalWidth [%d] totalHeight [%d]\n", stuff->format, stuff->srcX,
+                    stuff->srcY, stuff->totalWidth, stuff->totalHeight);
+    #endif
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmPutImage: Calling (*shmFuncs[pDraw->pScreen->myNum]->PutImage)().\n");
+    #endif
+
+    (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+                               pDraw, pGC, stuff->depth, stuff->format,
+                               stuff->totalWidth, stuff->totalHeight,
+                               stuff->srcX, stuff->srcY,
+                               stuff->srcWidth, stuff->srcHeight,
+                               stuff->dstX, stuff->dstY,
+                               shmdesc->addr + stuff->offset);
+
+    if (stuff->sendEvent)
+    {
+	xShmCompletionEvent ev;
+
+	ev.type = ShmCompletionCode;
+	ev.drawable = stuff->drawable;
+	ev.sequenceNumber = client->sequence;
+	ev.minorEvent = X_ShmPutImage;
+	ev.majorEvent = ShmReqCode;
+	ev.shmseg = stuff->shmseg;
+	ev.offset = stuff->offset;
+	WriteEventsToClient(client, 1, (xEvent *) &ev);
+    }
+
+    return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDraw;
+    long		lenPer = 0, length;
+    Mask		plane = 0;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int			n;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+    {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + stuff->x < 0 ||
+ 	 pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+         pDraw->y + stuff->y < 0 ||
+         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+         stuff->x + (int)stuff->width >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+         stuff->y + (int)stuff->height >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual(((WindowPtr)pDraw));
+    }
+    else
+    {
+	if (stuff->x < 0 ||
+	    stuff->x+(int)stuff->width > pDraw->width ||
+	    stuff->y < 0 ||
+	    stuff->y+(int)stuff->height > pDraw->height
+	    )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(stuff->format == ZPixmap)
+    {
+	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+    }
+    else 
+    {
+	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0)
+    {
+	/* nothing to do */
+    }
+    else if (stuff->format == ZPixmap)
+    {
+	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+				    stuff->width, stuff->height,
+				    stuff->format, stuff->planeMask,
+				    shmdesc->addr + stuff->offset);
+    }
+    else
+    {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1)
+	{
+	    if (stuff->planeMask & plane)
+	    {
+		(*pDraw->pScreen->GetImage)(pDraw,
+					    stuff->x, stuff->y,
+					    stuff->width, stuff->height,
+					    stuff->format, plane,
+					    shmdesc->addr + length);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+    ScreenPtr	pScreen;
+    int		width;
+    int		height;
+    int		depth;
+    char	*addr;
+{
+    register PixmapPtr pPixmap;
+
+    nxagentShmPixmapTrap = 1;
+
+    pPixmap = (*pScreen->CreatePixmap)(pScreen, width, height, depth);
+
+    if (!pPixmap)
+    {
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    #ifdef TEST
+    fprintf(stderr,"fbShmCreatePixmap: Width [%d] Height [%d] Depth [%d]\n", width, height, depth);
+    #endif
+
+    if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) 
+    {
+      #ifdef WARNING
+      fprintf(stderr,"fbShmCreatePixmap: Return Null Pixmap.\n");
+      #endif
+
+      (*pScreen->DestroyPixmap)(pPixmap);
+
+      nxagentShmPixmapTrap = 0;
+
+      return NullPixmap;
+    }
+
+    nxagentShmPixmapTrap = 0;
+
+    return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    DepthPtr pDepth;
+    register int i;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+    pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+			    pDraw->pScreen, stuff->width,
+			    stuff->height, stuff->depth,
+			    shmdesc->addr + stuff->offset);
+    if (pMap)
+    {
+#ifdef PIXPRIV
+	pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+	shmdesc->refcnt++;
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	{
+	    return(client->noClientException);
+	}
+    }
+    return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "ProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+
+    if (stuff->data <= X_ShmCreatePixmap)
+    {
+      fprintf(stderr, "ProcShmDispatch: Request [%s] OPCODE#%d.\n",
+                  nxagentShmRequestLiteral[stuff->data], stuff->data);
+    }
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return ProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return ProcShmAttach(client);
+    case X_ShmDetach:
+	return ProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Going to execute ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+        {
+           result = ProcPanoramiXShmPutImage(client);
+
+           nxagentShmTrap = 0;
+
+           return result;
+        }
+#endif
+
+        result = ProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "ProcShmDispatch: Returning from ProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmGetImage(client);
+#endif
+	return ProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmCreatePixmap(client);
+#endif
+	   return ProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static void
+SShmCompletionEvent(from, to)
+    xShmCompletionEvent *from, *to;
+{
+    to->type = from->type;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->drawable, to->drawable);
+    cpswaps(from->minorEvent, to->minorEvent);
+    to->majorEvent = from->majorEvent;
+    cpswapl(from->shmseg, to->shmseg);
+    cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+    register ClientPtr	client;
+{
+    register int n;
+    REQUEST(xShmQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmAttachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->shmid, n);
+    return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmDetachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    swapl(&stuff->shmseg, n);
+    return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmPutImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->gc, n);
+    swaps(&stuff->totalWidth, n);
+    swaps(&stuff->totalHeight, n);
+    swaps(&stuff->srcX, n);
+    swaps(&stuff->srcY, n);
+    swaps(&stuff->srcWidth, n);
+    swaps(&stuff->srcHeight, n);
+    swaps(&stuff->dstX, n);
+    swaps(&stuff->dstY, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmGetImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->planeMask, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmCreatePixmapReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+
+    #ifdef TEST
+    fprintf(stderr, "SProcShmDispatch: Going to execute operation [%d] for client [%d].\n", 
+                stuff -> data, client -> index);
+    #endif
+
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return SProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return SProcShmAttach(client);
+    case X_ShmDetach:
+	return SProcShmDetach(client);
+    case X_ShmPutImage:
+      {
+        int result;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Going to execute SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        nxagentShmTrap = 1;
+
+        result = SProcShmPutImage(client);
+
+        nxagentShmTrap = 0;
+
+        #ifdef TEST
+        fprintf(stderr, "SProcShmDispatch: Returning from SProcShmPutImage() for client [%d].\n", 
+                    client -> index);
+        #endif
+
+        return result;
+      }
+    case X_ShmGetImage:
+	return SProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+	return SProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
new file mode 100644
index 000000000..806008c60
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
@@ -0,0 +1,1267 @@
+/* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.41 2003/12/17 23:28:56 alanh Exp $ */
+/************************************************************
+
+Copyright 1989, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#else
+#include <ipc.h>
+#include <shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#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 "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#include <X11/Xfuncproto.h>
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "modinit.h"
+
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+    pointer		/* value */,
+    XID			/* shmseg */
+    );
+static void ShmResetProc(
+    ExtensionEntry *	/* extEntry */
+    );
+static void SShmCompletionEvent(
+    xShmCompletionEvent * /* from */,
+    xShmCompletionEvent * /* to */
+    );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
+#ifdef PIXPRIV
+static int  shmPixmapPrivate;
+#endif
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+    shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+    if (!shmdesc) \
+    { \
+	client->errorValue = shmseg; \
+	return BadShmSegCode; \
+    } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+    VERIFY_SHMSEG(shmseg, shmdesc, client); \
+    if ((offset & 3) || (offset > shmdesc->size)) \
+    { \
+	client->errorValue = offset; \
+	return BadValue; \
+    } \
+    if (needwrite && !shmdesc->writable) \
+	return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+    if ((offset + len) > shmdesc->size) \
+    { \
+	return BadAccess; \
+    } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(signo)
+int signo;
+{
+    badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall()
+{
+    void (*oldHandler)();
+    int shmid = -1;
+
+    /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+    oldHandler = signal(SIGSYS, SigSysHandler);
+
+    badSysCall = FALSE;
+    shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+
+    if (shmid != -1)
+    {
+        /* Successful allocation - clean up */
+	shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
+    }
+    else
+    {
+        /* Allocation failed */
+        badSysCall = TRUE;
+    }
+    signal(SIGSYS, oldHandler);
+    return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+void
+ShmExtensionInit(INITARGS)
+{
+    ExtensionEntry *extEntry;
+    int i;
+
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+    if (!CheckForShmSyscall())
+    {
+	ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+	return;
+    }
+#endif
+
+    sharedPixmaps = xFalse;
+    pixmapFormat = 0;
+    {
+      sharedPixmaps = xTrue;
+      pixmapFormat = shmPixFormat[0];
+      for (i = 0; i < screenInfo.numScreens; i++)
+      {
+	if (!shmFuncs[i])
+	    shmFuncs[i] = &miFuncs;
+	if (!shmFuncs[i]->CreatePixmap)
+	    sharedPixmaps = xFalse;
+	if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+	{
+	    sharedPixmaps = xFalse;
+	    pixmapFormat = 0;
+	}
+      }
+      if (!pixmapFormat)
+	pixmapFormat = ZPixmap;
+      if (sharedPixmaps)
+      {
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    destroyPixmap[i] = screenInfo.screens[i]->DestroyPixmap;
+	    screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+	}
+#ifdef PIXPRIV
+	shmPixmapPrivate = AllocatePixmapPrivateIndex();
+	for (i = 0; i < screenInfo.numScreens; i++)
+	{
+	    if (!AllocatePixmapPrivate(screenInfo.screens[i],
+				       shmPixmapPrivate, 0))
+		return;
+	}
+#endif
+      }
+    }
+    ShmSegType = CreateNewResourceType(ShmDetachSegment);
+    if (ShmSegType &&
+	(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+				 ProcShmDispatch, SProcShmDispatch,
+				 ShmResetProc, StandardMinorOpcode)))
+    {
+	ShmReqCode = (unsigned char)extEntry->base;
+	ShmCompletionCode = extEntry->eventBase;
+	BadShmSegCode = extEntry->errorBase;
+	EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+    }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry	*extEntry;
+{
+    int i;
+
+    for (i = 0; i < MAXSCREENS; i++)
+    {
+	shmFuncs[i] = (ShmFuncsPtr)NULL;
+	shmPixFormat[i] = 0;
+    }
+}
+
+void
+ShmRegisterFuncs(
+    ScreenPtr pScreen,
+    ShmFuncsPtr funcs)
+{
+    shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(
+    ScreenPtr pScreen,
+    int format)
+{
+    shmPixFormat[pScreen->myNum] = format;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+    ScreenPtr	    pScreen = pPixmap->drawable.pScreen;
+    Bool	    ret;
+    if (pPixmap->refcnt == 1)
+    {
+	ShmDescPtr  shmdesc;
+#ifdef PIXPRIV
+	shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
+#else
+	char	*base = (char *) pPixmap->devPrivate.ptr;
+	
+	if (base != (pointer) (pPixmap + 1))
+	{
+	    for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
+	    {
+		if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
+		    break;
+	    }
+	}
+	else
+	    shmdesc = 0;
+#endif
+	if (shmdesc)
+	    ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+    }
+    
+    pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
+    ret = (*pScreen->DestroyPixmap) (pPixmap);
+    destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
+    pScreen->DestroyPixmap = ShmDestroyPixmap;
+    return ret;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+    ScreenPtr pScreen;
+{
+    shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+    register ClientPtr client;
+{
+    xShmQueryVersionReply rep;
+    register int n;
+
+    REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.sharedPixmaps = sharedPixmaps;
+    rep.pixmapFormat = pixmapFormat;
+    rep.majorVersion = SHM_MAJOR_VERSION;
+    rep.minorVersion = SHM_MINOR_VERSION;
+    rep.uid = geteuid();
+    rep.gid = getegid();
+    if (client->swapped) {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+	swaps(&rep.uid, n);
+	swaps(&rep.gid, n);
+    }
+    WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+    return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
+{
+    int uid, gid;
+    mode_t mask;
+
+    if (LocalClientCred(client, &uid, &gid) != -1) {
+	
+	/* User id 0 always gets access */
+	if (uid == 0) {
+	    return 0;
+	}
+	/* Check the owner */
+	if (perm->uid == uid || perm->cuid == uid) {
+	    mask = S_IRUSR;
+	    if (!readonly) {
+		mask |= S_IWUSR;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+	/* Check the group */
+	if (perm->gid == gid || perm->cgid == gid) {
+	    mask = S_IRGRP;
+	    if (!readonly) {
+		mask |= S_IWGRP;
+	    }
+	    return (perm->mode & mask) == mask ? 0 : -1;
+	}
+    }
+    /* Otherwise, check everyone else */
+    mask = S_IROTH;
+    if (!readonly) {
+	mask |= S_IWOTH;
+    }
+    return (perm->mode & mask) == mask ? 0 : -1;
+}
+
+static int
+ProcShmAttach(client)
+    register ClientPtr client;
+{
+    struct shmid_ds buf;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmAttachReq);
+
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+    if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+    {
+	client->errorValue = stuff->readOnly;
+        return(BadValue);
+    }
+    for (shmdesc = Shmsegs;
+	 shmdesc && (shmdesc->shmid != stuff->shmid);
+	 shmdesc = shmdesc->next)
+	;
+    if (shmdesc)
+    {
+	if (!stuff->readOnly && !shmdesc->writable)
+	    return BadAccess;
+	shmdesc->refcnt++;
+    }
+    else
+    {
+	shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+	if (!shmdesc)
+	    return BadAlloc;
+	shmdesc->addr = shmat(stuff->shmid, 0,
+			      stuff->readOnly ? SHM_RDONLY : 0);
+	if ((shmdesc->addr == ((char *)-1)) ||
+	    shmctl(stuff->shmid, IPC_STAT, &buf))
+	{
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	/* The attach was performed with root privs. We must
+	 * do manual checking of access rights for the credentials 
+	 * of the client */
+
+	if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
+	    shmdt(shmdesc->addr);
+	    xfree(shmdesc);
+	    return BadAccess;
+	}
+
+	shmdesc->shmid = stuff->shmid;
+	shmdesc->refcnt = 1;
+	shmdesc->writable = !stuff->readOnly;
+	shmdesc->size = buf.shm_segsz;
+	shmdesc->next = Shmsegs;
+	Shmsegs = shmdesc;
+    }
+    if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+	return BadAlloc;
+    return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+    pointer value; /* must conform to DeleteType */
+    XID shmseg;
+{
+    ShmDescPtr shmdesc = (ShmDescPtr)value;
+    ShmDescPtr *prev;
+
+    if (--shmdesc->refcnt)
+	return TRUE;
+    shmdt(shmdesc->addr);
+    for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+	;
+    *prev = shmdesc->next;
+    xfree(shmdesc);
+    return Success;
+}
+
+static int
+ProcShmDetach(client)
+    register ClientPtr client;
+{
+    ShmDescPtr shmdesc;
+    REQUEST(xShmDetachReq);
+
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+    FreeResource(stuff->shmseg, RT_NONE);
+    return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    PixmapPtr pmap;
+    GCPtr putGC;
+
+    putGC = GetScratchGC(depth, dst->pScreen);
+    if (!putGC)
+	return;
+    pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+    if (!pmap)
+    {
+	FreeScratchGC(putGC);
+	return;
+    }
+    ValidateGC((DrawablePtr)pmap, putGC);
+    (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+			    (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+    FreeScratchGC(putGC);
+    if (format == XYBitmap)
+	(void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				     dx, dy, 1L);
+    else
+	(void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+				    dx, dy);
+    (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+    DrawablePtr dst;
+    GCPtr	pGC;
+    int		depth, w, h, sx, sy, sw, sh, dx, dy;
+    unsigned int format;
+    char 	*data;
+{
+    if ((format == ZPixmap) || (depth == 1))
+    {
+	PixmapPtr pPixmap;
+
+	pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+		BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+	if (!pPixmap)
+	    return;
+	if (format == XYBitmap)
+	    (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+					 sx, sy, sw, sh, dx, dy, 1L);
+	else
+	    (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+					sx, sy, sw, sh, dx, dy);
+	FreeScratchPixmapHeader(pPixmap);
+    }
+    else
+	miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+		      data);
+}
+
+
+#ifdef PANORAMIX
+static int 
+ProcPanoramiXShmPutImage(register ClientPtr client)
+{
+    int			 j, result = 0, orig_x, orig_y;
+    PanoramiXRes	*draw, *gc;
+    Bool		 sendEvent, isRoot;
+
+    REQUEST(xShmPutImageReq);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    orig_x = stuff->dstX;
+    orig_y = stuff->dstY;
+    sendEvent = stuff->sendEvent;
+    stuff->sendEvent = 0;
+    FOR_NSCREENS(j) {
+	if(!j) stuff->sendEvent = sendEvent;
+	stuff->drawable = draw->info[j].id;
+	stuff->gc = gc->info[j].id;
+	if (isRoot) {
+	    stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+	    stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+	}
+	result = ProcShmPutImage(client);
+	if(result != client->noClientException) break;
+    }
+    return(result);
+}
+
+static int 
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+    PanoramiXRes	*draw;
+    DrawablePtr 	drawables[MAXSCREENS];
+    DrawablePtr 	pDraw;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int         	i, x, y, w, h, format;
+    Mask		plane = 0, planemask;
+    long		lenPer = 0, length, widthBytesLine;
+    Bool		isRoot;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+		client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+	return BadDrawable;
+
+    if (draw->type == XRT_PIXMAP)
+	return ProcShmGetImage(client);
+
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+    x = stuff->x;
+    y = stuff->y;
+    w = stuff->width;
+    h = stuff->height;
+    format = stuff->format;
+    planemask = stuff->planeMask;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    if(isRoot) {
+      if( /* check for being onscreen */
+	x < 0 || x + w > PanoramiXPixWidth ||
+	y < 0 || y + h > PanoramiXPixHeight )
+	    return(BadMatch);
+    } else {
+      if( /* check for being onscreen */
+	panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+	panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+        panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+	panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+	 /* check for being inside of border */
+       	x < - wBorderWidth((WindowPtr)pDraw) ||
+	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+	y < -wBorderWidth((WindowPtr)pDraw) ||
+	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+	    return(BadMatch);
+    }
+
+    drawables[0] = pDraw;
+    for(i = 1; i < PanoramiXNumScreens; i++)
+	VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
+
+    xgi.visual = wVisual(((WindowPtr)pDraw));
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+
+    if(format == ZPixmap) {
+	widthBytesLine = PixmapBytePad(w, pDraw->depth);
+	length = widthBytesLine * h;
+    } else {
+	widthBytesLine = PixmapBytePad(w, 1);
+	lenPer = widthBytesLine * h;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	length = lenPer * Ones(planemask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0) {/* nothing to do */ }
+    else if (format == ZPixmap) {
+	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+					shmdesc->addr + stuff->offset,
+					widthBytesLine, isRoot);
+    } else {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1) {
+	    if (planemask & plane) {
+		XineramaGetImageData(drawables, x, y, w, h, 
+				     format, plane, shmdesc->addr + length,
+				     widthBytesLine, isRoot);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+	register int n;
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(
+    register ClientPtr client)
+{
+    ScreenPtr pScreen = NULL;
+    PixmapPtr pMap = NULL;
+    DrawablePtr pDraw;
+    DepthPtr pDepth;
+    int i, j, result;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+    PanoramiXRes *newPix;
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+
+    if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
+	return BadAlloc;
+
+    newPix->type = XRT_PIXMAP;
+    newPix->u.pix.shared = TRUE;
+    newPix->info[0].id = stuff->pid;
+    for(j = 1; j < PanoramiXNumScreens; j++)
+	newPix->info[j].id = FakeClientID(client->index);
+
+    result = (client->noClientException);
+
+    FOR_NSCREENS(j) {
+	pScreen = screenInfo.screens[j];
+
+	pMap = (*shmFuncs[j]->CreatePixmap)(pScreen, 
+				stuff->width, stuff->height, stuff->depth,
+				shmdesc->addr + stuff->offset);
+
+	if (pMap) {
+#ifdef PIXPRIV
+            pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+            shmdesc->refcnt++;
+	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    pMap->drawable.id = newPix->info[j].id;
+	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
+		(*pScreen->DestroyPixmap)(pMap);
+		result = BadAlloc;
+		break;
+	    }
+	} else {
+	   result = BadAlloc;
+	   break;
+	}
+    }
+
+    if(result == BadAlloc) {
+	while(j--) {
+	    (*pScreen->DestroyPixmap)(pMap);
+	    FreeResource(newPix->info[j].id, RT_NONE);
+	}
+	xfree(newPix);
+    } else 
+	AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+    return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(client)
+    register ClientPtr client;
+{
+    register GCPtr pGC;
+    register DrawablePtr pDraw;
+    long length;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmPutImageReq);
+
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+    if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+	return BadValue;
+    if (stuff->format == XYBitmap)
+    {
+        if (stuff->depth != 1)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+    }
+    else if (stuff->format == XYPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, 1);
+	length *= stuff->depth;
+    }
+    else if (stuff->format == ZPixmap)
+    {
+        if (pDraw->depth != stuff->depth)
+            return BadMatch;
+        length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+    }
+    else
+    {
+	client->errorValue = stuff->format;
+        return BadValue;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
+    if (stuff->srcX > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcX;
+	return BadValue;
+    }
+    if (stuff->srcY > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcY;
+	return BadValue;
+    }
+    if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+    {
+	client->errorValue = stuff->srcWidth;
+	return BadValue;
+    }
+    if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+    {
+	client->errorValue = stuff->srcHeight;
+	return BadValue;
+    }
+
+    if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
+	 ((stuff->format != ZPixmap) &&
+	  (stuff->srcX < screenInfo.bitmapScanlinePad) &&
+	  ((stuff->format == XYBitmap) ||
+	   ((stuff->srcY == 0) &&
+	    (stuff->srcHeight == stuff->totalHeight))))) &&
+	((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
+	(*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
+			       stuff->dstX, stuff->dstY,
+			       stuff->totalWidth, stuff->srcHeight, 
+			       stuff->srcX, stuff->format, 
+			       shmdesc->addr + stuff->offset +
+			       (stuff->srcY * length));
+    else
+	(*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+			       pDraw, pGC, stuff->depth, stuff->format,
+			       stuff->totalWidth, stuff->totalHeight,
+			       stuff->srcX, stuff->srcY,
+			       stuff->srcWidth, stuff->srcHeight,
+			       stuff->dstX, stuff->dstY,
+                               shmdesc->addr + stuff->offset);
+
+    if (stuff->sendEvent)
+    {
+	xShmCompletionEvent ev;
+
+	ev.type = ShmCompletionCode;
+	ev.drawable = stuff->drawable;
+	ev.sequenceNumber = client->sequence;
+	ev.minorEvent = X_ShmPutImage;
+	ev.majorEvent = ShmReqCode;
+	ev.shmseg = stuff->shmseg;
+	ev.offset = stuff->offset;
+	WriteEventsToClient(client, 1, (xEvent *) &ev);
+    }
+
+    return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+    register ClientPtr client;
+{
+    register DrawablePtr pDraw;
+    long		lenPer = 0, length;
+    Mask		plane = 0;
+    xShmGetImageReply	xgi;
+    ShmDescPtr		shmdesc;
+    int			n;
+
+    REQUEST(xShmGetImageReq);
+
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+    {
+	client->errorValue = stuff->format;
+        return(BadValue);
+    }
+    VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (pDraw->type == DRAWABLE_WINDOW)
+    {
+      if( /* check for being viewable */
+	 !((WindowPtr) pDraw)->realized ||
+	  /* check for being on screen */
+         pDraw->x + stuff->x < 0 ||
+ 	 pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+         pDraw->y + stuff->y < 0 ||
+         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+          /* check for being inside of border */
+         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+         stuff->x + (int)stuff->width >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+         stuff->y + (int)stuff->height >
+		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+        )
+	    return(BadMatch);
+	xgi.visual = wVisual(((WindowPtr)pDraw));
+    }
+    else
+    {
+	if (stuff->x < 0 ||
+	    stuff->x+(int)stuff->width > pDraw->width ||
+	    stuff->y < 0 ||
+	    stuff->y+(int)stuff->height > pDraw->height
+	    )
+	    return(BadMatch);
+	xgi.visual = None;
+    }
+    xgi.type = X_Reply;
+    xgi.length = 0;
+    xgi.sequenceNumber = client->sequence;
+    xgi.depth = pDraw->depth;
+    if(stuff->format == ZPixmap)
+    {
+	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+    }
+    else 
+    {
+	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+	plane = ((Mask)1) << (pDraw->depth - 1);
+	/* only planes asked for */
+	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+    xgi.size = length;
+
+    if (length == 0)
+    {
+	/* nothing to do */
+    }
+    else if (stuff->format == ZPixmap)
+    {
+	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+				    stuff->width, stuff->height,
+				    stuff->format, stuff->planeMask,
+				    shmdesc->addr + stuff->offset);
+    }
+    else
+    {
+
+	length = stuff->offset;
+        for (; plane; plane >>= 1)
+	{
+	    if (stuff->planeMask & plane)
+	    {
+		(*pDraw->pScreen->GetImage)(pDraw,
+					    stuff->x, stuff->y,
+					    stuff->width, stuff->height,
+					    stuff->format, plane,
+					    shmdesc->addr + length);
+		length += lenPer;
+	    }
+	}
+    }
+    
+    if (client->swapped) {
+    	swaps(&xgi.sequenceNumber, n);
+    	swapl(&xgi.length, n);
+	swapl(&xgi.visual, n);
+	swapl(&xgi.size, n);
+    }
+    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+    return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+    ScreenPtr	pScreen;
+    int		width;
+    int		height;
+    int		depth;
+    char	*addr;
+{
+    register PixmapPtr pPixmap;
+
+    pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
+    if (!pPixmap)
+	return NullPixmap;
+
+    if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+	    BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
+	(*pScreen->DestroyPixmap)(pPixmap);
+	return NullPixmap;
+    }
+    return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+    register ClientPtr client;
+{
+    PixmapPtr pMap;
+    register DrawablePtr pDraw;
+    DepthPtr pDepth;
+    register int i;
+    ShmDescPtr shmdesc;
+    REQUEST(xShmCreatePixmapReq);
+
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    client->errorValue = stuff->pid;
+    if (!sharedPixmaps)
+	return BadImplementation;
+    LEGAL_NEW_RESOURCE(stuff->pid, client);
+    VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+    if (!stuff->width || !stuff->height)
+    {
+	client->errorValue = 0;
+        return BadValue;
+    }
+    if (stuff->depth != 1)
+    {
+        pDepth = pDraw->pScreen->allowedDepths;
+        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+	   if (pDepth->depth == stuff->depth)
+               goto CreatePmap;
+	client->errorValue = stuff->depth;
+        return BadValue;
+    }
+CreatePmap:
+    VERIFY_SHMSIZE(shmdesc, stuff->offset,
+		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+		   client);
+    pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+			    pDraw->pScreen, stuff->width,
+			    stuff->height, stuff->depth,
+			    shmdesc->addr + stuff->offset);
+    if (pMap)
+    {
+#ifdef PIXPRIV
+	pMap->devPrivates[shmPixmapPrivate].ptr = (pointer) shmdesc;
+#endif
+	shmdesc->refcnt++;
+	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	pMap->drawable.id = stuff->pid;
+	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+	{
+	    return(client->noClientException);
+	}
+    }
+    return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return ProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return ProcShmAttach(client);
+    case X_ShmDetach:
+	return ProcShmDetach(client);
+    case X_ShmPutImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmPutImage(client);
+#endif
+	return ProcShmPutImage(client);
+    case X_ShmGetImage:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmGetImage(client);
+#endif
+	return ProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+        if ( !noPanoramiXExtension )
+	   return ProcPanoramiXShmCreatePixmap(client);
+#endif
+	   return ProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
+
+static void
+SShmCompletionEvent(from, to)
+    xShmCompletionEvent *from, *to;
+{
+    to->type = from->type;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->drawable, to->drawable);
+    cpswaps(from->minorEvent, to->minorEvent);
+    to->majorEvent = from->majorEvent;
+    cpswapl(from->shmseg, to->shmseg);
+    cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+    register ClientPtr	client;
+{
+    register int n;
+    REQUEST(xShmQueryVersionReq);
+
+    swaps(&stuff->length, n);
+    return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmAttachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmAttachReq);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->shmid, n);
+    return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmDetachReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmDetachReq);
+    swapl(&stuff->shmseg, n);
+    return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmPutImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmPutImageReq);
+    swapl(&stuff->drawable, n);
+    swapl(&stuff->gc, n);
+    swaps(&stuff->totalWidth, n);
+    swaps(&stuff->totalHeight, n);
+    swaps(&stuff->srcX, n);
+    swaps(&stuff->srcY, n);
+    swaps(&stuff->srcWidth, n);
+    swaps(&stuff->srcHeight, n);
+    swaps(&stuff->dstX, n);
+    swaps(&stuff->dstY, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmGetImageReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmGetImageReq);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->x, n);
+    swaps(&stuff->y, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->planeMask, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+    ClientPtr client;
+{
+    register int n;
+    REQUEST(xShmCreatePixmapReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+    swapl(&stuff->pid, n);
+    swapl(&stuff->drawable, n);
+    swaps(&stuff->width, n);
+    swaps(&stuff->height, n);
+    swapl(&stuff->shmseg, n);
+    swapl(&stuff->offset, n);
+    return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (client)
+    register ClientPtr	client;
+{
+    REQUEST(xReq);
+    switch (stuff->data)
+    {
+    case X_ShmQueryVersion:
+	return SProcShmQueryVersion(client);
+    case X_ShmAttach:
+	return SProcShmAttach(client);
+    case X_ShmDetach:
+	return SProcShmDetach(client);
+    case X_ShmPutImage:
+	return SProcShmPutImage(client);
+    case X_ShmGetImage:
+	return SProcShmGetImage(client);
+    case X_ShmCreatePixmap:
+	return SProcShmCreatePixmap(client);
+    default:
+	return BadRequest;
+    }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
new file mode 100644
index 000000000..7ba468ac0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -0,0 +1,4174 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.12 2005/07/03 08:53:38 daniels Exp $ */
+/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+/*
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+			All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.36 2003/11/14 23:52:50 torrey Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "selection.h"
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#include "Screen.h"
+#include "Options.h"
+#include "Atoms.h"
+#include "Clipboard.h"
+#include "Splash.h"
+#include "Rootless.h"
+#include "Composite.h"
+#include "Drawable.h"
+#include "Colormap.h"
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
+/******
+ * Window stuff for server 
+ *
+ *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+			      CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+      (!( ((b1)->x2 <= (b2)->x1)  || \
+	( ((b1)->x1 >= (b2)->x2)) || \
+	( ((b1)->y2 <= (b2)->y1)) || \
+	( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+WindowPtr nxagentRootTileWindow;
+
+/*
+ * This block used the DEBUG symbol.
+ */
+
+#ifdef WINDOW_TREE_DEBUG
+/******
+ * PrintWindowTree
+ *    For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+    WindowPtr p2;
+    int i;
+
+    while (p1)
+    {
+	p2 = p1->firstChild;
+	for (i=0; i<indent; i++) ErrorF( " ");
+	ErrorF( "%x\n", p1->drawable.id);
+	miPrintRegion(&p1->clipList);
+	PrintChildren(p2, indent+4);
+	p1 = p1->nextSib;
+    }
+}
+
+PrintWindowTree()
+{
+    int i;
+    WindowPtr pWin, p1;
+
+    for (i=0; i<screenInfo.numScreens; i++)
+    {
+	ErrorF( "WINDOW %d\n", i);
+	pWin = WindowTable[i];
+	miPrintRegion(&pWin->clipList);
+	p1 = pWin->firstChild;
+	PrintChildren(p1, 4);
+    }
+}
+#endif
+
+int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+{
+    register int result;
+    register WindowPtr pChild;
+
+    if (!(pChild = pWin))
+       return(WT_NOMATCH);
+    while (1)
+    {
+	result = (* func)(pChild, data);
+	if (result == WT_STOPWALKING)
+	    return(WT_STOPWALKING);
+	if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+    return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
+ *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
+ *   exit WalkTree.  Does depth-first traverse.
+ *****/
+
+int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+{
+    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int	defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool	disableBackingStore = FALSE;
+Bool	enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool	disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+    pWin->prevSib = NullWindow;
+    pWin->firstChild = NullWindow;
+    pWin->lastChild = NullWindow;
+
+    pWin->valdata = (ValidatePtr)NULL;
+    pWin->optional = (WindowOptPtr)NULL;
+    pWin->cursorIsNone = TRUE;
+
+    pWin->backingStore = NotUseful;
+    pWin->DIXsaveUnder = FALSE;
+    pWin->backStorage = (pointer) NULL;
+
+    pWin->mapped = FALSE;	    /* off */
+    pWin->realized = FALSE;	/* off */
+    pWin->viewable = FALSE;
+    pWin->visibility = VisibilityNotViewable;
+    pWin->overrideRedirect = FALSE;
+    pWin->saveUnder = FALSE;
+
+    pWin->bitGravity = ForgetGravity;
+    pWin->winGravity = NorthWestGravity;
+
+    pWin->eventMask = 0;
+    pWin->deliverableEvents = 0;
+    pWin->dontPropagate = 0;
+    pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+    pWin->srcBuffer = DBE_FRONT_BUFFER;
+    pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+    pWin->redirectDraw = 0;
+#endif
+}
+
+#ifdef NXAGENT_SERVER
+
+void nxagentClearSplash(WindowPtr pW)
+{
+    int w, h;
+    ScreenPtr pScreen;
+
+    w = pW->drawable.width;
+    h = pW->drawable.height;
+
+    pScreen = pW->drawable.pScreen;
+
+    if (pW->backgroundState == BackgroundPixmap)
+    {
+      (*pScreen->DestroyPixmap)(pW->background.pixmap);
+    }
+
+    pW->backgroundState = BackgroundPixel;
+    pW->background.pixel = nxagentLogoBlack;
+
+    (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
+
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+    WindowPtr pWin;
+#endif
+{
+    nxagentRootTileWindow = pWin;
+}
+
+#else /* NXAGENT_SERVER */
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    GCPtr pGC;
+    unsigned char back[128];
+    int len = BitmapBytePad(sizeof(long));
+    register unsigned char *from, *to;
+    register int i, j;
+
+    pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+						    pScreen->rootDepth);
+
+    pWin->backgroundState = BackgroundPixmap;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pWin->background.pixmap || !pGC)
+	FatalError("could not create root tile");
+
+    {
+	CARD32 attributes[2];
+
+	attributes[0] = pScreen->whitePixel;
+	attributes[1] = pScreen->blackPixel;
+
+	(void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+    }
+
+   ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+   from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+   to = back;
+
+   for (i = 4; i > 0; i--, from++)
+	for (j = len; j > 0; j--)
+	    *to++ = *from;
+
+   if (blackRoot)
+       bzero(back, sizeof(back));
+
+   (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+		    0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+   FreeScratchGC(pGC);
+
+}
+
+#endif /* NXAGENT_SERVER */
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+    WindowPtr pWin;
+    register char *ptr;
+    register DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+    if (pWin)
+    {
+	ppriv = (DevUnion *)(pWin + 1);
+	pWin->devPrivates = ppriv;
+	sizes = pScreen->WindowPrivateSizes;
+	ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+	for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+	{
+	    if ( (size = *sizes) )
+	    {
+		ppriv->ptr = (pointer)ptr;
+		ptr += size;
+	    }
+	    else
+		ppriv->ptr = (pointer)NULL;
+	}
+    }
+    return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ *    Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+    WindowPtr	pWin;
+    BoxRec	box;
+    PixmapFormatRec *format;
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+	return FALSE;
+
+    savedScreenInfo[pScreen->myNum].pWindow = NULL;
+    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+    screenIsSaved = SCREEN_SAVER_OFF;
+
+    WindowTable[pScreen->myNum] = pWin;
+
+    pWin->drawable.pScreen = pScreen;
+    pWin->drawable.type = DRAWABLE_WINDOW;
+
+    pWin->drawable.depth = pScreen->rootDepth;
+    for (format = screenInfo.formats;
+	 format->depth != pScreen->rootDepth;
+	 format++)
+	;
+    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->parent = NullWindow;
+    SetWindowToDefaults(pWin);
+
+    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+    if (!pWin->optional)
+        return FALSE;
+
+    pWin->optional->dontPropagateMask = 0;
+    pWin->optional->otherEventMasks = 0;
+    pWin->optional->otherClients = NULL;
+    pWin->optional->passiveGrabs = NULL;
+    pWin->optional->userProps = NULL;
+    pWin->optional->backingBitPlanes = ~0L;
+    pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+    pWin->optional->boundingShape = NULL;
+    pWin->optional->clipShape = NULL;
+    pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+    pWin->optional->inputMasks = NULL;
+#endif
+    pWin->optional->colormap = pScreen->defColormap;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->nextSib = NullWindow;
+
+    pWin->drawable.id = FakeClientID(0);
+
+    pWin->origin.x = pWin->origin.y = 0;
+    pWin->drawable.height = pScreen->height;
+    pWin->drawable.width = pScreen->width;
+    pWin->drawable.x = pWin->drawable.y = 0;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+    pWin->drawable.class = InputOutput;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->backgroundState = BackgroundPixel;
+    pWin->background.pixel = pScreen->whitePixel;
+
+    pWin->borderIsPixel = TRUE;
+    pWin->border.pixel = pScreen->blackPixel;
+    pWin->borderWidth = 0;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+	return FALSE;
+
+    if (disableBackingStore)
+    {
+      pScreen -> backingStoreSupport = NotUseful;
+    }
+
+    if (enableBackingStore)
+    {
+      pScreen -> backingStoreSupport = Always;
+    }
+
+    pScreen->saveUnderSupport = False;
+
+#ifdef DO_SAVE_UNDERS
+    if ((pScreen->backingStoreSupport != NotUseful) &&
+	(pScreen->saveUnderSupport == NotUseful))
+    {
+	/*
+	 * If the screen has backing-store but no save-unders, let the
+	 * clients know we can support save-unders using backing-store.
+	 */
+	pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+    }
+#endif /* DO_SAVE_UNDERS */
+		
+    if (disableSaveUnders)
+	pScreen->saveUnderSupport = NotUseful;
+
+    return TRUE;
+}
+
+#ifdef NXAGENT_SERVER
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen;
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (nxagentOption(Rootless))
+    {
+      #ifdef TEST
+      fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
+                  (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+      #endif
+
+      nxagentRootlessWindow = pWin;
+    }
+
+    pScreen = pWin->drawable.pScreen;
+
+    /*
+     * A root window is created for each screen by main
+     * and the pointer is saved in WindowTable as in the
+     * following snippet:
+     *
+     * for (i = 0; i < screenInfo.numScreens; i++)
+     *          InitRootWindow(WindowTable[i]);
+     *
+     * Our root window on the real display was already
+     * created at the time the screen was opened, so it
+     * is unclear how this window (or the other window,
+     * if you prefer) fits in the big picture.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+
+    #ifdef NXAGENT_SPLASH
+    /* We SHOULD check for an error value here XXX */
+    pWin -> background.pixel = pScreen -> blackPixel;
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
+    #else
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+    #endif
+
+    MakeRootTile(pWin);
+
+    /*
+     * Map both the root and the default agent window.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
+    #endif
+
+    nxagentInitAtoms(pWin);
+
+    nxagentInitClipboard(pWin);
+
+    nxagentMapDefaultWindows();
+
+    nxagentRedirectDefaultWindows();
+
+    #ifdef NXAGENT_ARTSD
+    {
+      char artsd_port[10];
+      int nPort;
+      extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+      nPort = atoi(display) + 7000;
+      sprintf(artsd_port,"%d", nPort);
+      nxagentPropagateArtsdProperties(pScreen, artsd_port);
+    }
+    #endif
+}
+
+#else /* NXAGENT_SERVER */
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    MakeRootTile(pWin);
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+    MapWindow(pWin, serverClient);
+}
+
+#endif /* NXAGENT_SERVER */
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize.  The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+                     register int x, register int y,
+                     register int w, register int h)
+{
+#ifndef NXAGENT_SERVER
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+    BoxRec box;
+
+    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+    /* we do these calculations to avoid overflows */
+    if (x > box.x1)
+	box.x1 = x;
+    if (y > box.y1)
+	box.y1 = y;
+    x += w;
+    if (x < box.x2)
+	box.x2 = x;
+    y += h;
+    if (y < box.y2)
+	box.y2 = y;
+    if (box.x1 > box.x2)
+	box.x2 = box.x1;
+    if (box.y1 > box.y2)
+	box.y2 = box.y1;
+    REGION_RESET(pScreen, Rgn, &box);
+    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+    if (!pWin->parent &&
+	(screenIsSaved == SCREEN_SAVER_ON) &&
+	(HasSaverWindow (pWin->drawable.pScreen->myNum)))
+	return (pWin->firstChild);
+    else
+	return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ *    Makes a window in response to client request 
+ *****/
+
+WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+             unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+             int depth, ClientPtr client, VisualID visual, int *error)
+{
+    register WindowPtr pWin;
+    WindowPtr pHead;
+    register ScreenPtr pScreen;
+    xEvent event;
+    int idepth, ivisual;
+    Bool fOK;
+    DepthPtr pDepth;
+    PixmapFormatRec *format;
+    register WindowOptPtr ancwopt;
+
+    if (class == CopyFromParent)
+	class = pParent->drawable.class;
+
+    if ((class != InputOutput) && (class != InputOnly))
+    {
+	*error = BadValue;
+	client->errorValue = class;
+	return NullWindow;
+    }
+
+    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pScreen = pParent->drawable.pScreen;
+    if ((class == InputOutput) && (depth == 0))
+	 depth = pParent->drawable.depth;
+    ancwopt = pParent->optional;
+    if (!ancwopt)
+	ancwopt = FindWindowWithOptional(pParent)->optional;
+    if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+	VisualID ag_visual;
+
+	if (client->appgroup && !pParent->parent &&
+	    (ag_visual = XagRootVisual (client)))
+	    visual = ag_visual;
+	else
+#endif
+	visual = ancwopt->visual;
+    }
+
+    /* Find out if the depth and visual are acceptable for this Screen */
+    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+    {
+	fOK = FALSE;
+	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+	{
+	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+	    if ((depth == pDepth->depth) || (depth == 0))
+	    {
+		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+		{
+		    if (visual == pDepth->vids[ivisual])
+		    {
+			fOK = TRUE;
+			break;
+		    }
+		}
+	    }
+	}
+	if (fOK == FALSE)
+	{
+	    *error = BadMatch;
+	    return NullWindow;
+	}
+    }
+
+    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+	(class != InputOnly) &&
+	(depth != pParent->drawable.depth))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if (((vmask & CWColormap) == 0) &&
+	(class != InputOnly) &&
+	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+    {
+	*error = BadAlloc;
+	return NullWindow;
+    }
+    pWin->drawable = pParent->drawable;
+    pWin->drawable.depth = depth;
+    if (depth == pParent->drawable.depth)
+	pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+    else
+    {
+	for (format = screenInfo.formats; format->depth != depth; format++)
+	    ;
+	pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+    }
+    if (class == InputOnly)
+	pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->drawable.id = wid;
+    pWin->drawable.class = class;
+
+    pWin->parent = pParent;
+    SetWindowToDefaults(pWin);
+
+    if (visual != ancwopt->visual)
+    {
+	if (!MakeWindowOptional (pWin))
+	{
+	    xfree (pWin);
+	    *error = BadAlloc;
+	    return NullWindow;
+	}
+	pWin->optional->visual = visual;
+	pWin->optional->colormap = None;
+    }
+
+    pWin->borderWidth = bw;
+#ifdef XCSECURITY
+    /*  can't let untrusted clients have background None windows;
+     *  they make it too easy to steal window contents
+     */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	pWin->backgroundState = BackgroundPixel;
+	pWin->background.pixel = 0;
+    }
+    else
+#endif
+    pWin->backgroundState = None;
+
+    pWin->borderIsPixel = pParent->borderIsPixel;
+    pWin->border = pParent->border;
+    if (pWin->borderIsPixel == FALSE)
+	pWin->border.pixmap->refcnt++;
+		
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    pWin->drawable.width = w;
+    pWin->drawable.height = h;
+    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+	/* set up clip list correctly for unobscured WindowPtr */
+    REGION_NULL(pScreen, &pWin->clipList);
+    REGION_NULL(pScreen, &pWin->borderClip);
+    REGION_NULL(pScreen, &pWin->winSize);
+    REGION_NULL(pScreen, &pWin->borderSize);
+
+    pHead = RealChildHead(pParent);
+    if (pHead)
+    {
+	pWin->nextSib = pHead->nextSib;
+	if (pHead->nextSib)
+	    pHead->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pHead->nextSib = pWin;
+	pWin->prevSib = pHead;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    /* We SHOULD check for an error value here XXX */
+    if (!(*pScreen->CreateWindow)(pWin))
+    {
+	*error = BadAlloc;
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    if (!(vmask & CWEventMask))
+	RecalculateDeliverableEvents(pWin);
+
+    if (vmask)
+	*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+    else
+	*error = Success;
+
+    if (*error != Success)
+    {
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+    {
+	XID value = defaultBackingStore;
+	(void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+	pWin->forcedBS = TRUE;
+    }
+
+    if (SubSend(pParent))
+    {
+	event.u.u.type = CreateNotify;
+	event.u.createNotify.window = wid;
+	event.u.createNotify.parent = pParent->drawable.id;
+	event.u.createNotify.x = x;
+	event.u.createNotify.y = y;
+	event.u.createNotify.width = w;
+	event.u.createNotify.height = h;
+	event.u.createNotify.borderWidth = bw;
+	event.u.createNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pParent, &event, 1, NullWindow);		
+    }
+    return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DeleteWindowFromAnySaveSet(pWin);
+    DeleteWindowFromAnySelections(pWin);
+    DeleteWindowFromAnyEvents(pWin, TRUE);
+    REGION_UNINIT(pScreen, &pWin->clipList);
+    REGION_UNINIT(pScreen, &pWin->winSize);
+    REGION_UNINIT(pScreen, &pWin->borderClip);
+    REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+    if (wBoundingShape (pWin))
+	REGION_DESTROY(pScreen, wBoundingShape (pWin));
+    if (wClipShape (pWin))
+	REGION_DESTROY(pScreen, wClipShape (pWin));
+    if (wInputShape (pWin))
+	REGION_DESTROY(pScreen, wInputShape (pWin));
+#endif
+    if (pWin->borderIsPixel == FALSE)
+	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+    if (pWin->backgroundState == BackgroundPixmap)
+	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+    DeleteAllWindowProperties(pWin);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->DestroyWindow)(pWin);
+    DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+    register WindowPtr pChild, pSib, pParent;
+    UnrealizeWindowProcPtr UnrealizeWindow;
+    xEvent event;
+
+    if (!(pChild = pWin->firstChild))
+	return;
+    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+    while (1)
+    {
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (1)
+	{
+	    pParent = pChild->parent;
+	    if (SubStrSend(pChild, pParent))
+	    {
+		event.u.u.type = DestroyNotify;
+		event.u.destroyNotify.window = pChild->drawable.id;
+		DeliverEvents(pChild, &event, 1, NullWindow);		
+	    }
+	    FreeResource(pChild->drawable.id, RT_WINDOW);
+	    pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder && pChild->viewable)
+		deltaSaveUndersViewable--;
+#endif
+	    pChild->viewable = FALSE;
+	    if (pChild->realized)
+	    {
+		pChild->realized = FALSE;
+		(*UnrealizeWindow)(pChild);
+	    }
+	    FreeWindowResources(pChild);
+	    xfree(pChild);
+	    if ( (pChild = pSib) )
+		break;
+	    pChild = pParent;
+	    pChild->firstChild = NullWindow;
+	    pChild->lastChild = NullWindow;
+	    if (pChild == pWin)
+		return;
+	}
+    }
+}
+	
+/*****
+ *  DeleteWindow
+ *	 Deletes child of window then window itself
+ *	 If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(pointer value, XID wid)
+ {
+    register WindowPtr pParent;
+    register WindowPtr pWin = (WindowPtr)value;
+    xEvent event;
+
+    UnmapWindow(pWin, FALSE);
+
+    CrushTree(pWin);
+
+    pParent = pWin->parent;
+    if (wid && pParent && SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = DestroyNotify;
+	event.u.destroyNotify.window = pWin->drawable.id;
+	DeliverEvents(pWin, &event, 1, NullWindow);		
+    }
+
+    FreeWindowResources(pWin);
+    if (pParent)
+    {
+	if (pParent->firstChild == pWin)
+	    pParent->firstChild = pWin->nextSib;
+	if (pParent->lastChild == pWin)
+	    pParent->lastChild = pWin->prevSib;
+	if (pWin->nextSib)
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	if (pWin->prevSib)
+	    pWin->prevSib->nextSib = pWin->nextSib;
+    }
+
+    if (pWin -> optional &&
+            pWin -> optional -> colormap &&
+                pWin -> parent)
+    {
+      nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+    }
+
+    xfree(pWin);
+    return Success;
+}
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+    /* XXX
+     * The protocol is quite clear that each window should be
+     * destroyed in turn, however, unmapping all of the first
+     * eliminates most of the calls to ValidateTree.  So,
+     * this implementation is incorrect in that all of the
+     * UnmapNotifies occur before all of the DestroyNotifies.
+     * If you care, simply delete the call to UnmapSubwindows.
+     */
+    UnmapSubwindows(pWin);
+    while (pWin->lastChild)
+	FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+    ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ *  ChangeWindowAttributes
+ *   
+ *  The value-mask specifies which attributes are to be changed; the
+ *  value-list contains one value for each one bit in the mask, from least
+ *  to most significant bit in the mask.  
+ *****/
+ 
+int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+    register Mask index2;
+    register XID *pVlist;
+    PixmapPtr pPixmap;
+    Pixmap pixID;
+    CursorPtr pCursor, pOldCursor;
+    Cursor cursorID;
+    WindowPtr pChild;
+    Colormap cmap;
+    ColormapPtr	pCmap;
+    xEvent xE;
+    int result;
+    register ScreenPtr pScreen;
+    Mask vmaskCopy = 0;
+    register Mask tmask;
+    unsigned int val;
+    int error;
+    Bool checkOptional = FALSE;
+    Bool borderRelative = FALSE;
+    WindowPtr pLayerWin;
+
+    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+	return BadMatch;
+
+    error = Success;
+    pScreen = pWin->drawable.pScreen;
+    pVlist = vlist;
+    tmask = vmask;
+    while (tmask)
+    {
+	index2 = (Mask) lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBackPixmap:
+	    pixID = (Pixmap )*pVlist;
+	    pVlist++;
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pixID == None)
+	    {
+#ifdef XCSECURITY
+		/*  can't let untrusted clients have background None windows */
+		if (client->trustLevel == XSecurityClientTrusted)
+		{
+#endif
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = None;
+#ifdef XCSECURITY
+		}
+		else
+		{ /* didn't change the background to None, so don't tell ddx */
+		    index2 = 0; 
+		}
+#endif
+	    }
+	    else if (pixID == ParentRelative)
+	    {
+		if (pWin->parent &&
+		    pWin->drawable.depth != pWin->parent->drawable.depth)
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = ParentRelative;
+		borderRelative = TRUE;
+		/* Note that the parent's backgroundTile's refcnt is NOT
+		 * incremented. */
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+						RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap != (PixmapPtr) NULL)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->backgroundState == BackgroundPixmap)
+			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    pWin->backgroundState = BackgroundPixmap;
+		    pWin->background.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBackPixel:
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pWin->backgroundState == BackgroundPixmap)
+		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+	    pWin->backgroundState = BackgroundPixel;
+	    pWin->background.pixel = (CARD32 ) *pVlist;
+		   /* background pixel overrides background pixmap,
+		      so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBackPixmap;
+	    pVlist++;
+	    break;
+	  case CWBorderPixmap:
+	    pixID = (Pixmap ) *pVlist;
+	    pVlist++;
+	    if (pixID == CopyFromParent)
+	    {
+		if (!pWin->parent ||
+		    (pWin->drawable.depth != pWin->parent->drawable.depth))
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->borderIsPixel == FALSE)
+		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		pWin->border = pWin->parent->border;
+		if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+		{
+		    index2 = CWBorderPixel;
+		}
+		else
+		{
+		    pWin->parent->border.pixmap->refcnt++;
+		}
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+					RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->borderIsPixel == FALSE)
+			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		    pWin->borderIsPixel = FALSE;
+		    pWin->border.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBorderPixel:
+	    if (pWin->borderIsPixel == FALSE)
+		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+	    pWin->borderIsPixel = TRUE;
+	    pWin->border.pixel = (CARD32) *pVlist;
+		    /* border pixel overrides border pixmap,
+		       so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBorderPixmap;
+	    pVlist++;
+	    break;
+	  case CWBitGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->bitGravity = val;
+	    break;
+	  case CWWinGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->winGravity = val;
+	    break;
+	  case CWBackingStore:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->backingStore = val;
+
+            #ifdef TEST
+            fprintf(stderr, "ChangeWindowAttributes: Changed backing store value to %d for window at %p.\n",
+                        val, (void*)pWin);
+            #endif
+
+	    pWin->forcedBS = FALSE;
+	    break;
+	  case CWBackingPlanes:
+	    if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+		if ((CARD32)*pVlist == (CARD32)~0L)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWBackingPixel:
+	    if (pWin->optional || (CARD32) *pVlist) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingPixel = (CARD32) *pVlist;
+		if (!*pVlist)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWSaveUnder:
+	    val = (BOOL) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+		DO_SAVE_UNDERS(pWin))
+	    {
+		/*
+		 * Re-check all siblings and inferiors for obscurity or
+		 * exposition (hee hee).
+		 */
+		if (pWin->saveUnder)
+		    deltaSaveUndersViewable--;
+		else
+		    deltaSaveUndersViewable++;
+		pWin->saveUnder = val;
+
+		if (pWin->firstChild)
+		{
+                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+                                                       pWin->nextSib);
+               }
+               else
+               {
+                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pWin,
+                                                       pWin->nextSib);
+               }                                   
+	    }
+	    else
+	    {
+		/*  If we're changing the saveUnder attribute of the root 
+		 *  window, all we do is set pWin->saveUnder so that
+		 *  GetWindowAttributes returns the right value.  We don't
+		 *  do the "normal" save-under processing (as above).
+		 *  Hope that doesn't cause any problems.
+		 */
+		pWin->saveUnder = val;
+	    }
+#else
+	    pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+	    break;
+	  case CWEventMask:
+            /*
+             * TODO: Some applications like java bean shell
+             * don' t work if they cannot monitor the root
+             * window for Structure Redirect events. However
+             * this doesn't seem to be the best solution, since
+             * also an X server with a window manager running,
+             * doesn't allow to monitor for those events, but
+             * the java bean shell works flawlessy on this
+             * server.
+             *
+             * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
+             * {
+             *   return BadAccess;
+             * }
+             */
+
+	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWDontPropagate:
+	    result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+					    &checkOptional);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWOverrideRedirect:
+	    val = (BOOL ) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->overrideRedirect = val;
+	    break;
+	  case CWColormap:
+	    cmap = (Colormap) *pVlist;
+	    pVlist++;
+	    if (cmap == CopyFromParent)
+	    {
+#ifdef XAPPGROUP
+		Colormap ag_colormap;
+		ClientPtr win_owner;
+
+		/*
+		 * win_owner == client for CreateWindow, other clients
+		 * can ChangeWindowAttributes
+		 */
+		win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+		if ( win_owner && win_owner->appgroup &&
+		    !pWin->parent->parent &&
+		    (ag_colormap = XagDefaultColormap (win_owner)))
+		    cmap = ag_colormap;
+		else
+#endif
+		if (pWin->parent &&
+		    (!pWin->optional ||
+		     pWin->optional->visual == wVisual (pWin->parent)))
+		{
+		    cmap = wColormap (pWin->parent);
+		}
+		else
+		    cmap = None;
+	    }
+	    if (cmap == None)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+					      RT_COLORMAP, SecurityReadAccess);
+	    if (!pCmap)
+	    {
+		error = BadColor;
+		client->errorValue = cmap;
+		goto PatchUp;
+	    }
+	    if (pCmap->pVisual->vid != wVisual (pWin) ||
+		pCmap->pScreen != pScreen)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    if (cmap != wColormap (pWin))
+	    {
+		if (!pWin->optional)
+		{
+		    if (!MakeWindowOptional (pWin))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+		else if (pWin->parent && cmap == wColormap (pWin->parent))
+		    checkOptional = TRUE;
+
+		/*
+		 * propagate the original colormap to any children
+		 * inheriting it
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pWin->optional->colormap = cmap;
+
+		/*
+		 * check on any children now matching the new colormap
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (pChild->optional->colormap == cmap)
+			CheckWindowOptionalNeed (pChild);
+		}
+	
+		xE.u.u.type = ColormapNotify;
+		xE.u.colormap.window = pWin->drawable.id;
+		xE.u.colormap.colormap = cmap;
+		xE.u.colormap.new = xTrue;
+		xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+		DeliverEvents(pWin, &xE, 1, NullWindow);
+	    }
+	    break;
+	  case CWCursor:
+	    cursorID = (Cursor ) *pVlist;
+	    pVlist++;
+	    /*
+	     * install the new
+	     */
+	    if ( cursorID == None)
+	    {
+		if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+		    pCursor = rootCursor;
+		else
+		    pCursor = (CursorPtr) None;
+	    }
+	    else
+	    {
+		pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+						RT_CURSOR, SecurityReadAccess);
+		if (!pCursor)
+		{
+		    error = BadCursor;
+		    client->errorValue = cursorID;
+		    goto PatchUp;
+		}
+	    }
+
+	    if (pCursor != wCursor (pWin))
+	    {
+		/*
+		 * patch up child windows so they don't lose cursors.
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !pChild->cursorIsNone &&
+			!MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pOldCursor = 0;
+		if (pCursor == (CursorPtr) None)
+		{
+		    pWin->cursorIsNone = TRUE;
+		    if (pWin->optional)
+		    {
+			pOldCursor = pWin->optional->cursor;
+			pWin->optional->cursor = (CursorPtr) None;
+			checkOptional = TRUE;
+		    }
+		} else {
+		    if (!pWin->optional)
+		    {
+			if (!MakeWindowOptional (pWin))
+			{
+			    error = BadAlloc;
+			    goto PatchUp;
+			}
+		    }
+		    else if (pWin->parent && pCursor == wCursor (pWin->parent))
+			checkOptional = TRUE;
+		    pOldCursor = pWin->optional->cursor;
+		    pWin->optional->cursor = pCursor;
+		    pCursor->refcnt++;
+		    pWin->cursorIsNone = FALSE;
+		    /*
+		     * check on any children now matching the new cursor
+		     */
+
+		    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+		    {
+			if (pChild->optional &&
+			    (pChild->optional->cursor == pCursor))
+			    CheckWindowOptionalNeed (pChild);
+		    }
+		}
+
+		if (pWin->realized)
+		    WindowHasNewCursor( pWin);
+
+		/* Can't free cursor until here - old cursor
+		 * is needed in WindowHasNewCursor
+		 */
+		if (pOldCursor)
+		    FreeCursor (pOldCursor, (Cursor)0);
+	    }
+	    break;
+	 default:
+	    error = BadValue;
+	    client->errorValue = vmask;
+	    goto PatchUp;
+      }
+      vmaskCopy |= index2;
+    }
+PatchUp:
+    if (checkOptional)
+	CheckWindowOptionalNeed (pWin);
+
+	/* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+    /* 
+	If the border contents have changed, redraw the border. 
+	Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+	for the tile to be rotated, and the correct function selected.
+    */
+    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+	&& pWin->viewable && HasBorder (pWin))
+    {
+	RegionRec exposed;
+
+	REGION_NULL(pScreen, &exposed);
+	REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+	(*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+	REGION_UNINIT(pScreen, &exposed);
+    }
+    return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ *    Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+    wa->type = X_Reply;
+    wa->bitGravity = pWin->bitGravity;
+    wa->winGravity = pWin->winGravity;
+    if (pWin->forcedBS && pWin->backingStore != Always)
+	wa->backingStore = NotUseful;
+    else
+	wa->backingStore = pWin->backingStore;
+    wa->length = (sizeof(xGetWindowAttributesReply) -
+		 sizeof(xGenericReply)) >> 2;
+    wa->sequenceNumber = client->sequence;
+    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
+    wa->backingPixel =  wBackingPixel (pWin);
+    wa->saveUnder = (BOOL)pWin->saveUnder;
+    wa->override = pWin->overrideRedirect;
+    if (!pWin->mapped)
+	wa->mapState = IsUnmapped;
+    else if (pWin->realized)
+	wa->mapState = IsViewable;
+    else
+	wa->mapState = IsUnviewable;
+
+    wa->colormap =  wColormap (pWin);
+    wa->mapInstalled = (wa->colormap == None) ? xFalse
+				: IsMapInstalled(wa->colormap, pWin);
+
+    wa->yourEventMask = EventMaskForClient(pWin, client);
+    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+    wa->doNotPropagateMask = wDontPropagateMask (pWin);
+    wa->class = pWin->drawable.class;
+    wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+    register WindowPtr pParent = pWin->parent;
+    WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+    if (pWin->nextSib != pNextSib)
+    {
+	WindowPtr pOldNextSib = pWin->nextSib;
+
+	if (!pNextSib)	      /* move to bottom */
+	{
+	    if (pParent->firstChild == pWin)
+		pParent->firstChild = pWin->nextSib;
+	    /* if (pWin->nextSib) */	 /* is always True: pNextSib == NULL
+					  * and pWin->nextSib != pNextSib
+					  * therefore pWin->nextSib != NULL */
+	    pFirstChange = pWin->nextSib;
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pParent->lastChild->nextSib = pWin;
+	    pWin->prevSib = pParent->lastChild;
+	    pWin->nextSib = NullWindow;
+	    pParent->lastChild = pWin;
+	}
+	else if (pParent->firstChild == pNextSib) /* move to top */
+	{
+	    pFirstChange = pWin;
+	    if (pParent->lastChild == pWin)
+	       pParent->lastChild = pWin->prevSib;
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pParent->firstChild;
+	    pWin->prevSib = (WindowPtr ) NULL;
+	    pNextSib->prevSib = pWin;
+	    pParent->firstChild = pWin;
+	}
+	else			/* move in middle of list */
+	{
+	    WindowPtr pOldNext = pWin->nextSib;
+
+	    pFirstChange = NullWindow;
+	    if (pParent->firstChild == pWin)
+		pFirstChange = pParent->firstChild = pWin->nextSib;
+	    if (pParent->lastChild == pWin) {
+	       pFirstChange = pWin;
+	       pParent->lastChild = pWin->prevSib;
+	    }
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pNextSib;
+	    pWin->prevSib = pNextSib->prevSib;
+	    if (pNextSib->prevSib)
+		pNextSib->prevSib->nextSib = pWin;
+	    pNextSib->prevSib = pWin;
+	    if (!pFirstChange) {		     /* do we know it yet? */
+		pFirstChange = pParent->firstChild;  /* no, search from top */
+		while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+		     pFirstChange = pFirstChange->nextSib;
+	    }
+	}
+	if(pWin->drawable.pScreen->RestackWindow)
+	    (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+    }
+
+#ifdef ROOTLESS
+    /*
+     * In rootless mode we can't optimize away window restacks.
+     * There may be non-X windows around, so even if the window
+     * is in the correct position from X's point of view,
+     * the underlying window system may want to reorder it.
+     */
+    else if (pWin->drawable.pScreen->RestackWindow)
+        (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+    return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+    RegionPtr	pRgn;
+    BoxRec	box;
+
+    box.x1 = pWin->drawable.x;
+    box.y1 = pWin->drawable.y;
+    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+	ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+    }
+#endif
+    return pRgn;
+}
+
+void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+    if (pWin->redirectDraw)
+    {
+	BoxRec	box;
+
+	box.x1 = pWin->drawable.x;
+	box.y1 = pWin->drawable.y;
+	box.x2 = pWin->drawable.x + pWin->drawable.width;
+	box.y2 = pWin->drawable.y + pWin->drawable.height;
+	REGION_RESET (pScreen, &pWin->winSize, &box);
+    }
+    else
+#endif
+    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+			 pWin->drawable.x, pWin->drawable.y,
+			 (int)pWin->drawable.width,
+			 (int)pWin->drawable.height);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+	ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+			 pWin->drawable.y);
+    }
+#endif
+}
+
+void
+SetBorderSize (register WindowPtr pWin)
+{
+    int	bw;
+
+    if (HasBorder (pWin)) {
+	bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+	if (pWin->redirectDraw)
+	{
+	    BoxRec	box;
+
+	    box.x1 = pWin->drawable.x - bw;
+	    box.y1 = pWin->drawable.y - bw;
+	    box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+	    box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+	    REGION_RESET (pScreen, &pWin->borderSize, &box);
+	}
+	else
+#endif
+	ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+		pWin->drawable.x - bw, pWin->drawable.y - bw,
+		(int)(pWin->drawable.width + (bw<<1)),
+		(int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+	if (wBoundingShape (pWin)) {
+#ifndef NXAGENT_SERVER
+	    ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+			     - pWin->drawable.y);
+	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+			     wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+			     pWin->drawable.y);
+	    REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+			 &pWin->winSize);
+	}
+#endif
+    } else {
+	REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+					       &pWin->winSize);
+    }
+}
+
+/**
+ *
+ *  \param x,y          new window position
+ *  \param oldx,oldy    old window position
+ *  \param destx,desty  position relative to gravity
+ */
+
+void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+                  int dw, int dh, unsigned gravity,
+                  register int *destx, register int *desty)
+{
+    switch (gravity) {
+    case NorthGravity:
+	*destx = x + dw / 2;
+	*desty = y;
+	break;
+    case NorthEastGravity:
+	*destx = x + dw;
+	*desty = y;
+	break;
+    case WestGravity:
+	*destx = x;
+	*desty = y + dh / 2;
+	break;
+    case CenterGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh / 2;
+	break;
+    case EastGravity:
+	*destx = x + dw;
+	*desty = y + dh / 2;
+	break;
+    case SouthWestGravity:
+	*destx = x;
+	*desty = y + dh;
+	break;
+    case SouthGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh;
+	break;
+    case SouthEastGravity:
+	*destx = x + dw;
+	*desty = y + dh;
+	break;
+    case StaticGravity:
+	*destx = oldx;
+	*desty = oldy;
+	break;
+    default:
+	*destx = x;
+	*desty = y;
+	break;
+    }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+    register ScreenPtr pScreen;
+    register WindowPtr pSib, pChild;
+    Bool resized = (dw || dh);
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+    {
+	if (resized && (pSib->winGravity > NorthWestGravity))
+	{
+	    int cwsx, cwsy;
+
+	    cwsx = pSib->origin.x;
+	    cwsy = pSib->origin.y;
+	    GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+			pSib->winGravity, &cwsx, &cwsy);
+	    if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+	    {
+		xEvent event;
+
+		event.u.u.type = GravityNotify;
+		event.u.gravity.window = pSib->drawable.id;
+		event.u.gravity.x = cwsx - wBorderWidth (pSib);
+		event.u.gravity.y = cwsy - wBorderWidth (pSib);
+		DeliverEvents (pSib, &event, 1, NullWindow);
+		pSib->origin.x = cwsx;
+		pSib->origin.y = cwsy;
+	    }
+	}
+	pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+	SetWinSize (pSib);
+	SetBorderSize (pSib);
+
+        /*
+         * Don't force X to move children. It will position them
+         * according with gravity.
+         *
+         * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+         */
+
+        /*
+         * Update pSib privates, as this window is moved by X.
+         */
+
+        nxagentAddConfiguredWindow(pSib, CW_Update);
+
+	if ( (pChild = pSib->firstChild) )
+	{
+	    while (1)
+	    {
+		pChild->drawable.x = pChild->parent->drawable.x +
+				     pChild->origin.x;
+		pChild->drawable.y = pChild->parent->drawable.y +
+				     pChild->origin.y;
+		SetWinSize (pChild);
+		SetBorderSize (pChild);
+
+                (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
+                                               pChild->drawable.y);
+
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+		while (!pChild->nextSib && (pChild != pSib))
+		    pChild = pChild->parent;
+		if (pChild == pSib)
+		    break;
+		pChild = pChild->nextSib;
+	    }
+	}
+    }
+}
+
+#define GET_INT16(m, f) \
+	if (m & mask) \
+	  { \
+	     f = (INT16) *pVlist;\
+	    pVlist++; \
+	 }
+#define GET_CARD16(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD16) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define GET_CARD8(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD8) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ *     returns Above if pSib above pMe in stack or Below otherwise 
+ */
+
+static int
+IsSiblingAboveMe(
+    register WindowPtr pMe,
+    register WindowPtr pSib)
+{
+    register WindowPtr pWin;
+
+    pWin = pMe->parent->firstChild;
+    while (pWin)
+    {
+	if (pWin == pSib)
+	    return(Above);
+	else if (pWin == pMe)
+	    return(Below);
+	pWin = pWin->nextSib;
+    }
+    return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+    register WindowPtr pWin,
+    register BoxPtr pBox)
+{
+    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+	       + wBorderWidth (pWin);
+    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+	       + wBorderWidth (pWin);
+    return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin)	(wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+    register WindowPtr	pWin,
+    BoxPtr	pBox)
+{
+    RegionPtr	pRgn;
+#ifndef NXAGENT_SERVER
+    ScreenPtr   pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+    pRgn = REGION_CREATE(pScreen, pBox, 1);
+    if (wBoundingShape (pWin)) {
+	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+						  -pWin->origin.y);
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+						  pWin->origin.y);
+    }
+    return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+    WindowPtr	pWin,
+    BoxPtr	pWinBox,
+    WindowPtr	pSib,
+    BoxPtr	pSibBox)
+{
+    RegionPtr	pWinRgn, pSibRgn;
+    register ScreenPtr	pScreen;
+    Bool	ret;
+
+    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+	return TRUE;
+    pScreen = pWin->drawable.pScreen;
+    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pSibRgn);
+    return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+    WindowPtr pWin,
+    WindowPtr pHead,
+    register BoxPtr box)
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+    WindowPtr pWin,
+    register BoxPtr box)
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+/*
+ *   WhereDoIGoInTheStack() 
+ *	  Given pWin and pSib and the relationshipe smode, return
+ *	  the window that pWin should go ABOVE.
+ *	  If a pSib is specified:
+ *	      Above:  pWin is placed just above pSib
+ *	      Below:  pWin is placed just below pSib
+ *	      TopIf:  if pSib occludes pWin, then pWin is placed
+ *		      at the top of the stack
+ *	      BottomIf:	 if pWin occludes pSib, then pWin is 
+ *			 placed at the bottom of the stack
+ *	      Opposite: if pSib occludes pWin, then pWin is placed at the
+ *			top of the stack, else if pWin occludes pSib, then
+ *			pWin is placed at the bottom of the stack
+ *
+ *	  If pSib is NULL:
+ *	      Above:  pWin is placed at the top of the stack
+ *	      Below:  pWin is placed at the bottom of the stack
+ *	      TopIf:  if any sibling occludes pWin, then pWin is placed at
+ *		      the top of the stack
+ *	      BottomIf: if pWin occludes any sibline, then pWin is placed at
+ *			the bottom of the stack
+ *	      Opposite: if any sibling occludes pWin, then pWin is placed at
+ *			the top of the stack, else if pWin occludes any
+ *			sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    short x,
+    short y,
+    unsigned short w,
+    unsigned short h,
+    int smode)
+{
+    BoxRec box;
+    register ScreenPtr pScreen;
+    WindowPtr pHead, pFirst;
+
+    if ((pWin == pWin->parent->firstChild) &&
+	(pWin == pWin->parent->lastChild))
+	return((WindowPtr ) NULL);
+    pHead = RealChildHead(pWin->parent);
+    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+    pScreen = pWin->drawable.pScreen;
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + (int)w;
+    box.y2 = y + (int)h;
+    switch (smode)
+    {
+      case Above:
+	if (pSib)
+	   return(pSib);
+	else if (pWin == pFirst)
+	    return(pWin->nextSib);
+	else
+	    return(pFirst);
+      case Below:
+	if (pSib)
+	    if (pSib->nextSib != pWin)
+		return(pSib->nextSib);
+	    else
+		return(pWin->nextSib);
+	else
+	    return NullWindow;
+      case TopIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return(pFirst);
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	    return(pFirst);
+	else
+	    return(pWin->nextSib);
+      case BottomIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return NullWindow;
+	    else
+		return(pWin->nextSib);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return(pWin->nextSib);
+      case Opposite:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+	    {
+		if (IsSiblingAboveMe(pWin, pSib) == Above)
+		    return(pFirst);
+		else
+		    return NullWindow;
+	    }
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	{
+	    /* If I'm occluded, I can't possibly be the first child
+	     * if (pWin == pWin->parent->firstChild)
+	     *	  return pWin->nextSib;
+	     */
+	    return(pFirst);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return pWin->nextSib;
+      default:
+      {
+	ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+	return pWin->nextSib;
+      }
+    }
+}
+
+static void
+ReflectStackChange(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    VTKind  kind)
+{
+/* Note that pSib might be NULL */
+
+    Bool WasViewable = (Bool)pWin->viewable;
+    Bool anyMarked;
+    WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    /* if this is a root window, can't be restacked */
+    if (!pWin->parent)
+	return;
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						      &pLayerWin);
+	if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN    0
+#define MOVE_WIN       1
+#define RESIZE_WIN     2
+#define REBORDER_WIN   3
+    register WindowPtr pSib = NullWindow;
+    register WindowPtr pParent = pWin->parent;
+    Window sibwid = 0;
+    Mask index2, tmask;
+    register XID *pVlist;
+    short x,   y, beforeX, beforeY;
+    unsigned short w = pWin->drawable.width,
+		   h = pWin->drawable.height,
+		   bw = pWin->borderWidth;
+    int action, smode = Above;
+#ifdef XAPPGROUP
+    ClientPtr win_owner;
+    ClientPtr ag_leader = NULL;
+#endif
+    xEvent event;
+
+    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+	return(BadMatch);
+
+    if ((mask & CWSibling) && !(mask & CWStackMode))
+	return(BadMatch);
+
+    pVlist = vlist;
+
+    if (pParent)
+    {
+	x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+	y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+    }
+    else
+    {
+	x = pWin->drawable.x;
+	y = pWin->drawable.y;
+    }
+    beforeX = x;
+    beforeY = y;
+    action = RESTACK_WIN;	
+    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	action = MOVE_WIN;
+    }
+	/* or should be resized */
+    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	GET_CARD16(CWWidth, w);
+	GET_CARD16 (CWHeight, h);
+	if (!w || !h)
+	{
+	    client->errorValue = 0;
+	    return BadValue;
+	}
+	action = RESIZE_WIN;
+    }
+    tmask = mask & ~ChangeMask;
+    while (tmask)
+    {
+	index2 = (Mask)lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBorderWidth:
+	    GET_CARD16(CWBorderWidth, bw);
+	    break;
+	  case CWSibling:
+	    sibwid = (Window ) *pVlist;
+	    pVlist++;
+	    pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+						RT_WINDOW, SecurityReadAccess);
+	    if (!pSib)
+	    {
+		client->errorValue = sibwid;
+		return(BadWindow);
+	    }
+	    if (pSib->parent != pParent)
+		return(BadMatch);
+	    if (pSib == pWin)
+		return(BadMatch);
+	    break;
+	  case CWStackMode:
+	    GET_CARD8(CWStackMode, smode);
+	    if ((smode != TopIf) && (smode != BottomIf) &&
+		(smode != Opposite) && (smode != Above) && (smode != Below))
+	    {
+		client->errorValue = smode;
+		return(BadValue);
+	    }
+	    break;
+	  default:
+	    client->errorValue = mask;
+	    return(BadValue);
+	}
+    }
+	/* root really can't be reconfigured, so just return */
+    if (!pParent)
+	return Success;
+
+	/* Figure out if the window should be moved.  Doesnt
+	   make the changes to the window if event sent */
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+
+      fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
+                  pWin, mask, client);
+
+      fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
+                  "smode [%d] pSib [%p]\n",
+                      x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
+    }
+    #endif
+
+    if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
+            pWin -> overrideRedirect == 0 &&
+                nxagentScreenTrap == 0)
+    {
+      nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
+
+      return Success;
+    }
+
+    if (mask & CWStackMode)
+	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+				    pParent->drawable.y + y,
+				    w + (bw << 1), h + (bw << 1), smode);
+    else
+	pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+    ag_leader = XagLeader (win_owner);
+#endif
+
+    if ((!pWin->overrideRedirect) && 
+	(RedirectSend(pParent)
+#ifdef XAPPGROUP
+	|| (win_owner->appgroup && ag_leader && 
+	    XagIsControlledRoot (client, pParent))
+#endif
+	))
+    {
+	event.u.u.type = ConfigureRequest;
+	event.u.configureRequest.window = pWin->drawable.id;
+	if (mask & CWSibling)
+	   event.u.configureRequest.sibling = sibwid;
+	else
+	    event.u.configureRequest.sibling = None;
+	if (mask & CWStackMode)
+	   event.u.u.detail = smode;
+	else
+	    event.u.u.detail = Above;
+	event.u.configureRequest.x = x;
+	event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+            event.u.configureRequest.x += panoramiXdataPtr[0].x;
+            event.u.configureRequest.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureRequest.width = w;
+	event.u.configureRequest.height = h;
+	event.u.configureRequest.borderWidth = bw;
+	event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+	/* make sure if the ag_leader maps the window it goes to the wm */
+	if (ag_leader && ag_leader != client && 
+	    XagIsControlledRoot (client, pParent)) {
+	    event.u.configureRequest.parent = XagId (win_owner);
+	    (void) TryClientEvents (ag_leader, &event, 1,
+				    NoEventMask, NoEventMask, NullGrab);
+	    return Success;
+	}
+#endif
+	event.u.configureRequest.parent = pParent->drawable.id;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+    if (action == RESIZE_WIN)
+    {
+	Bool size_change = (w != pWin->drawable.width)
+			|| (h != pWin->drawable.height);
+	if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+	{
+	    xEvent eventT;
+	    eventT.u.u.type = ResizeRequest;
+	    eventT.u.resizeRequest.window = pWin->drawable.id;
+	    eventT.u.resizeRequest.width = w;
+	    eventT.u.resizeRequest.height = h;
+	    if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+				       ResizeRedirectMask, client) == 1)
+	    {
+		/* if event is delivered, leave the actual size alone. */
+		w = pWin->drawable.width;
+		h = pWin->drawable.height;
+		size_change = FALSE;
+	    }
+	}
+	if (!size_change)
+	{
+	    if (mask & (CWX | CWY))
+		action = MOVE_WIN;
+	    else if (mask & (CWStackMode | CWBorderWidth))
+		action = RESTACK_WIN;
+	    else   /* really nothing to do */
+		return(Success) ;
+	}
+    }
+
+    if (action == RESIZE_WIN)
+	    /* we've already checked whether there's really a size change */
+	    goto ActuallyDoSomething;
+    if ((mask & CWX) && (x != beforeX))
+	    goto ActuallyDoSomething;
+    if ((mask & CWY) && (y != beforeY))
+	    goto ActuallyDoSomething;
+    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+	    goto ActuallyDoSomething;
+    if (mask & CWStackMode)
+    {
+#ifndef ROOTLESS
+        /* See above for why we always reorder in rootless mode. */
+	if (pWin->nextSib != pSib)
+#endif
+	    goto ActuallyDoSomething;
+    }
+    return(Success);
+
+ActuallyDoSomething:
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = ConfigureNotify;
+	event.u.configureNotify.window = pWin->drawable.id;
+	if (pSib)
+	    event.u.configureNotify.aboveSibling = pSib->drawable.id;
+	else
+	    event.u.configureNotify.aboveSibling = None;
+	event.u.configureNotify.x = x;
+	event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+	    event.u.configureNotify.x += panoramiXdataPtr[0].x;
+            event.u.configureNotify.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureNotify.width = w;
+	event.u.configureNotify.height = h;
+	event.u.configureNotify.borderWidth = bw;
+	event.u.configureNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (mask & CWBorderWidth)
+    {
+	if (action == RESTACK_WIN)
+	{
+	    action = MOVE_WIN;
+	    pWin->borderWidth = bw;
+	}
+	else if ((action == MOVE_WIN) &&
+		 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+		 (beforeY + wBorderWidth (pWin) == y + (int)bw))
+	{
+	    action = REBORDER_WIN;
+	    (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+	}
+	else
+	    pWin->borderWidth = bw;
+    }
+    if (action == MOVE_WIN)
+	(*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+		   (mask & CWBorderWidth) ? VTOther : VTMove);
+    else if (action == RESIZE_WIN)
+	(*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+    else if (mask & CWStackMode)
+	ReflectStackChange(pWin, pSib, VTOther);
+
+    if (action != RESTACK_WIN)
+	CheckCursorConfinement(pWin);
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ *    For RaiseLowest, raises the lowest mapped child (if any) that is
+ *    obscured by another child to the top of the stack.  For LowerHighest,
+ *    lowers the highest mapped child (if any) that is obscuring another
+ *    child to the bottom of the stack.	 Exposure processing is performed 
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+    register WindowPtr pWin, pHead, pFirst;
+    xEvent event;
+    BoxRec box;
+
+    #ifdef TEST
+    fprintf(stderr, "CirculateWindow: pParent [%p] direction [%d] client [%p]\n",
+                pParent, direction, client);
+    #endif
+
+    /*
+     * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+     *         nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
+     * {
+     *   nxagentCirculateRootlessWindows(direction);
+     *   return Success;
+     * }
+     */
+
+    pHead = RealChildHead(pParent);
+    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+    if (direction == RaiseLowest)
+    {
+	for (pWin = pParent->lastChild;
+	     (pWin != pHead) &&
+	     !(pWin->mapped &&
+	       AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+	     pWin = pWin->prevSib) ;
+	if (pWin == pHead)
+	    return Success;
+    }
+    else
+    {
+	for (pWin = pFirst;
+	     pWin &&
+	     !(pWin->mapped &&
+	       IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+	     pWin = pWin->nextSib) ;
+	if (!pWin)
+	    return Success;
+    }
+
+    event.u.circulate.window = pWin->drawable.id;
+    event.u.circulate.parent = pParent->drawable.id;
+    event.u.circulate.event = pParent->drawable.id;
+    if (direction == RaiseLowest)
+	event.u.circulate.place = PlaceOnTop;
+    else
+	event.u.circulate.place = PlaceOnBottom;
+
+    if (RedirectSend(pParent))
+    {
+	event.u.u.type = CirculateRequest;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+
+    event.u.u.type = CirculateNotify;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+    ReflectStackChange(pWin,
+		       (direction == RaiseLowest) ? pFirst : NullWindow,
+		       VTStack);
+
+    return(Success);
+}
+
+static int
+CompareWIDs(
+    WindowPtr pWin,
+    pointer   value) /* must conform to VisitWindowProcPtr */
+{
+    Window *wid = (Window *)value;
+
+    if (pWin->drawable.id == *wid)
+       return(WT_STOPWALKING);
+    else
+       return(WT_WALKCHILDREN);
+}
+
+/*****
+ *  ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+               int x, int y, ClientPtr client)
+{
+    WindowPtr pPrev, pPriorParent;
+    Bool WasMapped = (Bool)(pWin->mapped);
+    xEvent event;
+    int bw = wBorderWidth (pWin);
+    register ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+	return(BadMatch);		
+    if (!MakeWindowOptional(pWin))
+	return(BadAlloc);
+
+    if (WasMapped)
+       UnmapWindow(pWin, FALSE);
+
+    event.u.u.type = ReparentNotify;
+    event.u.reparent.window = pWin->drawable.id;
+    event.u.reparent.parent = pParent->drawable.id;
+    event.u.reparent.x = x;
+    event.u.reparent.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && !pParent->parent) {
+	event.u.reparent.x += panoramiXdataPtr[0].x;
+	event.u.reparent.y += panoramiXdataPtr[0].y;
+    }
+#endif
+    event.u.reparent.override = pWin->overrideRedirect;
+    DeliverEvents(pWin, &event, 1, pParent);
+
+    /* take out of sibling chain */
+
+    pPriorParent = pPrev = pWin->parent;
+    if (pPrev->firstChild == pWin)
+	pPrev->firstChild = pWin->nextSib;
+    if (pPrev->lastChild == pWin)
+	pPrev->lastChild = pWin->prevSib;
+
+    if (pWin->nextSib)
+	pWin->nextSib->prevSib = pWin->prevSib;
+    if (pWin->prevSib)
+	pWin->prevSib->nextSib = pWin->nextSib;
+
+    /* insert at begining of pParent */
+    pWin->parent = pParent;
+    pPrev = RealChildHead(pParent);
+
+    if (pWin->parent == WindowTable[0])
+    {
+      nxagentSetTopLevelEventMask(pWin);
+    }
+ 
+    if (pPrev)
+    {
+	pWin->nextSib = pPrev->nextSib;
+	if (pPrev->nextSib)
+	    pPrev->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pPrev->nextSib = pWin;
+	pWin->prevSib = pPrev;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	pWin->prevSib = NullWindow;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.x = x + bw + pParent->drawable.x;
+    pWin->drawable.y = y + bw + pParent->drawable.y;
+
+    /* clip to parent */
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    if (pScreen->ReparentWindow)
+	(*pScreen->ReparentWindow)(pWin, pPriorParent);
+
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    CheckWindowOptionalNeed(pWin);
+
+    if (WasMapped)
+	MapWindow(pWin, client);
+    RecalculateDeliverableEvents(pWin);
+    return(Success);
+}
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+    register WindowPtr pChild;
+    RealizeWindowProcPtr Realize;
+
+    Realize = pWin->drawable.pScreen->RealizeWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->mapped)
+	{
+	    pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder)
+		deltaSaveUndersViewable++;
+#endif
+	    pChild->viewable = (pChild->drawable.class == InputOutput);
+	    (* Realize)(pChild);
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * MapWindow
+ *    If some other client has selected SubStructureReDirect on the parent
+ *    and override-redirect is xFalse, then a MapRequest event is generated,
+ *    but the window remains unmapped.	Otherwise, the window is mapped and a
+ *    MapNotify event is generated.
+ *****/
+
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+    register ScreenPtr pScreen;
+
+    register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+    }
+    #endif
+
+    if (pWin->mapped)
+	return(Success);
+
+#ifdef XCSECURITY
+    /*  don't let an untrusted client map a child-of-trusted-window, InputOnly
+     *  window; too easy to steal device input
+     */
+    if ( (client->trustLevel != XSecurityClientTrusted) &&
+	 (pWin->drawable.class == InputOnly) &&
+	 (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+	 return Success;
+#endif	
+
+    pScreen = pWin->drawable.pScreen;
+    if ( (pParent = pWin->parent) )
+    {
+	xEvent event;
+	Bool anyMarked;
+#ifdef XAPPGROUP
+	ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+	ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+	if ((!pWin->overrideRedirect) && 
+	    (RedirectSend(pParent)
+#ifdef XAPPGROUP
+	    || (win_owner->appgroup && ag_leader &&
+		XagIsControlledRoot (client, pParent))
+#endif
+	))
+	{
+	    event.u.u.type = MapRequest;
+	    event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+	    /* make sure if the ag_leader maps the window it goes to the wm */
+	    if (ag_leader && ag_leader != client &&
+		XagIsControlledRoot (client, pParent)) {
+		event.u.mapRequest.parent = XagId (win_owner);
+		(void) TryClientEvents (ag_leader, &event, 1,
+					NoEventMask, NoEventMask, NullGrab);
+		return Success;
+	    }
+#endif
+	    event.u.mapRequest.parent = pParent->drawable.id;
+
+	    if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+		return(Success);
+	}
+
+	pWin->mapped = TRUE;
+	if (SubStrSend(pWin, pParent))
+	{
+	    event.u.u.type = MapNotify;
+	    event.u.mapNotify.window = pWin->drawable.id;
+	    event.u.mapNotify.override = pWin->overrideRedirect;
+	    DeliverEvents(pWin, &event, 1, NullWindow);
+	}
+
+	if (!pParent->realized)
+	    return(Success);
+	RealizeTree(pWin);
+	if (pWin->viewable)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+	    if (DO_SAVE_UNDERS(pWin))
+	    {
+		dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+#endif /* DO_SAVE_UNDERS */
+	    if (anyMarked)
+	    {
+		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+		(*pScreen->HandleExposures)(pLayerWin->parent);
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (dosave)
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+	}
+	WindowsRestructured ();
+    }
+    else
+    {
+	RegionRec   temp;
+
+	pWin->mapped = TRUE;
+	pWin->realized = TRUE;	   /* for roots */
+	pWin->viewable = pWin->drawable.class == InputOutput;
+	/* We SHOULD check for an error value here XXX */
+	(*pScreen->RealizeWindow)(pWin);
+	if (pScreen->ClipNotify)
+	    (*pScreen->ClipNotify) (pWin, 0, 0);
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+	REGION_NULL(pScreen, &temp);
+	REGION_COPY(pScreen, &temp, &pWin->clipList);
+	(*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+	REGION_UNINIT(pScreen, &temp);
+    }
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ *    Performs a MapWindow all unmapped children of the window, in top
+ *    to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+    register WindowPtr	pWin;
+    WindowPtr		pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+    WindowPtr		pFirstSaveUndered = NullWindow;
+#endif
+    register ScreenPtr	pScreen;
+    register Mask	parentRedirect;
+    register Mask	parentNotify;
+    xEvent		event;
+    Bool		anyMarked;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr		pLayerWin;
+
+    pScreen = pParent->drawable.pScreen;
+    parentRedirect = RedirectSend(pParent);
+    parentNotify = SubSend(pParent);
+    anyMarked = FALSE;
+    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+    {
+	if (!pWin->mapped)
+	{
+	    if (parentRedirect && !pWin->overrideRedirect)
+	    {
+		event.u.u.type = MapRequest;
+		event.u.mapRequest.window = pWin->drawable.id;
+		event.u.mapRequest.parent = pParent->drawable.id;
+    
+		if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		    SubstructureRedirectMask, client) == 1)
+		    continue;
+	    }
+    
+	    pWin->mapped = TRUE;
+	    if (parentNotify || StrSend(pWin))
+	    {
+		event.u.u.type = MapNotify;
+		event.u.mapNotify.window = pWin->drawable.id;
+		event.u.mapNotify.override = pWin->overrideRedirect;
+		DeliverEvents(pWin, &event, 1, NullWindow);
+	    }
+    
+	    if (!pFirstMapped)
+		pFirstMapped = pWin;
+	    if (pParent->realized)
+	    {
+		RealizeTree(pWin);
+		if (pWin->viewable)
+		{
+		    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							(WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave = TRUE;
+		    }
+#endif /* DO_SAVE_UNDERS */
+		}
+	    }
+	}
+    }
+
+    if (pFirstMapped)
+    {
+	pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+	if (pLayerWin->parent != pParent) {
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+							   pLayerWin,
+							   (WindowPtr *)NULL);
+	    pFirstMapped = pLayerWin;
+	}
+        if (anyMarked)
+        {
+#ifdef DO_SAVE_UNDERS
+	    if (pLayerWin->parent != pParent)
+	    {
+		if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+		{
+		    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+							 pLayerWin);
+		}
+	    }
+	    else if (dosave)
+	    {
+		dosave = FALSE;
+		for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+		{
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+							      pWin->nextSib);
+			if (dosave && !pFirstSaveUndered)
+			    pFirstSaveUndered = pWin;
+		    }
+		}
+            }
+#endif /* DO_SAVE_UNDERS */
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+        if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin,
+					    pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+        if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+					 VTMap);
+        WindowsRestructured ();
+    }
+}
+
+static void
+UnrealizeTree(
+    WindowPtr pWin,
+    Bool fromConfigure)
+{
+    register WindowPtr pChild;
+    UnrealizeWindowProcPtr Unrealize;
+    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->realized)
+	{
+	    pChild->realized = FALSE;
+	    pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+		PanoramiXRes *win;
+		win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+							XRT_WINDOW);
+		if(win)
+		   win->u.win.visibility = VisibilityNotViewable;
+	    } 
+#endif
+	    (* Unrealize)(pChild);
+	    DeleteWindowFromAnyEvents(pChild, FALSE);
+	    if (pChild->viewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		if (pChild->saveUnder)
+		    deltaSaveUndersViewable--;
+#endif
+		pChild->viewable = FALSE;
+		if (pChild->backStorage)
+		    (*pChild->drawable.pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+		(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+		pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    }
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * UnmapWindow
+ *    If the window is already unmapped, this request has no effect.
+ *    Otherwise, the window is unmapped and an UnMapNotify event is
+ *    generated.  Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+    register WindowPtr pParent;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
+                  fromConfigure);
+    }
+    #endif
+
+    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+	return(Success);
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = UnmapNotify;
+	event.u.unmapNotify.window = pWin->drawable.id;
+	event.u.unmapNotify.fromConfigure = fromConfigure;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (wasViewable && !fromConfigure)
+    {
+	pWin->valdata = UnmapValData;
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+	(*pScreen->MarkWindow)(pLayerWin->parent);
+    }
+    pWin->mapped = FALSE;
+    if (wasRealized)
+	UnrealizeTree(pWin, fromConfigure);
+    if (wasViewable)
+    {
+	if (!fromConfigure)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+	    {
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+	}
+	pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+	if (!fromConfigure && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+    }
+    if (wasRealized && !fromConfigure)
+	WindowsRestructured ();
+    return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ *    Performs an UnmapWindow request with the specified mode on all mapped
+ *    children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+    register WindowPtr pChild, pHead;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    Bool anyMarked = FALSE;
+    Mask parentNotify;
+    WindowPtr pLayerWin = NULL;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!pWin->firstChild)
+	return;
+    parentNotify = SubSend(pWin);
+    pHead = RealChildHead(pWin);
+
+    if (wasViewable)
+	pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+	if (pChild->mapped)
+	{
+	    if (parentNotify || StrSend(pChild))
+	    {
+		event.u.u.type = UnmapNotify;
+		event.u.unmapNotify.window = pChild->drawable.id;
+		event.u.unmapNotify.fromConfigure = xFalse;
+		DeliverEvents(pChild, &event, 1, NullWindow);
+	    }
+	    if (pChild->viewable)
+	    {
+		pChild->valdata = UnmapValData;
+		anyMarked = TRUE;
+	    }
+	    pChild->mapped = FALSE;
+	    if (pChild->realized)
+		UnrealizeTree(pChild, FALSE);
+	    if (wasViewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+		if (pChild->backStorage)
+		    (*pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+	    }
+	}
+    }
+    if (wasViewable)
+    {
+	if (anyMarked)
+	{
+	    if (pLayerWin->parent == pWin)
+		(*pScreen->MarkWindow)(pWin);
+	    else
+	    {
+		WindowPtr ptmp;
+                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						  (WindowPtr *)NULL);
+		(*pScreen->MarkWindow)(pLayerWin->parent);
+		
+		/* Windows between pWin and pLayerWin may not have been marked */
+		ptmp = pWin;
+ 
+		while (ptmp != pLayerWin->parent)
+		{
+		    (*pScreen->MarkWindow)(ptmp);
+		    ptmp = ptmp->parent;
+		}
+                pHead = pWin->firstChild;
+	    }
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+    }
+    if (wasRealized)
+	WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+    register WindowPtr pParent, pWin;
+    register int j;
+
+    for (j=0; j<client->numSaved; j++)
+    {
+	pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+	if (SaveSetToRoot(client->saveSet[j]))
+	    pParent = WindowTable[pWin->drawable.pScreen->myNum];
+	else
+#endif
+	{
+	    pParent = pWin->parent;
+	    while (pParent && (wClient (pParent) == client))
+		pParent = pParent->parent;
+	}
+	if (pParent)
+	{
+	    if (pParent != pWin->parent)
+	    {
+		ReparentWindow(pWin, pParent,
+			       pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+			       pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+			       client);
+		if(!pWin->realized && pWin->mapped)
+		    pWin->mapped = FALSE;
+	    }
+#ifdef XFIXES
+	    if (SaveSetRemap (client->saveSet[j]))
+#endif
+		MapWindow(pWin, client);
+	}
+    }
+    xfree(client->saveSet);
+    client->numSaved = 0;
+    client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ *  \param x,y  in root
+ *  \param box  "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+	return(TRUE);
+    return(FALSE);
+}
+
+/**
+ *
+ * \param x,y  in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+						  x, y, &box)
+	&& (!wInputShape(pWin) ||
+	    POINT_IN_REGION(pWin->drawable.pScreen,
+			    wInputShape(pWin),
+			    x - pWin->drawable.x, 
+			    y - pWin->drawable.y, &box)))
+	return(TRUE);
+    return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+    register ScreenPtr pScreen;
+    RegionPtr pReg;
+
+    pScreen = pWin->drawable.pScreen;
+    pReg = REGION_CREATE(pScreen, NullBox, 1);
+    if (pWin->parent ||
+	screenIsSaved != SCREEN_SAVER_ON ||
+	!HasSaverWindow (pWin->drawable.pScreen->myNum))
+    {
+	REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+    }
+    return(pReg);
+}
+
+void
+SendVisibilityNotify(WindowPtr pWin)
+{
+    xEvent event;
+#ifndef NO_XINERAMA_PORT
+    unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+    /* This is not quite correct yet, but it's close */
+    if(!noPanoramiXExtension) {
+	PanoramiXRes *win;
+	WindowPtr pWin2;
+	int i, Scrnum;
+
+	Scrnum = pWin->drawable.pScreen->myNum;
+	
+	win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+	if(!win || (win->u.win.visibility == visibility))
+	    return;
+
+	switch(visibility) {
+	case VisibilityUnobscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+		if (pWin2) {
+		    if(pWin2->visibility == VisibilityPartiallyObscured)
+		   	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	case VisibilityPartiallyObscured:
+	    if(Scrnum) {
+	        pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+		if (pWin2) pWin = pWin2;
+	    }
+	    break;
+	case VisibilityFullyObscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+		
+		if (pWin2) {
+		    if(pWin2->visibility != VisibilityFullyObscured)
+		    	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	}
+	
+	win->u.win.visibility = visibility;
+    }
+#endif
+
+    event.u.u.type = VisibilityNotify;
+    event.u.visibility.window = pWin->drawable.id;
+    event.u.visibility.state = visibility;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+    WindowPtr pWin
+);
+#endif
+
+void
+SaveScreens(int on, int mode)
+{
+    int i;
+    int what;
+    int type;
+
+    if (on == SCREEN_SAVER_FORCER)
+    {
+	UpdateCurrentTimeIf();
+	lastDeviceEventTime = currentTime;
+	if (mode == ScreenSaverReset)
+	    what = SCREEN_SAVER_OFF;
+	else
+	    what = SCREEN_SAVER_ON;
+	type = what;
+    }
+    else
+    {
+	what = on;
+	type = what;
+	if (what == screenIsSaved)
+	    type = SCREEN_SAVER_CYCLE;
+    }
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+	if (on == SCREEN_SAVER_FORCER)
+	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+	if (savedScreenInfo[i].ExternalScreenSaver)
+	{
+          if (nxagentOption(Timeout) != 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
+                        "Ignoring it to let the auto-disconnect feature work.\n");
+            #endif
+          }
+          else
+          {
+	      if ((*savedScreenInfo[i].ExternalScreenSaver)
+		  (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+		  continue;
+          }
+	}
+	if (type == screenIsSaved)
+	    continue;
+	switch (type) {
+	case SCREEN_SAVER_OFF:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+	       (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						      what);
+	    }
+	    else if (HasSaverWindow (i))
+	    {
+		savedScreenInfo[i].pWindow = NullWindow;
+		FreeResource(savedScreenInfo[i].wid, RT_NONE);
+	    }
+	    break;
+	case SCREEN_SAVER_CYCLE:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+	    {
+		WindowPtr pWin = savedScreenInfo[i].pWindow;
+		/* make it look like screen saver is off, so that
+		 * NotClippedByChildren will compute a clip list
+		 * for the root window, so miPaintWindow works
+		 */
+		screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+		(*pWin->drawable.pScreen->MoveWindow)(pWin,
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    DrawLogo(pWin);
+#endif
+		screenIsSaved = SCREEN_SAVER_ON;
+	    }
+	    /*
+	     * Call the DDX saver in case it wants to do something
+	     * at cycle time
+	     */
+	    else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+		(* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						       type);
+	    }
+	    break;
+	case SCREEN_SAVER_ON:
+	    if (ScreenSaverBlanking != DontPreferBlanking)
+	    {
+		if ((* screenInfo.screens[i]->SaveScreen)
+		   (screenInfo.screens[i], what))
+		{
+		   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+		   continue;
+		}
+		if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		    TileScreenSaver(i, SCREEN_IS_BLACK))
+		{
+		    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+		    continue;
+		}
+	    }
+	    if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		TileScreenSaver(i, SCREEN_IS_TILED))
+	    {
+		savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+	    }
+	    else
+		savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+	    break;
+	}
+    }
+    screenIsSaved = what;
+    if (mode == ScreenSaverReset)
+       SetScreenSaverTimer();
+}
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+    int j;
+    int result;
+    XID attributes[3];
+    Mask mask;
+    WindowPtr pWin;		
+    CursorMetricRec cm;
+    unsigned char *srcbits, *mskbits;
+    CursorPtr cursor;
+    XID	cursorID = 0;
+    int	attri;
+
+    mask = 0;
+    attri = 0;
+    switch (kind) {
+    case SCREEN_IS_TILED:
+	switch (WindowTable[i]->backgroundState) {
+	case BackgroundPixel:
+	    attributes[attri++] = WindowTable[i]->background.pixel;
+	    mask |= CWBackPixel;
+	    break;
+	case BackgroundPixmap:
+	    attributes[attri++] = None;
+	    mask |= CWBackPixmap;
+	    break;
+	default:
+	    break;
+	}
+	break;
+    case SCREEN_IS_BLACK:
+	attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+	mask |= CWBackPixel;
+	break;
+    }
+    mask |= CWOverrideRedirect;
+    attributes[attri++] = xTrue;
+
+    /*
+     * create a blank cursor
+     */
+
+    cm.width=16;
+    cm.height=16;
+    cm.xhot=8;
+    cm.yhot=8;
+    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    if (!srcbits || !mskbits)
+    {
+	xfree(srcbits);
+	xfree(mskbits);
+	cursor = 0;
+    }
+    else
+    {
+	for (j=0; j<BitmapBytePad(32)*16; j++)
+	    srcbits[j] = mskbits[j] = 0x0;
+	cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+	if (cursor)
+	{
+	    cursorID = FakeClientID(0);
+	    if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+	    {
+		attributes[attri] = cursorID;
+		mask |= CWCursor;
+	    }
+	    else
+		cursor = 0;
+	}
+	else
+	{
+	    xfree (srcbits);
+	    xfree (mskbits);
+	}
+    }
+
+    pWin = savedScreenInfo[i].pWindow =
+	 CreateWindow(savedScreenInfo[i].wid,
+	      WindowTable[i],
+	      -RANDOM_WIDTH, -RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+	      0, InputOutput, mask, attributes, 0, serverClient,
+	      wVisual (WindowTable[i]), &result);
+
+    if (cursor)
+	FreeResource (cursorID, RT_NONE);
+
+    if (!pWin)
+	return FALSE;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW,
+		     (pointer)savedScreenInfo[i].pWindow))
+	return FALSE;
+
+    if (mask & CWBackPixmap)
+    {
+	MakeRootTile (pWin);
+	(*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+    }
+    MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+    if (kind == SCREEN_IS_TILED && logoScreenSaver)
+	DrawLogo(pWin);
+#endif
+    return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure.  Assumptions:	 some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+    do
+	w = w->parent;
+    while (!w->optional);
+    return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules.	 If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (!w->parent)
+	return;
+    optional = w->optional;
+    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+	return;
+    if (optional->otherEventMasks != 0)
+	return;
+    if (optional->otherClients != NULL)
+	return;
+    if (optional->passiveGrabs != NULL)
+	return;
+    if (optional->userProps != NULL)
+	return;
+    if (optional->backingBitPlanes != ~0L)
+	return;
+    if (optional->backingPixel != 0)
+	return;
+#ifdef SHAPE
+    if (optional->boundingShape != NULL)
+	return;
+    if (optional->clipShape != NULL)
+	return;
+    if (optional->inputShape != NULL)
+	return;
+#endif
+#ifdef XINPUT
+    if (optional->inputMasks != NULL)
+	return;
+#endif
+    parentOptional = FindWindowWithOptional(w)->optional;
+    if (optional->visual != parentOptional->visual)
+	return;
+    if (optional->cursor != None &&
+	(optional->cursor != parentOptional->cursor ||
+	 w->parent->cursorIsNone))
+	return;
+    if (optional->colormap != parentOptional->colormap)
+	return;
+    DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (pWin->optional)
+	return TRUE;
+    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+    if (!optional)
+	return FALSE;
+    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+    optional->otherEventMasks = 0;
+    optional->otherClients = NULL;
+    optional->passiveGrabs = NULL;
+    optional->userProps = NULL;
+    optional->backingBitPlanes = ~0L;
+    optional->backingPixel = 0;
+#ifdef SHAPE
+    optional->boundingShape = NULL;
+    optional->clipShape = NULL;
+    optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+    optional->inputMasks = NULL;
+#endif
+    parentOptional = FindWindowWithOptional(pWin)->optional;
+    optional->visual = parentOptional->visual;
+    if (!pWin->cursorIsNone)
+    {
+	optional->cursor = parentOptional->cursor;
+	optional->cursor->refcnt++;
+    }
+    else
+    {
+	optional->cursor = None;
+    }
+    optional->colormap = parentOptional->colormap;
+    pWin->optional = optional;
+    return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+    if (!pWin->optional)
+	return;
+    /*
+     * everything is peachy.  Delete the optional record
+     * and clean up
+     */
+    /*
+     * TOG changed this code to:
+     *
+     *	    if (pWin->cursorIsNone == FALSE)
+     *		FreeCursor (pWin->optional->cursor, (Cursor)0);
+     *	    pWin->cursorIsNone = TRUE;
+     *
+     * This is blatently wrong; windows without optionals can have
+     * two different cursor values, either None or sharing their
+     * parents cursor.  This difference is controlled by the
+     * cursorIsNone value; when TRUE, the window has no cursor,
+     * when false, it shares its cursor with its parent; TOG
+     * made it impossible for a window to have a cursor without
+     * an optional record.
+     */
+    if (pWin->optional->cursor)
+    {
+	FreeCursor (pWin->optional->cursor, (Cursor)0);
+	pWin->cursorIsNone = FALSE;
+    }
+    else
+	pWin->cursorIsNone = TRUE;
+/* FIXME
+   There is an error when disposing ClientResources on Agent exit
+   this xfree is not valid in some window at exit
+*/
+
+    xfree (pWin->optional);
+    pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+    DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    int x, y;
+    unsigned int width, height, size;
+    GC *pGC;
+    int thin, gap, d31;
+    DDXPointRec poly[4];
+    ChangeGCVal fore[2], back[2];
+    xrgb rgb[2];
+    BITS32 fmask, bmask;
+    ColormapPtr cmap;
+
+    pDraw = (DrawablePtr)pWin;
+    pScreen = pDraw->pScreen;
+    x = -pWin->origin.x;
+    y = -pWin->origin.y;
+    width = pScreen->width;
+    height = pScreen->height;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pGC)
+	return;
+
+    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+	fore[0].val = pScreen->whitePixel;
+    else
+	fore[0].val = pScreen->blackPixel;
+    if ((pWin->backgroundState == BackgroundPixel) &&
+	(cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+	Pixel querypixels[2];
+
+	querypixels[0] = fore[0].val;
+	querypixels[1] = pWin->background.pixel;
+	QueryColors(cmap, 2, querypixels, rgb);
+	if ((rgb[0].red == rgb[1].red) &&
+	    (rgb[0].green == rgb[1].green) &&
+	    (rgb[0].blue == rgb[1].blue)) {
+	    if (fore[0].val == pScreen->blackPixel)
+		fore[0].val = pScreen->whitePixel;
+	    else
+		fore[0].val = pScreen->blackPixel;
+	}
+    }
+    fore[1].val = FillSolid;
+    fmask = GCForeground|GCFillStyle;
+    if (pWin->backgroundState == BackgroundPixel) {
+	back[0].val = pWin->background.pixel;
+	back[1].val = FillSolid;
+	bmask = GCForeground|GCFillStyle;
+    } else {
+	back[0].val = 0;
+	back[1].val = 0;
+	dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+		    NULL, back);
+	back[0].val = FillTiled;
+	back[1].ptr = pWin->background.pixmap;
+	bmask = GCFillStyle|GCTile;
+    }
+
+    /* should be the same as the reference function XmuDrawLogo() */
+
+    size = width;
+    if (height < width)
+	 size = height;
+    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+    size &= ~1;
+    x += rand() % (width - size);
+    y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ *           -----
+ *          /    /
+ *         /    /
+ *        /    /
+ *       /    /
+ *      /____/
+ *           d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+    thin = (size / 11);
+    if (thin < 1) thin = 1;
+    gap = (thin+3) / 4;
+    d31 = thin + thin + gap;
+    poly[0].x = x + size;	       poly[0].y = y;
+    poly[1].x = x + size-d31;	       poly[1].y = y;
+    poly[2].x = x + 0;		       poly[2].y = y + size;
+    poly[3].x = x + d31;	       poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ *           ------
+ *          /	  /
+ *         /  __ /
+ *        /  /	/
+ *       /  /  /
+ *      /__/__/
+ */
+
+    poly[0].x = x + d31/2;			 poly[0].y = y + size;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)+(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + d31;			 poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ *	     ------
+ *	    /  /  /
+ *	   /--/	 /
+ *	  /	/
+ *	 /     /
+ *	/_____/
+ */
+
+    poly[0].x = x + size - d31/2;		 poly[0].y = y;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)-(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + size - d31;			 poly[3].y = y;
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ *      b
+ * -----
+ * \	\
+ *  \	 \
+ *   \	  \
+ *    \	   \
+ *     \____\
+ */
+
+    poly[0].x = x;		       poly[0].y = y;
+    poly[1].x = x + size/4;	       poly[1].y = y;
+    poly[2].x = x + size;	       poly[2].y = y + size;
+    poly[3].x = x + size - size/4;     poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ *	    /
+ *	   /
+ *	  /
+ *	 /
+ *	/
+ */
+
+    poly[0].x = x + size- thin;	      poly[0].y = y;
+    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
+    poly[2].x = x + thin;	      poly[2].y = y + size;
+    poly[3].x = x + thin + gap;	      poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+    FreeScratchGC(pGC);
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
new file mode 100644
index 000000000..7ba468ac0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -0,0 +1,4174 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.12 2005/07/03 08:53:38 daniels Exp $ */
+/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+/*
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+			All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.36 2003/11/14 23:52:50 torrey Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#include "selection.h"
+#ifdef PANORAMIX
+#include "../../Xext/panoramiX.h"
+#include "../../Xext/panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+#include "Screen.h"
+#include "Options.h"
+#include "Atoms.h"
+#include "Clipboard.h"
+#include "Splash.h"
+#include "Rootless.h"
+#include "Composite.h"
+#include "Drawable.h"
+#include "Colormap.h"
+
+extern Bool nxagentWMIsRunning;
+extern Bool nxagentScreenTrap;
+
+/******
+ * Window stuff for server 
+ *
+ *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+			      CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+      (!( ((b1)->x2 <= (b2)->x1)  || \
+	( ((b1)->x1 >= (b2)->x2)) || \
+	( ((b1)->y2 <= (b2)->y1)) || \
+	( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+/*
+ * Set here the required log level.
+ */
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+WindowPtr nxagentRootTileWindow;
+
+/*
+ * This block used the DEBUG symbol.
+ */
+
+#ifdef WINDOW_TREE_DEBUG
+/******
+ * PrintWindowTree
+ *    For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+    WindowPtr p2;
+    int i;
+
+    while (p1)
+    {
+	p2 = p1->firstChild;
+	for (i=0; i<indent; i++) ErrorF( " ");
+	ErrorF( "%x\n", p1->drawable.id);
+	miPrintRegion(&p1->clipList);
+	PrintChildren(p2, indent+4);
+	p1 = p1->nextSib;
+    }
+}
+
+PrintWindowTree()
+{
+    int i;
+    WindowPtr pWin, p1;
+
+    for (i=0; i<screenInfo.numScreens; i++)
+    {
+	ErrorF( "WINDOW %d\n", i);
+	pWin = WindowTable[i];
+	miPrintRegion(&pWin->clipList);
+	p1 = pWin->firstChild;
+	PrintChildren(p1, 4);
+    }
+}
+#endif
+
+int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+{
+    register int result;
+    register WindowPtr pChild;
+
+    if (!(pChild = pWin))
+       return(WT_NOMATCH);
+    while (1)
+    {
+	result = (* func)(pChild, data);
+	if (result == WT_STOPWALKING)
+	    return(WT_STOPWALKING);
+	if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+    return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
+ *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
+ *   exit WalkTree.  Does depth-first traverse.
+ *****/
+
+int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+{
+    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int	defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool	disableBackingStore = FALSE;
+Bool	enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool	disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+    pWin->prevSib = NullWindow;
+    pWin->firstChild = NullWindow;
+    pWin->lastChild = NullWindow;
+
+    pWin->valdata = (ValidatePtr)NULL;
+    pWin->optional = (WindowOptPtr)NULL;
+    pWin->cursorIsNone = TRUE;
+
+    pWin->backingStore = NotUseful;
+    pWin->DIXsaveUnder = FALSE;
+    pWin->backStorage = (pointer) NULL;
+
+    pWin->mapped = FALSE;	    /* off */
+    pWin->realized = FALSE;	/* off */
+    pWin->viewable = FALSE;
+    pWin->visibility = VisibilityNotViewable;
+    pWin->overrideRedirect = FALSE;
+    pWin->saveUnder = FALSE;
+
+    pWin->bitGravity = ForgetGravity;
+    pWin->winGravity = NorthWestGravity;
+
+    pWin->eventMask = 0;
+    pWin->deliverableEvents = 0;
+    pWin->dontPropagate = 0;
+    pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+    pWin->srcBuffer = DBE_FRONT_BUFFER;
+    pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+    pWin->redirectDraw = 0;
+#endif
+}
+
+#ifdef NXAGENT_SERVER
+
+void nxagentClearSplash(WindowPtr pW)
+{
+    int w, h;
+    ScreenPtr pScreen;
+
+    w = pW->drawable.width;
+    h = pW->drawable.height;
+
+    pScreen = pW->drawable.pScreen;
+
+    if (pW->backgroundState == BackgroundPixmap)
+    {
+      (*pScreen->DestroyPixmap)(pW->background.pixmap);
+    }
+
+    pW->backgroundState = BackgroundPixel;
+    pW->background.pixel = nxagentLogoBlack;
+
+    (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
+}
+
+static void
+#if NeedFunctionPrototypes
+MakeRootTile(WindowPtr pWin)
+#else
+MakeRootTile(pWin)
+    WindowPtr pWin;
+#endif
+{
+    nxagentRootTileWindow = pWin;
+}
+
+#else /* NXAGENT_SERVER */
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    GCPtr pGC;
+    unsigned char back[128];
+    int len = BitmapBytePad(sizeof(long));
+    register unsigned char *from, *to;
+    register int i, j;
+
+    pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+						    pScreen->rootDepth);
+
+    pWin->backgroundState = BackgroundPixmap;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pWin->background.pixmap || !pGC)
+	FatalError("could not create root tile");
+
+    {
+	CARD32 attributes[2];
+
+	attributes[0] = pScreen->whitePixel;
+	attributes[1] = pScreen->blackPixel;
+
+	(void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+    }
+
+   ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+   from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+   to = back;
+
+   for (i = 4; i > 0; i--, from++)
+	for (j = len; j > 0; j--)
+	    *to++ = *from;
+
+   if (blackRoot)
+       bzero(back, sizeof(back));
+
+   (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+		    0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+   FreeScratchGC(pGC);
+
+}
+
+#endif /* NXAGENT_SERVER */
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+    WindowPtr pWin;
+    register char *ptr;
+    register DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+    if (pWin)
+    {
+	ppriv = (DevUnion *)(pWin + 1);
+	pWin->devPrivates = ppriv;
+	sizes = pScreen->WindowPrivateSizes;
+	ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+	for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+	{
+	    if ( (size = *sizes) )
+	    {
+		ppriv->ptr = (pointer)ptr;
+		ptr += size;
+	    }
+	    else
+		ppriv->ptr = (pointer)NULL;
+	}
+    }
+    return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ *    Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+    WindowPtr	pWin;
+    BoxRec	box;
+    PixmapFormatRec *format;
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+	return FALSE;
+
+    savedScreenInfo[pScreen->myNum].pWindow = NULL;
+    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+    screenIsSaved = SCREEN_SAVER_OFF;
+
+    WindowTable[pScreen->myNum] = pWin;
+
+    pWin->drawable.pScreen = pScreen;
+    pWin->drawable.type = DRAWABLE_WINDOW;
+
+    pWin->drawable.depth = pScreen->rootDepth;
+    for (format = screenInfo.formats;
+	 format->depth != pScreen->rootDepth;
+	 format++)
+	;
+    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->parent = NullWindow;
+    SetWindowToDefaults(pWin);
+
+    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+    if (!pWin->optional)
+        return FALSE;
+
+    pWin->optional->dontPropagateMask = 0;
+    pWin->optional->otherEventMasks = 0;
+    pWin->optional->otherClients = NULL;
+    pWin->optional->passiveGrabs = NULL;
+    pWin->optional->userProps = NULL;
+    pWin->optional->backingBitPlanes = ~0L;
+    pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+    pWin->optional->boundingShape = NULL;
+    pWin->optional->clipShape = NULL;
+    pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+    pWin->optional->inputMasks = NULL;
+#endif
+    pWin->optional->colormap = pScreen->defColormap;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->nextSib = NullWindow;
+
+    pWin->drawable.id = FakeClientID(0);
+
+    pWin->origin.x = pWin->origin.y = 0;
+    pWin->drawable.height = pScreen->height;
+    pWin->drawable.width = pScreen->width;
+    pWin->drawable.x = pWin->drawable.y = 0;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+    pWin->drawable.class = InputOutput;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->backgroundState = BackgroundPixel;
+    pWin->background.pixel = pScreen->whitePixel;
+
+    pWin->borderIsPixel = TRUE;
+    pWin->border.pixel = pScreen->blackPixel;
+    pWin->borderWidth = 0;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+	return FALSE;
+
+    if (disableBackingStore)
+    {
+      pScreen -> backingStoreSupport = NotUseful;
+    }
+
+    if (enableBackingStore)
+    {
+      pScreen -> backingStoreSupport = Always;
+    }
+
+    pScreen->saveUnderSupport = False;
+
+#ifdef DO_SAVE_UNDERS
+    if ((pScreen->backingStoreSupport != NotUseful) &&
+	(pScreen->saveUnderSupport == NotUseful))
+    {
+	/*
+	 * If the screen has backing-store but no save-unders, let the
+	 * clients know we can support save-unders using backing-store.
+	 */
+	pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+    }
+#endif /* DO_SAVE_UNDERS */
+		
+    if (disableSaveUnders)
+	pScreen->saveUnderSupport = NotUseful;
+
+    return TRUE;
+}
+
+#ifdef NXAGENT_SERVER
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen;
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Called for window at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (nxagentOption(Rootless))
+    {
+      #ifdef TEST
+      fprintf(stderr, "InitRootWindow: Assigned agent root to window at [%p][%ld] with parent [%p].\n",
+                  (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+      #endif
+
+      nxagentRootlessWindow = pWin;
+    }
+
+    pScreen = pWin->drawable.pScreen;
+
+    /*
+     * A root window is created for each screen by main
+     * and the pointer is saved in WindowTable as in the
+     * following snippet:
+     *
+     * for (i = 0; i < screenInfo.numScreens; i++)
+     *          InitRootWindow(WindowTable[i]);
+     *
+     * Our root window on the real display was already
+     * created at the time the screen was opened, so it
+     * is unclear how this window (or the other window,
+     * if you prefer) fits in the big picture.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Going to create window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Created window as root at [%p][%ld] with parent [%p].\n",
+                (void *) pWin, nxagentWindowPriv(pWin)->window, (void *) pWin -> parent);
+    #endif
+
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+
+    #ifdef NXAGENT_SPLASH
+    /* We SHOULD check for an error value here XXX */
+    pWin -> background.pixel = pScreen -> blackPixel;
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixel|CWBorderPixel|CWCursor|CWBackingStore);
+    #else
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+    #endif
+
+    MakeRootTile(pWin);
+
+    /*
+     * Map both the root and the default agent window.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "InitRootWindow: Mapping default windows.\n");
+    #endif
+
+    nxagentInitAtoms(pWin);
+
+    nxagentInitClipboard(pWin);
+
+    nxagentMapDefaultWindows();
+
+    nxagentRedirectDefaultWindows();
+
+    #ifdef NXAGENT_ARTSD
+    {
+      char artsd_port[10];
+      int nPort;
+      extern void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
+      nPort = atoi(display) + 7000;
+      sprintf(artsd_port,"%d", nPort);
+      nxagentPropagateArtsdProperties(pScreen, artsd_port);
+    }
+    #endif
+}
+
+#else /* NXAGENT_SERVER */
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    MakeRootTile(pWin);
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+    MapWindow(pWin, serverClient);
+}
+
+#endif /* NXAGENT_SERVER */
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize.  The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+                     register int x, register int y,
+                     register int w, register int h)
+{
+#ifndef NXAGENT_SERVER
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+    BoxRec box;
+
+    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+    /* we do these calculations to avoid overflows */
+    if (x > box.x1)
+	box.x1 = x;
+    if (y > box.y1)
+	box.y1 = y;
+    x += w;
+    if (x < box.x2)
+	box.x2 = x;
+    y += h;
+    if (y < box.y2)
+	box.y2 = y;
+    if (box.x1 > box.x2)
+	box.x2 = box.x1;
+    if (box.y1 > box.y2)
+	box.y2 = box.y1;
+    REGION_RESET(pScreen, Rgn, &box);
+    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+    if (!pWin->parent &&
+	(screenIsSaved == SCREEN_SAVER_ON) &&
+	(HasSaverWindow (pWin->drawable.pScreen->myNum)))
+	return (pWin->firstChild);
+    else
+	return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ *    Makes a window in response to client request 
+ *****/
+
+WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+             unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+             int depth, ClientPtr client, VisualID visual, int *error)
+{
+    register WindowPtr pWin;
+    WindowPtr pHead;
+    register ScreenPtr pScreen;
+    xEvent event;
+    int idepth, ivisual;
+    Bool fOK;
+    DepthPtr pDepth;
+    PixmapFormatRec *format;
+    register WindowOptPtr ancwopt;
+
+    if (class == CopyFromParent)
+	class = pParent->drawable.class;
+
+    if ((class != InputOutput) && (class != InputOnly))
+    {
+	*error = BadValue;
+	client->errorValue = class;
+	return NullWindow;
+    }
+
+    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pScreen = pParent->drawable.pScreen;
+    if ((class == InputOutput) && (depth == 0))
+	 depth = pParent->drawable.depth;
+    ancwopt = pParent->optional;
+    if (!ancwopt)
+	ancwopt = FindWindowWithOptional(pParent)->optional;
+    if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+	VisualID ag_visual;
+
+	if (client->appgroup && !pParent->parent &&
+	    (ag_visual = XagRootVisual (client)))
+	    visual = ag_visual;
+	else
+#endif
+	visual = ancwopt->visual;
+    }
+
+    /* Find out if the depth and visual are acceptable for this Screen */
+    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+    {
+	fOK = FALSE;
+	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+	{
+	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+	    if ((depth == pDepth->depth) || (depth == 0))
+	    {
+		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+		{
+		    if (visual == pDepth->vids[ivisual])
+		    {
+			fOK = TRUE;
+			break;
+		    }
+		}
+	    }
+	}
+	if (fOK == FALSE)
+	{
+	    *error = BadMatch;
+	    return NullWindow;
+	}
+    }
+
+    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+	(class != InputOnly) &&
+	(depth != pParent->drawable.depth))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if (((vmask & CWColormap) == 0) &&
+	(class != InputOnly) &&
+	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+    {
+	*error = BadAlloc;
+	return NullWindow;
+    }
+    pWin->drawable = pParent->drawable;
+    pWin->drawable.depth = depth;
+    if (depth == pParent->drawable.depth)
+	pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+    else
+    {
+	for (format = screenInfo.formats; format->depth != depth; format++)
+	    ;
+	pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+    }
+    if (class == InputOnly)
+	pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->drawable.id = wid;
+    pWin->drawable.class = class;
+
+    pWin->parent = pParent;
+    SetWindowToDefaults(pWin);
+
+    if (visual != ancwopt->visual)
+    {
+	if (!MakeWindowOptional (pWin))
+	{
+	    xfree (pWin);
+	    *error = BadAlloc;
+	    return NullWindow;
+	}
+	pWin->optional->visual = visual;
+	pWin->optional->colormap = None;
+    }
+
+    pWin->borderWidth = bw;
+#ifdef XCSECURITY
+    /*  can't let untrusted clients have background None windows;
+     *  they make it too easy to steal window contents
+     */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	pWin->backgroundState = BackgroundPixel;
+	pWin->background.pixel = 0;
+    }
+    else
+#endif
+    pWin->backgroundState = None;
+
+    pWin->borderIsPixel = pParent->borderIsPixel;
+    pWin->border = pParent->border;
+    if (pWin->borderIsPixel == FALSE)
+	pWin->border.pixmap->refcnt++;
+		
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    pWin->drawable.width = w;
+    pWin->drawable.height = h;
+    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+	/* set up clip list correctly for unobscured WindowPtr */
+    REGION_NULL(pScreen, &pWin->clipList);
+    REGION_NULL(pScreen, &pWin->borderClip);
+    REGION_NULL(pScreen, &pWin->winSize);
+    REGION_NULL(pScreen, &pWin->borderSize);
+
+    pHead = RealChildHead(pParent);
+    if (pHead)
+    {
+	pWin->nextSib = pHead->nextSib;
+	if (pHead->nextSib)
+	    pHead->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pHead->nextSib = pWin;
+	pWin->prevSib = pHead;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    /* We SHOULD check for an error value here XXX */
+    if (!(*pScreen->CreateWindow)(pWin))
+    {
+	*error = BadAlloc;
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    if (!(vmask & CWEventMask))
+	RecalculateDeliverableEvents(pWin);
+
+    if (vmask)
+	*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+    else
+	*error = Success;
+
+    if (*error != Success)
+    {
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+    {
+	XID value = defaultBackingStore;
+	(void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+	pWin->forcedBS = TRUE;
+    }
+
+    if (SubSend(pParent))
+    {
+	event.u.u.type = CreateNotify;
+	event.u.createNotify.window = wid;
+	event.u.createNotify.parent = pParent->drawable.id;
+	event.u.createNotify.x = x;
+	event.u.createNotify.y = y;
+	event.u.createNotify.width = w;
+	event.u.createNotify.height = h;
+	event.u.createNotify.borderWidth = bw;
+	event.u.createNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pParent, &event, 1, NullWindow);		
+    }
+    return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DeleteWindowFromAnySaveSet(pWin);
+    DeleteWindowFromAnySelections(pWin);
+    DeleteWindowFromAnyEvents(pWin, TRUE);
+    REGION_UNINIT(pScreen, &pWin->clipList);
+    REGION_UNINIT(pScreen, &pWin->winSize);
+    REGION_UNINIT(pScreen, &pWin->borderClip);
+    REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+    if (wBoundingShape (pWin))
+	REGION_DESTROY(pScreen, wBoundingShape (pWin));
+    if (wClipShape (pWin))
+	REGION_DESTROY(pScreen, wClipShape (pWin));
+    if (wInputShape (pWin))
+	REGION_DESTROY(pScreen, wInputShape (pWin));
+#endif
+    if (pWin->borderIsPixel == FALSE)
+	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+    if (pWin->backgroundState == BackgroundPixmap)
+	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+    DeleteAllWindowProperties(pWin);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->DestroyWindow)(pWin);
+    DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+    register WindowPtr pChild, pSib, pParent;
+    UnrealizeWindowProcPtr UnrealizeWindow;
+    xEvent event;
+
+    if (!(pChild = pWin->firstChild))
+	return;
+    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+    while (1)
+    {
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (1)
+	{
+	    pParent = pChild->parent;
+	    if (SubStrSend(pChild, pParent))
+	    {
+		event.u.u.type = DestroyNotify;
+		event.u.destroyNotify.window = pChild->drawable.id;
+		DeliverEvents(pChild, &event, 1, NullWindow);		
+	    }
+	    FreeResource(pChild->drawable.id, RT_WINDOW);
+	    pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder && pChild->viewable)
+		deltaSaveUndersViewable--;
+#endif
+	    pChild->viewable = FALSE;
+	    if (pChild->realized)
+	    {
+		pChild->realized = FALSE;
+		(*UnrealizeWindow)(pChild);
+	    }
+	    FreeWindowResources(pChild);
+	    xfree(pChild);
+	    if ( (pChild = pSib) )
+		break;
+	    pChild = pParent;
+	    pChild->firstChild = NullWindow;
+	    pChild->lastChild = NullWindow;
+	    if (pChild == pWin)
+		return;
+	}
+    }
+}
+	
+/*****
+ *  DeleteWindow
+ *	 Deletes child of window then window itself
+ *	 If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(pointer value, XID wid)
+ {
+    register WindowPtr pParent;
+    register WindowPtr pWin = (WindowPtr)value;
+    xEvent event;
+
+    UnmapWindow(pWin, FALSE);
+
+    CrushTree(pWin);
+
+    pParent = pWin->parent;
+    if (wid && pParent && SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = DestroyNotify;
+	event.u.destroyNotify.window = pWin->drawable.id;
+	DeliverEvents(pWin, &event, 1, NullWindow);		
+    }
+
+    FreeWindowResources(pWin);
+    if (pParent)
+    {
+	if (pParent->firstChild == pWin)
+	    pParent->firstChild = pWin->nextSib;
+	if (pParent->lastChild == pWin)
+	    pParent->lastChild = pWin->prevSib;
+	if (pWin->nextSib)
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	if (pWin->prevSib)
+	    pWin->prevSib->nextSib = pWin->nextSib;
+    }
+
+    if (pWin -> optional &&
+            pWin -> optional -> colormap &&
+                pWin -> parent)
+    {
+      nxagentSetInstalledColormapWindows(pWin -> drawable.pScreen);
+    }
+
+    xfree(pWin);
+    return Success;
+}
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+    /* XXX
+     * The protocol is quite clear that each window should be
+     * destroyed in turn, however, unmapping all of the first
+     * eliminates most of the calls to ValidateTree.  So,
+     * this implementation is incorrect in that all of the
+     * UnmapNotifies occur before all of the DestroyNotifies.
+     * If you care, simply delete the call to UnmapSubwindows.
+     */
+    UnmapSubwindows(pWin);
+    while (pWin->lastChild)
+	FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+    ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ *  ChangeWindowAttributes
+ *   
+ *  The value-mask specifies which attributes are to be changed; the
+ *  value-list contains one value for each one bit in the mask, from least
+ *  to most significant bit in the mask.  
+ *****/
+ 
+int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+    register Mask index2;
+    register XID *pVlist;
+    PixmapPtr pPixmap;
+    Pixmap pixID;
+    CursorPtr pCursor, pOldCursor;
+    Cursor cursorID;
+    WindowPtr pChild;
+    Colormap cmap;
+    ColormapPtr	pCmap;
+    xEvent xE;
+    int result;
+    register ScreenPtr pScreen;
+    Mask vmaskCopy = 0;
+    register Mask tmask;
+    unsigned int val;
+    int error;
+    Bool checkOptional = FALSE;
+    Bool borderRelative = FALSE;
+    WindowPtr pLayerWin;
+
+    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+	return BadMatch;
+
+    error = Success;
+    pScreen = pWin->drawable.pScreen;
+    pVlist = vlist;
+    tmask = vmask;
+    while (tmask)
+    {
+	index2 = (Mask) lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBackPixmap:
+	    pixID = (Pixmap )*pVlist;
+	    pVlist++;
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pixID == None)
+	    {
+#ifdef XCSECURITY
+		/*  can't let untrusted clients have background None windows */
+		if (client->trustLevel == XSecurityClientTrusted)
+		{
+#endif
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = None;
+#ifdef XCSECURITY
+		}
+		else
+		{ /* didn't change the background to None, so don't tell ddx */
+		    index2 = 0; 
+		}
+#endif
+	    }
+	    else if (pixID == ParentRelative)
+	    {
+		if (pWin->parent &&
+		    pWin->drawable.depth != pWin->parent->drawable.depth)
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = ParentRelative;
+		borderRelative = TRUE;
+		/* Note that the parent's backgroundTile's refcnt is NOT
+		 * incremented. */
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+						RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap != (PixmapPtr) NULL)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->backgroundState == BackgroundPixmap)
+			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    pWin->backgroundState = BackgroundPixmap;
+		    pWin->background.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBackPixel:
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pWin->backgroundState == BackgroundPixmap)
+		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+	    pWin->backgroundState = BackgroundPixel;
+	    pWin->background.pixel = (CARD32 ) *pVlist;
+		   /* background pixel overrides background pixmap,
+		      so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBackPixmap;
+	    pVlist++;
+	    break;
+	  case CWBorderPixmap:
+	    pixID = (Pixmap ) *pVlist;
+	    pVlist++;
+	    if (pixID == CopyFromParent)
+	    {
+		if (!pWin->parent ||
+		    (pWin->drawable.depth != pWin->parent->drawable.depth))
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->borderIsPixel == FALSE)
+		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		pWin->border = pWin->parent->border;
+		if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+		{
+		    index2 = CWBorderPixel;
+		}
+		else
+		{
+		    pWin->parent->border.pixmap->refcnt++;
+		}
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+					RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->borderIsPixel == FALSE)
+			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		    pWin->borderIsPixel = FALSE;
+		    pWin->border.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBorderPixel:
+	    if (pWin->borderIsPixel == FALSE)
+		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+	    pWin->borderIsPixel = TRUE;
+	    pWin->border.pixel = (CARD32) *pVlist;
+		    /* border pixel overrides border pixmap,
+		       so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBorderPixmap;
+	    pVlist++;
+	    break;
+	  case CWBitGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->bitGravity = val;
+	    break;
+	  case CWWinGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->winGravity = val;
+	    break;
+	  case CWBackingStore:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->backingStore = val;
+
+            #ifdef TEST
+            fprintf(stderr, "ChangeWindowAttributes: Changed backing store value to %d for window at %p.\n",
+                        val, (void*)pWin);
+            #endif
+
+	    pWin->forcedBS = FALSE;
+	    break;
+	  case CWBackingPlanes:
+	    if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+		if ((CARD32)*pVlist == (CARD32)~0L)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWBackingPixel:
+	    if (pWin->optional || (CARD32) *pVlist) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingPixel = (CARD32) *pVlist;
+		if (!*pVlist)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWSaveUnder:
+	    val = (BOOL) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+		DO_SAVE_UNDERS(pWin))
+	    {
+		/*
+		 * Re-check all siblings and inferiors for obscurity or
+		 * exposition (hee hee).
+		 */
+		if (pWin->saveUnder)
+		    deltaSaveUndersViewable--;
+		else
+		    deltaSaveUndersViewable++;
+		pWin->saveUnder = val;
+
+		if (pWin->firstChild)
+		{
+                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+                                                       pWin->nextSib);
+               }
+               else
+               {
+                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pWin,
+                                                       pWin->nextSib);
+               }                                   
+	    }
+	    else
+	    {
+		/*  If we're changing the saveUnder attribute of the root 
+		 *  window, all we do is set pWin->saveUnder so that
+		 *  GetWindowAttributes returns the right value.  We don't
+		 *  do the "normal" save-under processing (as above).
+		 *  Hope that doesn't cause any problems.
+		 */
+		pWin->saveUnder = val;
+	    }
+#else
+	    pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+	    break;
+	  case CWEventMask:
+            /*
+             * TODO: Some applications like java bean shell
+             * don' t work if they cannot monitor the root
+             * window for Structure Redirect events. However
+             * this doesn't seem to be the best solution, since
+             * also an X server with a window manager running,
+             * doesn't allow to monitor for those events, but
+             * the java bean shell works flawlessy on this
+             * server.
+             *
+             * if (nxagentCheckIllegalRootMonitoring(pWin, (Mask)*pVlist))
+             * {
+             *   return BadAccess;
+             * }
+             */
+
+	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWDontPropagate:
+	    result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+					    &checkOptional);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWOverrideRedirect:
+	    val = (BOOL ) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->overrideRedirect = val;
+	    break;
+	  case CWColormap:
+	    cmap = (Colormap) *pVlist;
+	    pVlist++;
+	    if (cmap == CopyFromParent)
+	    {
+#ifdef XAPPGROUP
+		Colormap ag_colormap;
+		ClientPtr win_owner;
+
+		/*
+		 * win_owner == client for CreateWindow, other clients
+		 * can ChangeWindowAttributes
+		 */
+		win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+		if ( win_owner && win_owner->appgroup &&
+		    !pWin->parent->parent &&
+		    (ag_colormap = XagDefaultColormap (win_owner)))
+		    cmap = ag_colormap;
+		else
+#endif
+		if (pWin->parent &&
+		    (!pWin->optional ||
+		     pWin->optional->visual == wVisual (pWin->parent)))
+		{
+		    cmap = wColormap (pWin->parent);
+		}
+		else
+		    cmap = None;
+	    }
+	    if (cmap == None)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+					      RT_COLORMAP, SecurityReadAccess);
+	    if (!pCmap)
+	    {
+		error = BadColor;
+		client->errorValue = cmap;
+		goto PatchUp;
+	    }
+	    if (pCmap->pVisual->vid != wVisual (pWin) ||
+		pCmap->pScreen != pScreen)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    if (cmap != wColormap (pWin))
+	    {
+		if (!pWin->optional)
+		{
+		    if (!MakeWindowOptional (pWin))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+		else if (pWin->parent && cmap == wColormap (pWin->parent))
+		    checkOptional = TRUE;
+
+		/*
+		 * propagate the original colormap to any children
+		 * inheriting it
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pWin->optional->colormap = cmap;
+
+		/*
+		 * check on any children now matching the new colormap
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (pChild->optional->colormap == cmap)
+			CheckWindowOptionalNeed (pChild);
+		}
+	
+		xE.u.u.type = ColormapNotify;
+		xE.u.colormap.window = pWin->drawable.id;
+		xE.u.colormap.colormap = cmap;
+		xE.u.colormap.new = xTrue;
+		xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+		DeliverEvents(pWin, &xE, 1, NullWindow);
+	    }
+	    break;
+	  case CWCursor:
+	    cursorID = (Cursor ) *pVlist;
+	    pVlist++;
+	    /*
+	     * install the new
+	     */
+	    if ( cursorID == None)
+	    {
+		if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+		    pCursor = rootCursor;
+		else
+		    pCursor = (CursorPtr) None;
+	    }
+	    else
+	    {
+		pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+						RT_CURSOR, SecurityReadAccess);
+		if (!pCursor)
+		{
+		    error = BadCursor;
+		    client->errorValue = cursorID;
+		    goto PatchUp;
+		}
+	    }
+
+	    if (pCursor != wCursor (pWin))
+	    {
+		/*
+		 * patch up child windows so they don't lose cursors.
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !pChild->cursorIsNone &&
+			!MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pOldCursor = 0;
+		if (pCursor == (CursorPtr) None)
+		{
+		    pWin->cursorIsNone = TRUE;
+		    if (pWin->optional)
+		    {
+			pOldCursor = pWin->optional->cursor;
+			pWin->optional->cursor = (CursorPtr) None;
+			checkOptional = TRUE;
+		    }
+		} else {
+		    if (!pWin->optional)
+		    {
+			if (!MakeWindowOptional (pWin))
+			{
+			    error = BadAlloc;
+			    goto PatchUp;
+			}
+		    }
+		    else if (pWin->parent && pCursor == wCursor (pWin->parent))
+			checkOptional = TRUE;
+		    pOldCursor = pWin->optional->cursor;
+		    pWin->optional->cursor = pCursor;
+		    pCursor->refcnt++;
+		    pWin->cursorIsNone = FALSE;
+		    /*
+		     * check on any children now matching the new cursor
+		     */
+
+		    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+		    {
+			if (pChild->optional &&
+			    (pChild->optional->cursor == pCursor))
+			    CheckWindowOptionalNeed (pChild);
+		    }
+		}
+
+		if (pWin->realized)
+		    WindowHasNewCursor( pWin);
+
+		/* Can't free cursor until here - old cursor
+		 * is needed in WindowHasNewCursor
+		 */
+		if (pOldCursor)
+		    FreeCursor (pOldCursor, (Cursor)0);
+	    }
+	    break;
+	 default:
+	    error = BadValue;
+	    client->errorValue = vmask;
+	    goto PatchUp;
+      }
+      vmaskCopy |= index2;
+    }
+PatchUp:
+    if (checkOptional)
+	CheckWindowOptionalNeed (pWin);
+
+	/* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+    /* 
+	If the border contents have changed, redraw the border. 
+	Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+	for the tile to be rotated, and the correct function selected.
+    */
+    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+	&& pWin->viewable && HasBorder (pWin))
+    {
+	RegionRec exposed;
+
+	REGION_NULL(pScreen, &exposed);
+	REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+	(*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+	REGION_UNINIT(pScreen, &exposed);
+    }
+    return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ *    Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+    wa->type = X_Reply;
+    wa->bitGravity = pWin->bitGravity;
+    wa->winGravity = pWin->winGravity;
+    if (pWin->forcedBS && pWin->backingStore != Always)
+	wa->backingStore = NotUseful;
+    else
+	wa->backingStore = pWin->backingStore;
+    wa->length = (sizeof(xGetWindowAttributesReply) -
+		 sizeof(xGenericReply)) >> 2;
+    wa->sequenceNumber = client->sequence;
+    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
+    wa->backingPixel =  wBackingPixel (pWin);
+    wa->saveUnder = (BOOL)pWin->saveUnder;
+    wa->override = pWin->overrideRedirect;
+    if (!pWin->mapped)
+	wa->mapState = IsUnmapped;
+    else if (pWin->realized)
+	wa->mapState = IsViewable;
+    else
+	wa->mapState = IsUnviewable;
+
+    wa->colormap =  wColormap (pWin);
+    wa->mapInstalled = (wa->colormap == None) ? xFalse
+				: IsMapInstalled(wa->colormap, pWin);
+
+    wa->yourEventMask = EventMaskForClient(pWin, client);
+    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+    wa->doNotPropagateMask = wDontPropagateMask (pWin);
+    wa->class = pWin->drawable.class;
+    wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+    register WindowPtr pParent = pWin->parent;
+    WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+    if (pWin->nextSib != pNextSib)
+    {
+	WindowPtr pOldNextSib = pWin->nextSib;
+
+	if (!pNextSib)	      /* move to bottom */
+	{
+	    if (pParent->firstChild == pWin)
+		pParent->firstChild = pWin->nextSib;
+	    /* if (pWin->nextSib) */	 /* is always True: pNextSib == NULL
+					  * and pWin->nextSib != pNextSib
+					  * therefore pWin->nextSib != NULL */
+	    pFirstChange = pWin->nextSib;
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pParent->lastChild->nextSib = pWin;
+	    pWin->prevSib = pParent->lastChild;
+	    pWin->nextSib = NullWindow;
+	    pParent->lastChild = pWin;
+	}
+	else if (pParent->firstChild == pNextSib) /* move to top */
+	{
+	    pFirstChange = pWin;
+	    if (pParent->lastChild == pWin)
+	       pParent->lastChild = pWin->prevSib;
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pParent->firstChild;
+	    pWin->prevSib = (WindowPtr ) NULL;
+	    pNextSib->prevSib = pWin;
+	    pParent->firstChild = pWin;
+	}
+	else			/* move in middle of list */
+	{
+	    WindowPtr pOldNext = pWin->nextSib;
+
+	    pFirstChange = NullWindow;
+	    if (pParent->firstChild == pWin)
+		pFirstChange = pParent->firstChild = pWin->nextSib;
+	    if (pParent->lastChild == pWin) {
+	       pFirstChange = pWin;
+	       pParent->lastChild = pWin->prevSib;
+	    }
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pNextSib;
+	    pWin->prevSib = pNextSib->prevSib;
+	    if (pNextSib->prevSib)
+		pNextSib->prevSib->nextSib = pWin;
+	    pNextSib->prevSib = pWin;
+	    if (!pFirstChange) {		     /* do we know it yet? */
+		pFirstChange = pParent->firstChild;  /* no, search from top */
+		while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+		     pFirstChange = pFirstChange->nextSib;
+	    }
+	}
+	if(pWin->drawable.pScreen->RestackWindow)
+	    (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+    }
+
+#ifdef ROOTLESS
+    /*
+     * In rootless mode we can't optimize away window restacks.
+     * There may be non-X windows around, so even if the window
+     * is in the correct position from X's point of view,
+     * the underlying window system may want to reorder it.
+     */
+    else if (pWin->drawable.pScreen->RestackWindow)
+        (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+    return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+    RegionPtr	pRgn;
+    BoxRec	box;
+
+    box.x1 = pWin->drawable.x;
+    box.y1 = pWin->drawable.y;
+    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+	ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+    }
+#endif
+    return pRgn;
+}
+
+void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+    if (pWin->redirectDraw)
+    {
+	BoxRec	box;
+
+	box.x1 = pWin->drawable.x;
+	box.y1 = pWin->drawable.y;
+	box.x2 = pWin->drawable.x + pWin->drawable.width;
+	box.y2 = pWin->drawable.y + pWin->drawable.height;
+	REGION_RESET (pScreen, &pWin->winSize, &box);
+    }
+    else
+#endif
+    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+			 pWin->drawable.x, pWin->drawable.y,
+			 (int)pWin->drawable.width,
+			 (int)pWin->drawable.height);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+#ifndef NXAGENT_SERVER
+	ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+			 pWin->drawable.y);
+    }
+#endif
+}
+
+void
+SetBorderSize (register WindowPtr pWin)
+{
+    int	bw;
+
+    if (HasBorder (pWin)) {
+	bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+	if (pWin->redirectDraw)
+	{
+	    BoxRec	box;
+
+	    box.x1 = pWin->drawable.x - bw;
+	    box.y1 = pWin->drawable.y - bw;
+	    box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+	    box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+	    REGION_RESET (pScreen, &pWin->borderSize, &box);
+	}
+	else
+#endif
+	ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+		pWin->drawable.x - bw, pWin->drawable.y - bw,
+		(int)(pWin->drawable.width + (bw<<1)),
+		(int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+	if (wBoundingShape (pWin)) {
+#ifndef NXAGENT_SERVER
+	    ScreenPtr pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+			     - pWin->drawable.y);
+	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+			     wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+			     pWin->drawable.y);
+	    REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+			 &pWin->winSize);
+	}
+#endif
+    } else {
+	REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+					       &pWin->winSize);
+    }
+}
+
+/**
+ *
+ *  \param x,y          new window position
+ *  \param oldx,oldy    old window position
+ *  \param destx,desty  position relative to gravity
+ */
+
+void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+                  int dw, int dh, unsigned gravity,
+                  register int *destx, register int *desty)
+{
+    switch (gravity) {
+    case NorthGravity:
+	*destx = x + dw / 2;
+	*desty = y;
+	break;
+    case NorthEastGravity:
+	*destx = x + dw;
+	*desty = y;
+	break;
+    case WestGravity:
+	*destx = x;
+	*desty = y + dh / 2;
+	break;
+    case CenterGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh / 2;
+	break;
+    case EastGravity:
+	*destx = x + dw;
+	*desty = y + dh / 2;
+	break;
+    case SouthWestGravity:
+	*destx = x;
+	*desty = y + dh;
+	break;
+    case SouthGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh;
+	break;
+    case SouthEastGravity:
+	*destx = x + dw;
+	*desty = y + dh;
+	break;
+    case StaticGravity:
+	*destx = oldx;
+	*desty = oldy;
+	break;
+    default:
+	*destx = x;
+	*desty = y;
+	break;
+    }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+    register ScreenPtr pScreen;
+    register WindowPtr pSib, pChild;
+    Bool resized = (dw || dh);
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+    {
+	if (resized && (pSib->winGravity > NorthWestGravity))
+	{
+	    int cwsx, cwsy;
+
+	    cwsx = pSib->origin.x;
+	    cwsy = pSib->origin.y;
+	    GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+			pSib->winGravity, &cwsx, &cwsy);
+	    if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+	    {
+		xEvent event;
+
+		event.u.u.type = GravityNotify;
+		event.u.gravity.window = pSib->drawable.id;
+		event.u.gravity.x = cwsx - wBorderWidth (pSib);
+		event.u.gravity.y = cwsy - wBorderWidth (pSib);
+		DeliverEvents (pSib, &event, 1, NullWindow);
+		pSib->origin.x = cwsx;
+		pSib->origin.y = cwsy;
+	    }
+	}
+	pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+	SetWinSize (pSib);
+	SetBorderSize (pSib);
+
+        /*
+         * Don't force X to move children. It will position them
+         * according with gravity.
+         *
+         * (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+         */
+
+        /*
+         * Update pSib privates, as this window is moved by X.
+         */
+
+        nxagentAddConfiguredWindow(pSib, CW_Update);
+
+	if ( (pChild = pSib->firstChild) )
+	{
+	    while (1)
+	    {
+		pChild->drawable.x = pChild->parent->drawable.x +
+				     pChild->origin.x;
+		pChild->drawable.y = pChild->parent->drawable.y +
+				     pChild->origin.y;
+		SetWinSize (pChild);
+		SetBorderSize (pChild);
+
+                (*pScreen->PositionWindow)(pChild, pChild->drawable.x,
+                                               pChild->drawable.y);
+
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+		while (!pChild->nextSib && (pChild != pSib))
+		    pChild = pChild->parent;
+		if (pChild == pSib)
+		    break;
+		pChild = pChild->nextSib;
+	    }
+	}
+    }
+}
+
+#define GET_INT16(m, f) \
+	if (m & mask) \
+	  { \
+	     f = (INT16) *pVlist;\
+	    pVlist++; \
+	 }
+#define GET_CARD16(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD16) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define GET_CARD8(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD8) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ *     returns Above if pSib above pMe in stack or Below otherwise 
+ */
+
+static int
+IsSiblingAboveMe(
+    register WindowPtr pMe,
+    register WindowPtr pSib)
+{
+    register WindowPtr pWin;
+
+    pWin = pMe->parent->firstChild;
+    while (pWin)
+    {
+	if (pWin == pSib)
+	    return(Above);
+	else if (pWin == pMe)
+	    return(Below);
+	pWin = pWin->nextSib;
+    }
+    return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+    register WindowPtr pWin,
+    register BoxPtr pBox)
+{
+    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+	       + wBorderWidth (pWin);
+    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+	       + wBorderWidth (pWin);
+    return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin)	(wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+    register WindowPtr	pWin,
+    BoxPtr	pBox)
+{
+    RegionPtr	pRgn;
+#ifndef NXAGENT_SERVER
+    ScreenPtr   pScreen = pWin->drawable.pScreen;
+#endif /* NXAGENT_SERVER */
+    pRgn = REGION_CREATE(pScreen, pBox, 1);
+    if (wBoundingShape (pWin)) {
+	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+						  -pWin->origin.y);
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+						  pWin->origin.y);
+    }
+    return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+    WindowPtr	pWin,
+    BoxPtr	pWinBox,
+    WindowPtr	pSib,
+    BoxPtr	pSibBox)
+{
+    RegionPtr	pWinRgn, pSibRgn;
+    register ScreenPtr	pScreen;
+    Bool	ret;
+
+    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+	return TRUE;
+    pScreen = pWin->drawable.pScreen;
+    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pSibRgn);
+    return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+    WindowPtr pWin,
+    WindowPtr pHead,
+    register BoxPtr box)
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+    WindowPtr pWin,
+    register BoxPtr box)
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+/*
+ *   WhereDoIGoInTheStack() 
+ *	  Given pWin and pSib and the relationshipe smode, return
+ *	  the window that pWin should go ABOVE.
+ *	  If a pSib is specified:
+ *	      Above:  pWin is placed just above pSib
+ *	      Below:  pWin is placed just below pSib
+ *	      TopIf:  if pSib occludes pWin, then pWin is placed
+ *		      at the top of the stack
+ *	      BottomIf:	 if pWin occludes pSib, then pWin is 
+ *			 placed at the bottom of the stack
+ *	      Opposite: if pSib occludes pWin, then pWin is placed at the
+ *			top of the stack, else if pWin occludes pSib, then
+ *			pWin is placed at the bottom of the stack
+ *
+ *	  If pSib is NULL:
+ *	      Above:  pWin is placed at the top of the stack
+ *	      Below:  pWin is placed at the bottom of the stack
+ *	      TopIf:  if any sibling occludes pWin, then pWin is placed at
+ *		      the top of the stack
+ *	      BottomIf: if pWin occludes any sibline, then pWin is placed at
+ *			the bottom of the stack
+ *	      Opposite: if any sibling occludes pWin, then pWin is placed at
+ *			the top of the stack, else if pWin occludes any
+ *			sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    short x,
+    short y,
+    unsigned short w,
+    unsigned short h,
+    int smode)
+{
+    BoxRec box;
+    register ScreenPtr pScreen;
+    WindowPtr pHead, pFirst;
+
+    if ((pWin == pWin->parent->firstChild) &&
+	(pWin == pWin->parent->lastChild))
+	return((WindowPtr ) NULL);
+    pHead = RealChildHead(pWin->parent);
+    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+    pScreen = pWin->drawable.pScreen;
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + (int)w;
+    box.y2 = y + (int)h;
+    switch (smode)
+    {
+      case Above:
+	if (pSib)
+	   return(pSib);
+	else if (pWin == pFirst)
+	    return(pWin->nextSib);
+	else
+	    return(pFirst);
+      case Below:
+	if (pSib)
+	    if (pSib->nextSib != pWin)
+		return(pSib->nextSib);
+	    else
+		return(pWin->nextSib);
+	else
+	    return NullWindow;
+      case TopIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return(pFirst);
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	    return(pFirst);
+	else
+	    return(pWin->nextSib);
+      case BottomIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return NullWindow;
+	    else
+		return(pWin->nextSib);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return(pWin->nextSib);
+      case Opposite:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+	    {
+		if (IsSiblingAboveMe(pWin, pSib) == Above)
+		    return(pFirst);
+		else
+		    return NullWindow;
+	    }
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	{
+	    /* If I'm occluded, I can't possibly be the first child
+	     * if (pWin == pWin->parent->firstChild)
+	     *	  return pWin->nextSib;
+	     */
+	    return(pFirst);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return pWin->nextSib;
+      default:
+      {
+	ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+	return pWin->nextSib;
+      }
+    }
+}
+
+static void
+ReflectStackChange(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    VTKind  kind)
+{
+/* Note that pSib might be NULL */
+
+    Bool WasViewable = (Bool)pWin->viewable;
+    Bool anyMarked;
+    WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    /* if this is a root window, can't be restacked */
+    if (!pWin->parent)
+	return;
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						      &pLayerWin);
+	if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN    0
+#define MOVE_WIN       1
+#define RESIZE_WIN     2
+#define REBORDER_WIN   3
+    register WindowPtr pSib = NullWindow;
+    register WindowPtr pParent = pWin->parent;
+    Window sibwid = 0;
+    Mask index2, tmask;
+    register XID *pVlist;
+    short x,   y, beforeX, beforeY;
+    unsigned short w = pWin->drawable.width,
+		   h = pWin->drawable.height,
+		   bw = pWin->borderWidth;
+    int action, smode = Above;
+#ifdef XAPPGROUP
+    ClientPtr win_owner;
+    ClientPtr ag_leader = NULL;
+#endif
+    xEvent event;
+
+    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+	return(BadMatch);
+
+    if ((mask & CWSibling) && !(mask & CWStackMode))
+	return(BadMatch);
+
+    pVlist = vlist;
+
+    if (pParent)
+    {
+	x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+	y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+    }
+    else
+    {
+	x = pWin->drawable.x;
+	y = pWin->drawable.y;
+    }
+    beforeX = x;
+    beforeY = y;
+    action = RESTACK_WIN;	
+    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	action = MOVE_WIN;
+    }
+	/* or should be resized */
+    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	GET_CARD16(CWWidth, w);
+	GET_CARD16 (CWHeight, h);
+	if (!w || !h)
+	{
+	    client->errorValue = 0;
+	    return BadValue;
+	}
+	action = RESIZE_WIN;
+    }
+    tmask = mask & ~ChangeMask;
+    while (tmask)
+    {
+	index2 = (Mask)lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBorderWidth:
+	    GET_CARD16(CWBorderWidth, bw);
+	    break;
+	  case CWSibling:
+	    sibwid = (Window ) *pVlist;
+	    pVlist++;
+	    pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+						RT_WINDOW, SecurityReadAccess);
+	    if (!pSib)
+	    {
+		client->errorValue = sibwid;
+		return(BadWindow);
+	    }
+	    if (pSib->parent != pParent)
+		return(BadMatch);
+	    if (pSib == pWin)
+		return(BadMatch);
+	    break;
+	  case CWStackMode:
+	    GET_CARD8(CWStackMode, smode);
+	    if ((smode != TopIf) && (smode != BottomIf) &&
+		(smode != Opposite) && (smode != Above) && (smode != Below))
+	    {
+		client->errorValue = smode;
+		return(BadValue);
+	    }
+	    break;
+	  default:
+	    client->errorValue = mask;
+	    return(BadValue);
+	}
+    }
+	/* root really can't be reconfigured, so just return */
+    if (!pParent)
+	return Success;
+
+	/* Figure out if the window should be moved.  Doesnt
+	   make the changes to the window if event sent */
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+
+      fprintf(stderr, "ConfigureWindow: pWin [%p] mask [%lu] client [%p]\n",
+                  pWin, mask, client);
+
+      fprintf(stderr, "ConfigureWindow: x [%d] y [%d] w [%d] h [%d] CWStackMode [%d] "
+                  "smode [%d] pSib [%p]\n",
+                      x, y, w, h, (mask & CWStackMode) ? 1 : 0, smode, pSib);
+    }
+    #endif
+
+    if (nxagentOption(Rootless) && nxagentWindowTopLevel(pWin) &&
+            pWin -> overrideRedirect == 0 &&
+                nxagentScreenTrap == 0)
+    {
+      nxagentConfigureRootlessWindow(pWin, x, y, w, h, bw, pSib, smode, mask);
+
+      return Success;
+    }
+
+    if (mask & CWStackMode)
+	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+				    pParent->drawable.y + y,
+				    w + (bw << 1), h + (bw << 1), smode);
+    else
+	pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+    ag_leader = XagLeader (win_owner);
+#endif
+
+    if ((!pWin->overrideRedirect) && 
+	(RedirectSend(pParent)
+#ifdef XAPPGROUP
+	|| (win_owner->appgroup && ag_leader && 
+	    XagIsControlledRoot (client, pParent))
+#endif
+	))
+    {
+	event.u.u.type = ConfigureRequest;
+	event.u.configureRequest.window = pWin->drawable.id;
+	if (mask & CWSibling)
+	   event.u.configureRequest.sibling = sibwid;
+	else
+	    event.u.configureRequest.sibling = None;
+	if (mask & CWStackMode)
+	   event.u.u.detail = smode;
+	else
+	    event.u.u.detail = Above;
+	event.u.configureRequest.x = x;
+	event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+            event.u.configureRequest.x += panoramiXdataPtr[0].x;
+            event.u.configureRequest.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureRequest.width = w;
+	event.u.configureRequest.height = h;
+	event.u.configureRequest.borderWidth = bw;
+	event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+	/* make sure if the ag_leader maps the window it goes to the wm */
+	if (ag_leader && ag_leader != client && 
+	    XagIsControlledRoot (client, pParent)) {
+	    event.u.configureRequest.parent = XagId (win_owner);
+	    (void) TryClientEvents (ag_leader, &event, 1,
+				    NoEventMask, NoEventMask, NullGrab);
+	    return Success;
+	}
+#endif
+	event.u.configureRequest.parent = pParent->drawable.id;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+    if (action == RESIZE_WIN)
+    {
+	Bool size_change = (w != pWin->drawable.width)
+			|| (h != pWin->drawable.height);
+	if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+	{
+	    xEvent eventT;
+	    eventT.u.u.type = ResizeRequest;
+	    eventT.u.resizeRequest.window = pWin->drawable.id;
+	    eventT.u.resizeRequest.width = w;
+	    eventT.u.resizeRequest.height = h;
+	    if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+				       ResizeRedirectMask, client) == 1)
+	    {
+		/* if event is delivered, leave the actual size alone. */
+		w = pWin->drawable.width;
+		h = pWin->drawable.height;
+		size_change = FALSE;
+	    }
+	}
+	if (!size_change)
+	{
+	    if (mask & (CWX | CWY))
+		action = MOVE_WIN;
+	    else if (mask & (CWStackMode | CWBorderWidth))
+		action = RESTACK_WIN;
+	    else   /* really nothing to do */
+		return(Success) ;
+	}
+    }
+
+    if (action == RESIZE_WIN)
+	    /* we've already checked whether there's really a size change */
+	    goto ActuallyDoSomething;
+    if ((mask & CWX) && (x != beforeX))
+	    goto ActuallyDoSomething;
+    if ((mask & CWY) && (y != beforeY))
+	    goto ActuallyDoSomething;
+    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+	    goto ActuallyDoSomething;
+    if (mask & CWStackMode)
+    {
+#ifndef ROOTLESS
+        /* See above for why we always reorder in rootless mode. */
+	if (pWin->nextSib != pSib)
+#endif
+	    goto ActuallyDoSomething;
+    }
+    return(Success);
+
+ActuallyDoSomething:
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = ConfigureNotify;
+	event.u.configureNotify.window = pWin->drawable.id;
+	if (pSib)
+	    event.u.configureNotify.aboveSibling = pSib->drawable.id;
+	else
+	    event.u.configureNotify.aboveSibling = None;
+	event.u.configureNotify.x = x;
+	event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+	    event.u.configureNotify.x += panoramiXdataPtr[0].x;
+            event.u.configureNotify.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureNotify.width = w;
+	event.u.configureNotify.height = h;
+	event.u.configureNotify.borderWidth = bw;
+	event.u.configureNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (mask & CWBorderWidth)
+    {
+	if (action == RESTACK_WIN)
+	{
+	    action = MOVE_WIN;
+	    pWin->borderWidth = bw;
+	}
+	else if ((action == MOVE_WIN) &&
+		 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+		 (beforeY + wBorderWidth (pWin) == y + (int)bw))
+	{
+	    action = REBORDER_WIN;
+	    (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+	}
+	else
+	    pWin->borderWidth = bw;
+    }
+    if (action == MOVE_WIN)
+	(*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+		   (mask & CWBorderWidth) ? VTOther : VTMove);
+    else if (action == RESIZE_WIN)
+	(*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+    else if (mask & CWStackMode)
+	ReflectStackChange(pWin, pSib, VTOther);
+
+    if (action != RESTACK_WIN)
+	CheckCursorConfinement(pWin);
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ *    For RaiseLowest, raises the lowest mapped child (if any) that is
+ *    obscured by another child to the top of the stack.  For LowerHighest,
+ *    lowers the highest mapped child (if any) that is obscuring another
+ *    child to the bottom of the stack.	 Exposure processing is performed 
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+    register WindowPtr pWin, pHead, pFirst;
+    xEvent event;
+    BoxRec box;
+
+    #ifdef TEST
+    fprintf(stderr, "CirculateWindow: pParent [%p] direction [%d] client [%p]\n",
+                pParent, direction, client);
+    #endif
+
+    /*
+     * if (nxagentOption(Rootless) && nxagentWMIsRunning &&
+     *         nxagentWindowTopLevel(pWin) && pWin -> overrideRedirect == 0)
+     * {
+     *   nxagentCirculateRootlessWindows(direction);
+     *   return Success;
+     * }
+     */
+
+    pHead = RealChildHead(pParent);
+    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+    if (direction == RaiseLowest)
+    {
+	for (pWin = pParent->lastChild;
+	     (pWin != pHead) &&
+	     !(pWin->mapped &&
+	       AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+	     pWin = pWin->prevSib) ;
+	if (pWin == pHead)
+	    return Success;
+    }
+    else
+    {
+	for (pWin = pFirst;
+	     pWin &&
+	     !(pWin->mapped &&
+	       IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+	     pWin = pWin->nextSib) ;
+	if (!pWin)
+	    return Success;
+    }
+
+    event.u.circulate.window = pWin->drawable.id;
+    event.u.circulate.parent = pParent->drawable.id;
+    event.u.circulate.event = pParent->drawable.id;
+    if (direction == RaiseLowest)
+	event.u.circulate.place = PlaceOnTop;
+    else
+	event.u.circulate.place = PlaceOnBottom;
+
+    if (RedirectSend(pParent))
+    {
+	event.u.u.type = CirculateRequest;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+
+    event.u.u.type = CirculateNotify;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+    ReflectStackChange(pWin,
+		       (direction == RaiseLowest) ? pFirst : NullWindow,
+		       VTStack);
+
+    return(Success);
+}
+
+static int
+CompareWIDs(
+    WindowPtr pWin,
+    pointer   value) /* must conform to VisitWindowProcPtr */
+{
+    Window *wid = (Window *)value;
+
+    if (pWin->drawable.id == *wid)
+       return(WT_STOPWALKING);
+    else
+       return(WT_WALKCHILDREN);
+}
+
+/*****
+ *  ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+               int x, int y, ClientPtr client)
+{
+    WindowPtr pPrev, pPriorParent;
+    Bool WasMapped = (Bool)(pWin->mapped);
+    xEvent event;
+    int bw = wBorderWidth (pWin);
+    register ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+	return(BadMatch);		
+    if (!MakeWindowOptional(pWin))
+	return(BadAlloc);
+
+    if (WasMapped)
+       UnmapWindow(pWin, FALSE);
+
+    event.u.u.type = ReparentNotify;
+    event.u.reparent.window = pWin->drawable.id;
+    event.u.reparent.parent = pParent->drawable.id;
+    event.u.reparent.x = x;
+    event.u.reparent.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && !pParent->parent) {
+	event.u.reparent.x += panoramiXdataPtr[0].x;
+	event.u.reparent.y += panoramiXdataPtr[0].y;
+    }
+#endif
+    event.u.reparent.override = pWin->overrideRedirect;
+    DeliverEvents(pWin, &event, 1, pParent);
+
+    /* take out of sibling chain */
+
+    pPriorParent = pPrev = pWin->parent;
+    if (pPrev->firstChild == pWin)
+	pPrev->firstChild = pWin->nextSib;
+    if (pPrev->lastChild == pWin)
+	pPrev->lastChild = pWin->prevSib;
+
+    if (pWin->nextSib)
+	pWin->nextSib->prevSib = pWin->prevSib;
+    if (pWin->prevSib)
+	pWin->prevSib->nextSib = pWin->nextSib;
+
+    /* insert at begining of pParent */
+    pWin->parent = pParent;
+    pPrev = RealChildHead(pParent);
+
+    if (pWin->parent == WindowTable[0])
+    {
+      nxagentSetTopLevelEventMask(pWin);
+    }
+ 
+    if (pPrev)
+    {
+	pWin->nextSib = pPrev->nextSib;
+	if (pPrev->nextSib)
+	    pPrev->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pPrev->nextSib = pWin;
+	pWin->prevSib = pPrev;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	pWin->prevSib = NullWindow;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.x = x + bw + pParent->drawable.x;
+    pWin->drawable.y = y + bw + pParent->drawable.y;
+
+    /* clip to parent */
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    if (pScreen->ReparentWindow)
+	(*pScreen->ReparentWindow)(pWin, pPriorParent);
+
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    CheckWindowOptionalNeed(pWin);
+
+    if (WasMapped)
+	MapWindow(pWin, client);
+    RecalculateDeliverableEvents(pWin);
+    return(Success);
+}
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+    register WindowPtr pChild;
+    RealizeWindowProcPtr Realize;
+
+    Realize = pWin->drawable.pScreen->RealizeWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->mapped)
+	{
+	    pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder)
+		deltaSaveUndersViewable++;
+#endif
+	    pChild->viewable = (pChild->drawable.class == InputOutput);
+	    (* Realize)(pChild);
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * MapWindow
+ *    If some other client has selected SubStructureReDirect on the parent
+ *    and override-redirect is xFalse, then a MapRequest event is generated,
+ *    but the window remains unmapped.	Otherwise, the window is mapped and a
+ *    MapNotify event is generated.
+ *****/
+
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+    register ScreenPtr pScreen;
+
+    register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "MapWindow: pWin [%p] client [%p]\n", pWin, client);
+    }
+    #endif
+
+    if (pWin->mapped)
+	return(Success);
+
+#ifdef XCSECURITY
+    /*  don't let an untrusted client map a child-of-trusted-window, InputOnly
+     *  window; too easy to steal device input
+     */
+    if ( (client->trustLevel != XSecurityClientTrusted) &&
+	 (pWin->drawable.class == InputOnly) &&
+	 (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+	 return Success;
+#endif	
+
+    pScreen = pWin->drawable.pScreen;
+    if ( (pParent = pWin->parent) )
+    {
+	xEvent event;
+	Bool anyMarked;
+#ifdef XAPPGROUP
+	ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+	ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+	if ((!pWin->overrideRedirect) && 
+	    (RedirectSend(pParent)
+#ifdef XAPPGROUP
+	    || (win_owner->appgroup && ag_leader &&
+		XagIsControlledRoot (client, pParent))
+#endif
+	))
+	{
+	    event.u.u.type = MapRequest;
+	    event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+	    /* make sure if the ag_leader maps the window it goes to the wm */
+	    if (ag_leader && ag_leader != client &&
+		XagIsControlledRoot (client, pParent)) {
+		event.u.mapRequest.parent = XagId (win_owner);
+		(void) TryClientEvents (ag_leader, &event, 1,
+					NoEventMask, NoEventMask, NullGrab);
+		return Success;
+	    }
+#endif
+	    event.u.mapRequest.parent = pParent->drawable.id;
+
+	    if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+		return(Success);
+	}
+
+	pWin->mapped = TRUE;
+	if (SubStrSend(pWin, pParent))
+	{
+	    event.u.u.type = MapNotify;
+	    event.u.mapNotify.window = pWin->drawable.id;
+	    event.u.mapNotify.override = pWin->overrideRedirect;
+	    DeliverEvents(pWin, &event, 1, NullWindow);
+	}
+
+	if (!pParent->realized)
+	    return(Success);
+	RealizeTree(pWin);
+	if (pWin->viewable)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+	    if (DO_SAVE_UNDERS(pWin))
+	    {
+		dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+#endif /* DO_SAVE_UNDERS */
+	    if (anyMarked)
+	    {
+		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+		(*pScreen->HandleExposures)(pLayerWin->parent);
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (dosave)
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+	}
+	WindowsRestructured ();
+    }
+    else
+    {
+	RegionRec   temp;
+
+	pWin->mapped = TRUE;
+	pWin->realized = TRUE;	   /* for roots */
+	pWin->viewable = pWin->drawable.class == InputOutput;
+	/* We SHOULD check for an error value here XXX */
+	(*pScreen->RealizeWindow)(pWin);
+	if (pScreen->ClipNotify)
+	    (*pScreen->ClipNotify) (pWin, 0, 0);
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+	REGION_NULL(pScreen, &temp);
+	REGION_COPY(pScreen, &temp, &pWin->clipList);
+	(*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+	REGION_UNINIT(pScreen, &temp);
+    }
+
+    nxagentFlushConfigureWindow();
+
+    return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ *    Performs a MapWindow all unmapped children of the window, in top
+ *    to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+    register WindowPtr	pWin;
+    WindowPtr		pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+    WindowPtr		pFirstSaveUndered = NullWindow;
+#endif
+    register ScreenPtr	pScreen;
+    register Mask	parentRedirect;
+    register Mask	parentNotify;
+    xEvent		event;
+    Bool		anyMarked;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr		pLayerWin;
+
+    pScreen = pParent->drawable.pScreen;
+    parentRedirect = RedirectSend(pParent);
+    parentNotify = SubSend(pParent);
+    anyMarked = FALSE;
+    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+    {
+	if (!pWin->mapped)
+	{
+	    if (parentRedirect && !pWin->overrideRedirect)
+	    {
+		event.u.u.type = MapRequest;
+		event.u.mapRequest.window = pWin->drawable.id;
+		event.u.mapRequest.parent = pParent->drawable.id;
+    
+		if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		    SubstructureRedirectMask, client) == 1)
+		    continue;
+	    }
+    
+	    pWin->mapped = TRUE;
+	    if (parentNotify || StrSend(pWin))
+	    {
+		event.u.u.type = MapNotify;
+		event.u.mapNotify.window = pWin->drawable.id;
+		event.u.mapNotify.override = pWin->overrideRedirect;
+		DeliverEvents(pWin, &event, 1, NullWindow);
+	    }
+    
+	    if (!pFirstMapped)
+		pFirstMapped = pWin;
+	    if (pParent->realized)
+	    {
+		RealizeTree(pWin);
+		if (pWin->viewable)
+		{
+		    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							(WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave = TRUE;
+		    }
+#endif /* DO_SAVE_UNDERS */
+		}
+	    }
+	}
+    }
+
+    if (pFirstMapped)
+    {
+	pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+	if (pLayerWin->parent != pParent) {
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+							   pLayerWin,
+							   (WindowPtr *)NULL);
+	    pFirstMapped = pLayerWin;
+	}
+        if (anyMarked)
+        {
+#ifdef DO_SAVE_UNDERS
+	    if (pLayerWin->parent != pParent)
+	    {
+		if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+		{
+		    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+							 pLayerWin);
+		}
+	    }
+	    else if (dosave)
+	    {
+		dosave = FALSE;
+		for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+		{
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+							      pWin->nextSib);
+			if (dosave && !pFirstSaveUndered)
+			    pFirstSaveUndered = pWin;
+		    }
+		}
+            }
+#endif /* DO_SAVE_UNDERS */
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+        if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin,
+					    pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+        if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+					 VTMap);
+        WindowsRestructured ();
+    }
+}
+
+static void
+UnrealizeTree(
+    WindowPtr pWin,
+    Bool fromConfigure)
+{
+    register WindowPtr pChild;
+    UnrealizeWindowProcPtr Unrealize;
+    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->realized)
+	{
+	    pChild->realized = FALSE;
+	    pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+		PanoramiXRes *win;
+		win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+							XRT_WINDOW);
+		if(win)
+		   win->u.win.visibility = VisibilityNotViewable;
+	    } 
+#endif
+	    (* Unrealize)(pChild);
+	    DeleteWindowFromAnyEvents(pChild, FALSE);
+	    if (pChild->viewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		if (pChild->saveUnder)
+		    deltaSaveUndersViewable--;
+#endif
+		pChild->viewable = FALSE;
+		if (pChild->backStorage)
+		    (*pChild->drawable.pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+		(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+		pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    }
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * UnmapWindow
+ *    If the window is already unmapped, this request has no effect.
+ *    Otherwise, the window is unmapped and an UnMapNotify event is
+ *    generated.  Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+    register WindowPtr pParent;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    #ifdef TEST
+    if (nxagentWindowTopLevel(pWin))
+    {
+      fprintf(stderr, "UnmapWindow: pWin [%p] fromConfigure [%d]\n", pWin,
+                  fromConfigure);
+    }
+    #endif
+
+    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+	return(Success);
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = UnmapNotify;
+	event.u.unmapNotify.window = pWin->drawable.id;
+	event.u.unmapNotify.fromConfigure = fromConfigure;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (wasViewable && !fromConfigure)
+    {
+	pWin->valdata = UnmapValData;
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+	(*pScreen->MarkWindow)(pLayerWin->parent);
+    }
+    pWin->mapped = FALSE;
+    if (wasRealized)
+	UnrealizeTree(pWin, fromConfigure);
+    if (wasViewable)
+    {
+	if (!fromConfigure)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+	    {
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+	}
+	pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+	if (!fromConfigure && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+    }
+    if (wasRealized && !fromConfigure)
+	WindowsRestructured ();
+    return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ *    Performs an UnmapWindow request with the specified mode on all mapped
+ *    children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+    register WindowPtr pChild, pHead;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    Bool anyMarked = FALSE;
+    Mask parentNotify;
+    WindowPtr pLayerWin = NULL;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!pWin->firstChild)
+	return;
+    parentNotify = SubSend(pWin);
+    pHead = RealChildHead(pWin);
+
+    if (wasViewable)
+	pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+	if (pChild->mapped)
+	{
+	    if (parentNotify || StrSend(pChild))
+	    {
+		event.u.u.type = UnmapNotify;
+		event.u.unmapNotify.window = pChild->drawable.id;
+		event.u.unmapNotify.fromConfigure = xFalse;
+		DeliverEvents(pChild, &event, 1, NullWindow);
+	    }
+	    if (pChild->viewable)
+	    {
+		pChild->valdata = UnmapValData;
+		anyMarked = TRUE;
+	    }
+	    pChild->mapped = FALSE;
+	    if (pChild->realized)
+		UnrealizeTree(pChild, FALSE);
+	    if (wasViewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+		if (pChild->backStorage)
+		    (*pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+	    }
+	}
+    }
+    if (wasViewable)
+    {
+	if (anyMarked)
+	{
+	    if (pLayerWin->parent == pWin)
+		(*pScreen->MarkWindow)(pWin);
+	    else
+	    {
+		WindowPtr ptmp;
+                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						  (WindowPtr *)NULL);
+		(*pScreen->MarkWindow)(pLayerWin->parent);
+		
+		/* Windows between pWin and pLayerWin may not have been marked */
+		ptmp = pWin;
+ 
+		while (ptmp != pLayerWin->parent)
+		{
+		    (*pScreen->MarkWindow)(ptmp);
+		    ptmp = ptmp->parent;
+		}
+                pHead = pWin->firstChild;
+	    }
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+    }
+    if (wasRealized)
+	WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+    register WindowPtr pParent, pWin;
+    register int j;
+
+    for (j=0; j<client->numSaved; j++)
+    {
+	pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+	if (SaveSetToRoot(client->saveSet[j]))
+	    pParent = WindowTable[pWin->drawable.pScreen->myNum];
+	else
+#endif
+	{
+	    pParent = pWin->parent;
+	    while (pParent && (wClient (pParent) == client))
+		pParent = pParent->parent;
+	}
+	if (pParent)
+	{
+	    if (pParent != pWin->parent)
+	    {
+		ReparentWindow(pWin, pParent,
+			       pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+			       pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+			       client);
+		if(!pWin->realized && pWin->mapped)
+		    pWin->mapped = FALSE;
+	    }
+#ifdef XFIXES
+	    if (SaveSetRemap (client->saveSet[j]))
+#endif
+		MapWindow(pWin, client);
+	}
+    }
+    xfree(client->saveSet);
+    client->numSaved = 0;
+    client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ *  \param x,y  in root
+ *  \param box  "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+	return(TRUE);
+    return(FALSE);
+}
+
+/**
+ *
+ * \param x,y  in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+						  x, y, &box)
+	&& (!wInputShape(pWin) ||
+	    POINT_IN_REGION(pWin->drawable.pScreen,
+			    wInputShape(pWin),
+			    x - pWin->drawable.x, 
+			    y - pWin->drawable.y, &box)))
+	return(TRUE);
+    return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+    register ScreenPtr pScreen;
+    RegionPtr pReg;
+
+    pScreen = pWin->drawable.pScreen;
+    pReg = REGION_CREATE(pScreen, NullBox, 1);
+    if (pWin->parent ||
+	screenIsSaved != SCREEN_SAVER_ON ||
+	!HasSaverWindow (pWin->drawable.pScreen->myNum))
+    {
+	REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+    }
+    return(pReg);
+}
+
+void
+SendVisibilityNotify(WindowPtr pWin)
+{
+    xEvent event;
+#ifndef NO_XINERAMA_PORT
+    unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+    /* This is not quite correct yet, but it's close */
+    if(!noPanoramiXExtension) {
+	PanoramiXRes *win;
+	WindowPtr pWin2;
+	int i, Scrnum;
+
+	Scrnum = pWin->drawable.pScreen->myNum;
+	
+	win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+	if(!win || (win->u.win.visibility == visibility))
+	    return;
+
+	switch(visibility) {
+	case VisibilityUnobscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+		if (pWin2) {
+		    if(pWin2->visibility == VisibilityPartiallyObscured)
+		   	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	case VisibilityPartiallyObscured:
+	    if(Scrnum) {
+	        pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+		if (pWin2) pWin = pWin2;
+	    }
+	    break;
+	case VisibilityFullyObscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+		
+		if (pWin2) {
+		    if(pWin2->visibility != VisibilityFullyObscured)
+		    	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	}
+	
+	win->u.win.visibility = visibility;
+    }
+#endif
+
+    event.u.u.type = VisibilityNotify;
+    event.u.visibility.window = pWin->drawable.id;
+    event.u.visibility.state = visibility;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+    WindowPtr pWin
+);
+#endif
+
+void
+SaveScreens(int on, int mode)
+{
+    int i;
+    int what;
+    int type;
+
+    if (on == SCREEN_SAVER_FORCER)
+    {
+	UpdateCurrentTimeIf();
+	lastDeviceEventTime = currentTime;
+	if (mode == ScreenSaverReset)
+	    what = SCREEN_SAVER_OFF;
+	else
+	    what = SCREEN_SAVER_ON;
+	type = what;
+    }
+    else
+    {
+	what = on;
+	type = what;
+	if (what == screenIsSaved)
+	    type = SCREEN_SAVER_CYCLE;
+    }
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+	if (on == SCREEN_SAVER_FORCER)
+	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+	if (savedScreenInfo[i].ExternalScreenSaver)
+	{
+          if (nxagentOption(Timeout) != 0)
+          {
+            #ifdef TEST
+            fprintf(stderr, "SaveScreens: An external screen-saver handler is installed. "
+                        "Ignoring it to let the auto-disconnect feature work.\n");
+            #endif
+          }
+          else
+          {
+	      if ((*savedScreenInfo[i].ExternalScreenSaver)
+		  (screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+		  continue;
+          }
+	}
+	if (type == screenIsSaved)
+	    continue;
+	switch (type) {
+	case SCREEN_SAVER_OFF:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+	       (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						      what);
+	    }
+	    else if (HasSaverWindow (i))
+	    {
+		savedScreenInfo[i].pWindow = NullWindow;
+		FreeResource(savedScreenInfo[i].wid, RT_NONE);
+	    }
+	    break;
+	case SCREEN_SAVER_CYCLE:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+	    {
+		WindowPtr pWin = savedScreenInfo[i].pWindow;
+		/* make it look like screen saver is off, so that
+		 * NotClippedByChildren will compute a clip list
+		 * for the root window, so miPaintWindow works
+		 */
+		screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+		(*pWin->drawable.pScreen->MoveWindow)(pWin,
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    DrawLogo(pWin);
+#endif
+		screenIsSaved = SCREEN_SAVER_ON;
+	    }
+	    /*
+	     * Call the DDX saver in case it wants to do something
+	     * at cycle time
+	     */
+	    else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+		(* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						       type);
+	    }
+	    break;
+	case SCREEN_SAVER_ON:
+	    if (ScreenSaverBlanking != DontPreferBlanking)
+	    {
+		if ((* screenInfo.screens[i]->SaveScreen)
+		   (screenInfo.screens[i], what))
+		{
+		   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+		   continue;
+		}
+		if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		    TileScreenSaver(i, SCREEN_IS_BLACK))
+		{
+		    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+		    continue;
+		}
+	    }
+	    if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		TileScreenSaver(i, SCREEN_IS_TILED))
+	    {
+		savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+	    }
+	    else
+		savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+	    break;
+	}
+    }
+    screenIsSaved = what;
+    if (mode == ScreenSaverReset)
+       SetScreenSaverTimer();
+}
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+    int j;
+    int result;
+    XID attributes[3];
+    Mask mask;
+    WindowPtr pWin;		
+    CursorMetricRec cm;
+    unsigned char *srcbits, *mskbits;
+    CursorPtr cursor;
+    XID	cursorID = 0;
+    int	attri;
+
+    mask = 0;
+    attri = 0;
+    switch (kind) {
+    case SCREEN_IS_TILED:
+	switch (WindowTable[i]->backgroundState) {
+	case BackgroundPixel:
+	    attributes[attri++] = WindowTable[i]->background.pixel;
+	    mask |= CWBackPixel;
+	    break;
+	case BackgroundPixmap:
+	    attributes[attri++] = None;
+	    mask |= CWBackPixmap;
+	    break;
+	default:
+	    break;
+	}
+	break;
+    case SCREEN_IS_BLACK:
+	attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+	mask |= CWBackPixel;
+	break;
+    }
+    mask |= CWOverrideRedirect;
+    attributes[attri++] = xTrue;
+
+    /*
+     * create a blank cursor
+     */
+
+    cm.width=16;
+    cm.height=16;
+    cm.xhot=8;
+    cm.yhot=8;
+    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    if (!srcbits || !mskbits)
+    {
+	xfree(srcbits);
+	xfree(mskbits);
+	cursor = 0;
+    }
+    else
+    {
+	for (j=0; j<BitmapBytePad(32)*16; j++)
+	    srcbits[j] = mskbits[j] = 0x0;
+	cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+	if (cursor)
+	{
+	    cursorID = FakeClientID(0);
+	    if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+	    {
+		attributes[attri] = cursorID;
+		mask |= CWCursor;
+	    }
+	    else
+		cursor = 0;
+	}
+	else
+	{
+	    xfree (srcbits);
+	    xfree (mskbits);
+	}
+    }
+
+    pWin = savedScreenInfo[i].pWindow =
+	 CreateWindow(savedScreenInfo[i].wid,
+	      WindowTable[i],
+	      -RANDOM_WIDTH, -RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+	      0, InputOutput, mask, attributes, 0, serverClient,
+	      wVisual (WindowTable[i]), &result);
+
+    if (cursor)
+	FreeResource (cursorID, RT_NONE);
+
+    if (!pWin)
+	return FALSE;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW,
+		     (pointer)savedScreenInfo[i].pWindow))
+	return FALSE;
+
+    if (mask & CWBackPixmap)
+    {
+	MakeRootTile (pWin);
+	(*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+    }
+    MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+    if (kind == SCREEN_IS_TILED && logoScreenSaver)
+	DrawLogo(pWin);
+#endif
+    return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure.  Assumptions:	 some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+    do
+	w = w->parent;
+    while (!w->optional);
+    return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules.	 If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (!w->parent)
+	return;
+    optional = w->optional;
+    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+	return;
+    if (optional->otherEventMasks != 0)
+	return;
+    if (optional->otherClients != NULL)
+	return;
+    if (optional->passiveGrabs != NULL)
+	return;
+    if (optional->userProps != NULL)
+	return;
+    if (optional->backingBitPlanes != ~0L)
+	return;
+    if (optional->backingPixel != 0)
+	return;
+#ifdef SHAPE
+    if (optional->boundingShape != NULL)
+	return;
+    if (optional->clipShape != NULL)
+	return;
+    if (optional->inputShape != NULL)
+	return;
+#endif
+#ifdef XINPUT
+    if (optional->inputMasks != NULL)
+	return;
+#endif
+    parentOptional = FindWindowWithOptional(w)->optional;
+    if (optional->visual != parentOptional->visual)
+	return;
+    if (optional->cursor != None &&
+	(optional->cursor != parentOptional->cursor ||
+	 w->parent->cursorIsNone))
+	return;
+    if (optional->colormap != parentOptional->colormap)
+	return;
+    DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (pWin->optional)
+	return TRUE;
+    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+    if (!optional)
+	return FALSE;
+    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+    optional->otherEventMasks = 0;
+    optional->otherClients = NULL;
+    optional->passiveGrabs = NULL;
+    optional->userProps = NULL;
+    optional->backingBitPlanes = ~0L;
+    optional->backingPixel = 0;
+#ifdef SHAPE
+    optional->boundingShape = NULL;
+    optional->clipShape = NULL;
+    optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+    optional->inputMasks = NULL;
+#endif
+    parentOptional = FindWindowWithOptional(pWin)->optional;
+    optional->visual = parentOptional->visual;
+    if (!pWin->cursorIsNone)
+    {
+	optional->cursor = parentOptional->cursor;
+	optional->cursor->refcnt++;
+    }
+    else
+    {
+	optional->cursor = None;
+    }
+    optional->colormap = parentOptional->colormap;
+    pWin->optional = optional;
+    return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+    if (!pWin->optional)
+	return;
+    /*
+     * everything is peachy.  Delete the optional record
+     * and clean up
+     */
+    /*
+     * TOG changed this code to:
+     *
+     *	    if (pWin->cursorIsNone == FALSE)
+     *		FreeCursor (pWin->optional->cursor, (Cursor)0);
+     *	    pWin->cursorIsNone = TRUE;
+     *
+     * This is blatently wrong; windows without optionals can have
+     * two different cursor values, either None or sharing their
+     * parents cursor.  This difference is controlled by the
+     * cursorIsNone value; when TRUE, the window has no cursor,
+     * when false, it shares its cursor with its parent; TOG
+     * made it impossible for a window to have a cursor without
+     * an optional record.
+     */
+    if (pWin->optional->cursor)
+    {
+	FreeCursor (pWin->optional->cursor, (Cursor)0);
+	pWin->cursorIsNone = FALSE;
+    }
+    else
+	pWin->cursorIsNone = TRUE;
+/* FIXME
+   There is an error when disposing ClientResources on Agent exit
+   this xfree is not valid in some window at exit
+*/
+
+    xfree (pWin->optional);
+    pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+    DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    int x, y;
+    unsigned int width, height, size;
+    GC *pGC;
+    int thin, gap, d31;
+    DDXPointRec poly[4];
+    ChangeGCVal fore[2], back[2];
+    xrgb rgb[2];
+    BITS32 fmask, bmask;
+    ColormapPtr cmap;
+
+    pDraw = (DrawablePtr)pWin;
+    pScreen = pDraw->pScreen;
+    x = -pWin->origin.x;
+    y = -pWin->origin.y;
+    width = pScreen->width;
+    height = pScreen->height;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pGC)
+	return;
+
+    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+	fore[0].val = pScreen->whitePixel;
+    else
+	fore[0].val = pScreen->blackPixel;
+    if ((pWin->backgroundState == BackgroundPixel) &&
+	(cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+	Pixel querypixels[2];
+
+	querypixels[0] = fore[0].val;
+	querypixels[1] = pWin->background.pixel;
+	QueryColors(cmap, 2, querypixels, rgb);
+	if ((rgb[0].red == rgb[1].red) &&
+	    (rgb[0].green == rgb[1].green) &&
+	    (rgb[0].blue == rgb[1].blue)) {
+	    if (fore[0].val == pScreen->blackPixel)
+		fore[0].val = pScreen->whitePixel;
+	    else
+		fore[0].val = pScreen->blackPixel;
+	}
+    }
+    fore[1].val = FillSolid;
+    fmask = GCForeground|GCFillStyle;
+    if (pWin->backgroundState == BackgroundPixel) {
+	back[0].val = pWin->background.pixel;
+	back[1].val = FillSolid;
+	bmask = GCForeground|GCFillStyle;
+    } else {
+	back[0].val = 0;
+	back[1].val = 0;
+	dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+		    NULL, back);
+	back[0].val = FillTiled;
+	back[1].ptr = pWin->background.pixmap;
+	bmask = GCFillStyle|GCTile;
+    }
+
+    /* should be the same as the reference function XmuDrawLogo() */
+
+    size = width;
+    if (height < width)
+	 size = height;
+    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+    size &= ~1;
+    x += rand() % (width - size);
+    y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ *           -----
+ *          /    /
+ *         /    /
+ *        /    /
+ *       /    /
+ *      /____/
+ *           d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+    thin = (size / 11);
+    if (thin < 1) thin = 1;
+    gap = (thin+3) / 4;
+    d31 = thin + thin + gap;
+    poly[0].x = x + size;	       poly[0].y = y;
+    poly[1].x = x + size-d31;	       poly[1].y = y;
+    poly[2].x = x + 0;		       poly[2].y = y + size;
+    poly[3].x = x + d31;	       poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ *           ------
+ *          /	  /
+ *         /  __ /
+ *        /  /	/
+ *       /  /  /
+ *      /__/__/
+ */
+
+    poly[0].x = x + d31/2;			 poly[0].y = y + size;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)+(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + d31;			 poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ *	     ------
+ *	    /  /  /
+ *	   /--/	 /
+ *	  /	/
+ *	 /     /
+ *	/_____/
+ */
+
+    poly[0].x = x + size - d31/2;		 poly[0].y = y;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)-(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + size - d31;			 poly[3].y = y;
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ *      b
+ * -----
+ * \	\
+ *  \	 \
+ *   \	  \
+ *    \	   \
+ *     \____\
+ */
+
+    poly[0].x = x;		       poly[0].y = y;
+    poly[1].x = x + size/4;	       poly[1].y = y;
+    poly[2].x = x + size;	       poly[2].y = y + size;
+    poly[3].x = x + size - size/4;     poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ *	    /
+ *	   /
+ *	  /
+ *	 /
+ *	/
+ */
+
+    poly[0].x = x + size- thin;	      poly[0].y = y;
+    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
+    poly[2].x = x + thin;	      poly[2].y = y + size;
+    poly[3].x = x + thin + gap;	      poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+    FreeScratchGC(pGC);
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original
new file mode 100644
index 000000000..c060f4a23
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.X.original
@@ -0,0 +1,3853 @@
+/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.12 2005/07/03 08:53:38 daniels Exp $ */
+/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
+/*
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+			All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.36 2003/11/14 23:52:50 torrey Exp $ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "os.h"
+#include "regionstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "input.h"
+#include "resource.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "servermd.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "dixevents.h"
+#include "globals.h"
+
+#ifdef XAPPGROUP
+#include <X11/extensions/Xagsrv.h>
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include <X11/extensions/security.h>
+#endif
+
+/******
+ * Window stuff for server 
+ *
+ *    CreateRootWindow, CreateWindow, ChangeWindowAttributes,
+ *    GetWindowAttributes, DeleteWindow, DestroySubWindows,
+ *    HandleSaveSet, ReparentWindow, MapWindow, MapSubWindows,
+ *    UnmapWindow, UnmapSubWindows, ConfigureWindow, CirculateWindow,
+ *
+ ******/
+
+static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
+static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+
+int screenIsSaved = SCREEN_SAVER_OFF;
+
+ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+#if 0
+extern void DeleteWindowFromAnyEvents();
+extern Mask EventMaskForClient();
+extern void WindowHasNewCursor();
+extern void RecalculateDeliverableEvents();
+#endif
+
+static Bool TileScreenSaver(int i, int kind);
+
+
+#define INPUTONLY_LEGAL_MASK (CWWinGravity | CWEventMask | \
+			      CWDontPropagate | CWOverrideRedirect | CWCursor )
+
+#define BOXES_OVERLAP(b1, b2) \
+      (!( ((b1)->x2 <= (b2)->x1)  || \
+	( ((b1)->x1 >= (b2)->x2)) || \
+	( ((b1)->y2 <= (b2)->y1)) || \
+	( ((b1)->y1 >= (b2)->y2)) ) )
+
+#define RedirectSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureRedirectMask)
+
+#define SubSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & SubstructureNotifyMask)
+
+#define StrSend(pWin) \
+    ((pWin->eventMask|wOtherEventMasks(pWin)) & StructureNotifyMask)
+
+#define SubStrSend(pWin,pParent) (StrSend(pWin) || SubSend(pParent))
+
+
+int numSaveUndersViewable = 0;
+int deltaSaveUndersViewable = 0;
+
+#ifdef DEBUG
+/******
+ * PrintWindowTree
+ *    For debugging only
+ ******/
+
+int
+PrintChildren(WindowPtr p1, int indent)
+{
+    WindowPtr p2;
+    int i;
+
+    while (p1)
+    {
+	p2 = p1->firstChild;
+	for (i=0; i<indent; i++) ErrorF( " ");
+	ErrorF( "%x\n", p1->drawable.id);
+	miPrintRegion(&p1->clipList);
+	PrintChildren(p2, indent+4);
+	p1 = p1->nextSib;
+    }
+}
+
+PrintWindowTree()
+{
+    int i;
+    WindowPtr pWin, p1;
+
+    for (i=0; i<screenInfo.numScreens; i++)
+    {
+	ErrorF( "WINDOW %d\n", i);
+	pWin = WindowTable[i];
+	miPrintRegion(&pWin->clipList);
+	p1 = pWin->firstChild;
+	PrintChildren(p1, 4);
+    }
+}
+#endif
+
+int
+TraverseTree(register WindowPtr pWin, VisitWindowProcPtr func, pointer data)
+{
+    register int result;
+    register WindowPtr pChild;
+
+    if (!(pChild = pWin))
+       return(WT_NOMATCH);
+    while (1)
+    {
+	result = (* func)(pChild, data);
+	if (result == WT_STOPWALKING)
+	    return(WT_STOPWALKING);
+	if ((result == WT_WALKCHILDREN) && pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    break;
+	pChild = pChild->nextSib;
+    }
+    return(WT_NOMATCH);
+}
+
+/*****
+ * WalkTree
+ *   Walk the window tree, for SCREEN, preforming FUNC(pWin, data) on
+ *   each window.  If FUNC returns WT_WALKCHILDREN, traverse the children,
+ *   if it returns WT_DONTWALKCHILDREN, dont.  If it returns WT_STOPWALKING
+ *   exit WalkTree.  Does depth-first traverse.
+ *****/
+
+int
+WalkTree(ScreenPtr pScreen, VisitWindowProcPtr func, pointer data)
+{
+    return(TraverseTree(WindowTable[pScreen->myNum], func, data));
+}
+
+/* hack for forcing backing store on all windows */
+int	defaultBackingStore = NotUseful;
+/* hack to force no backing store */
+Bool	disableBackingStore = FALSE;
+Bool	enableBackingStore = FALSE;
+/* hack to force no save unders */
+Bool	disableSaveUnders = FALSE;
+
+static void
+SetWindowToDefaults(register WindowPtr pWin)
+{
+    pWin->prevSib = NullWindow;
+    pWin->firstChild = NullWindow;
+    pWin->lastChild = NullWindow;
+
+    pWin->valdata = (ValidatePtr)NULL;
+    pWin->optional = (WindowOptPtr)NULL;
+    pWin->cursorIsNone = TRUE;
+
+    pWin->backingStore = NotUseful;
+    pWin->DIXsaveUnder = FALSE;
+    pWin->backStorage = (pointer) NULL;
+
+    pWin->mapped = FALSE;	    /* off */
+    pWin->realized = FALSE;	/* off */
+    pWin->viewable = FALSE;
+    pWin->visibility = VisibilityNotViewable;
+    pWin->overrideRedirect = FALSE;
+    pWin->saveUnder = FALSE;
+
+    pWin->bitGravity = ForgetGravity;
+    pWin->winGravity = NorthWestGravity;
+
+    pWin->eventMask = 0;
+    pWin->deliverableEvents = 0;
+    pWin->dontPropagate = 0;
+    pWin->forcedBS = FALSE;
+#ifdef NEED_DBE_BUF_BITS
+    pWin->srcBuffer = DBE_FRONT_BUFFER;
+    pWin->dstBuffer = DBE_FRONT_BUFFER;
+#endif
+#ifdef COMPOSITE
+    pWin->redirectDraw = 0;
+#endif
+}
+
+static void
+MakeRootTile(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    GCPtr pGC;
+    unsigned char back[128];
+    int len = BitmapBytePad(sizeof(long));
+    register unsigned char *from, *to;
+    register int i, j;
+
+    pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4,
+						    pScreen->rootDepth);
+
+    pWin->backgroundState = BackgroundPixmap;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pWin->background.pixmap || !pGC)
+	FatalError("could not create root tile");
+
+    {
+	CARD32 attributes[2];
+
+	attributes[0] = pScreen->whitePixel;
+	attributes[1] = pScreen->blackPixel;
+
+	(void)ChangeGC(pGC, GCForeground | GCBackground, attributes);
+    }
+
+   ValidateGC((DrawablePtr)pWin->background.pixmap, pGC);
+
+   from = (screenInfo.bitmapBitOrder == LSBFirst) ? _back_lsb : _back_msb;
+   to = back;
+
+   for (i = 4; i > 0; i--, from++)
+	for (j = len; j > 0; j--)
+	    *to++ = *from;
+
+   if (blackRoot)
+       bzero(back, sizeof(back));
+
+   (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1,
+		    0, 0, len, 4, 0, XYBitmap, (char *)back);
+
+   FreeScratchGC(pGC);
+
+}
+
+WindowPtr
+AllocateWindow(ScreenPtr pScreen)
+{
+    WindowPtr pWin;
+    register char *ptr;
+    register DevUnion *ppriv;
+    register unsigned *sizes;
+    register unsigned size;
+    register int i;
+
+    pWin = (WindowPtr)xalloc(pScreen->totalWindowSize);
+    if (pWin)
+    {
+	ppriv = (DevUnion *)(pWin + 1);
+	pWin->devPrivates = ppriv;
+	sizes = pScreen->WindowPrivateSizes;
+	ptr = (char *)(ppriv + pScreen->WindowPrivateLen);
+	for (i = pScreen->WindowPrivateLen; --i >= 0; ppriv++, sizes++)
+	{
+	    if ( (size = *sizes) )
+	    {
+		ppriv->ptr = (pointer)ptr;
+		ptr += size;
+	    }
+	    else
+		ppriv->ptr = (pointer)NULL;
+	}
+    }
+    return pWin;
+}
+
+/*****
+ * CreateRootWindow
+ *    Makes a window at initialization time for specified screen
+ *****/
+
+Bool
+CreateRootWindow(ScreenPtr pScreen)
+{
+    WindowPtr	pWin;
+    BoxRec	box;
+    PixmapFormatRec *format;
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+	return FALSE;
+
+    savedScreenInfo[pScreen->myNum].pWindow = NULL;
+    savedScreenInfo[pScreen->myNum].wid = FakeClientID(0);
+    savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+    screenIsSaved = SCREEN_SAVER_OFF;
+
+    WindowTable[pScreen->myNum] = pWin;
+
+    pWin->drawable.pScreen = pScreen;
+    pWin->drawable.type = DRAWABLE_WINDOW;
+
+    pWin->drawable.depth = pScreen->rootDepth;
+    for (format = screenInfo.formats;
+	 format->depth != pScreen->rootDepth;
+	 format++)
+	;
+    pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->parent = NullWindow;
+    SetWindowToDefaults(pWin);
+
+    pWin->optional = (WindowOptRec *) xalloc (sizeof (WindowOptRec));
+    if (!pWin->optional)
+        return FALSE;
+
+    pWin->optional->dontPropagateMask = 0;
+    pWin->optional->otherEventMasks = 0;
+    pWin->optional->otherClients = NULL;
+    pWin->optional->passiveGrabs = NULL;
+    pWin->optional->userProps = NULL;
+    pWin->optional->backingBitPlanes = ~0L;
+    pWin->optional->backingPixel = 0;
+#ifdef SHAPE
+    pWin->optional->boundingShape = NULL;
+    pWin->optional->clipShape = NULL;
+    pWin->optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+    pWin->optional->inputMasks = NULL;
+#endif
+    pWin->optional->colormap = pScreen->defColormap;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->nextSib = NullWindow;
+
+    pWin->drawable.id = FakeClientID(0);
+
+    pWin->origin.x = pWin->origin.y = 0;
+    pWin->drawable.height = pScreen->height;
+    pWin->drawable.width = pScreen->width;
+    pWin->drawable.x = pWin->drawable.y = 0;
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = pScreen->width;
+    box.y2 = pScreen->height;
+    REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+    REGION_INIT(pScreen, &pWin->winSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderSize, &box, 1);
+    REGION_INIT(pScreen, &pWin->borderClip, &box, 1);
+
+    pWin->drawable.class = InputOutput;
+    pWin->optional->visual = pScreen->rootVisual;
+
+    pWin->backgroundState = BackgroundPixel;
+    pWin->background.pixel = pScreen->whitePixel;
+
+    pWin->borderIsPixel = TRUE;
+    pWin->border.pixel = pScreen->blackPixel;
+    pWin->borderWidth = 0;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+	return FALSE;
+
+    if (disableBackingStore)
+	pScreen->backingStoreSupport = NotUseful;
+    if (enableBackingStore)
+	pScreen->backingStoreSupport = Always;
+
+#ifdef DO_SAVE_UNDERS
+    if ((pScreen->backingStoreSupport != NotUseful) &&
+	(pScreen->saveUnderSupport == NotUseful))
+    {
+	/*
+	 * If the screen has backing-store but no save-unders, let the
+	 * clients know we can support save-unders using backing-store.
+	 */
+	pScreen->saveUnderSupport = USE_DIX_SAVE_UNDERS;
+    }
+#endif /* DO_SAVE_UNDERS */
+		
+    if (disableSaveUnders)
+	pScreen->saveUnderSupport = NotUseful;
+
+    return TRUE;
+}
+
+void
+InitRootWindow(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!(*pScreen->CreateWindow)(pWin))
+	return; /* XXX */
+    (*pScreen->PositionWindow)(pWin, 0, 0);
+
+    pWin->cursorIsNone = FALSE;
+    pWin->optional->cursor = rootCursor;
+    rootCursor->refcnt++;
+    MakeRootTile(pWin);
+    pWin->backingStore = defaultBackingStore;
+    pWin->forcedBS = (defaultBackingStore != NotUseful);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin,
+		       CWBackPixmap|CWBorderPixel|CWCursor|CWBackingStore);
+
+    MapWindow(pWin, serverClient);
+}
+
+/* Set the region to the intersection of the rectangle and the
+ * window's winSize.  The window is typically the parent of the
+ * window from which the region came.
+ */
+
+void
+ClippedRegionFromBox(register WindowPtr pWin, RegionPtr Rgn,
+                     register int x, register int y,
+                     register int w, register int h)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    BoxRec box;
+
+    box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+    /* we do these calculations to avoid overflows */
+    if (x > box.x1)
+	box.x1 = x;
+    if (y > box.y1)
+	box.y1 = y;
+    x += w;
+    if (x < box.x2)
+	box.x2 = x;
+    y += h;
+    if (y < box.y2)
+	box.y2 = y;
+    if (box.x1 > box.x2)
+	box.x2 = box.x1;
+    if (box.y1 > box.y2)
+	box.y2 = box.y1;
+    REGION_RESET(pScreen, Rgn, &box);
+    REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize);
+}
+
+WindowPtr
+RealChildHead(register WindowPtr pWin)
+{
+    if (!pWin->parent &&
+	(screenIsSaved == SCREEN_SAVER_ON) &&
+	(HasSaverWindow (pWin->drawable.pScreen->myNum)))
+	return (pWin->firstChild);
+    else
+	return (NullWindow);
+}
+
+/*****
+ * CreateWindow
+ *    Makes a window in response to client request 
+ *****/
+
+WindowPtr
+CreateWindow(Window wid, register WindowPtr pParent, int x, int y, unsigned w,
+             unsigned h, unsigned bw, unsigned class, register Mask vmask, XID *vlist,
+             int depth, ClientPtr client, VisualID visual, int *error)
+{
+    register WindowPtr pWin;
+    WindowPtr pHead;
+    register ScreenPtr pScreen;
+    xEvent event;
+    int idepth, ivisual;
+    Bool fOK;
+    DepthPtr pDepth;
+    PixmapFormatRec *format;
+    register WindowOptPtr ancwopt;
+
+    if (class == CopyFromParent)
+	class = pParent->drawable.class;
+
+    if ((class != InputOutput) && (class != InputOnly))
+    {
+	*error = BadValue;
+	client->errorValue = class;
+	return NullWindow;
+    }
+
+    if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pScreen = pParent->drawable.pScreen;
+    if ((class == InputOutput) && (depth == 0))
+	 depth = pParent->drawable.depth;
+    ancwopt = pParent->optional;
+    if (!ancwopt)
+	ancwopt = FindWindowWithOptional(pParent)->optional;
+    if (visual == CopyFromParent) {
+#ifdef XAPPGROUP
+	VisualID ag_visual;
+
+	if (client->appgroup && !pParent->parent &&
+	    (ag_visual = XagRootVisual (client)))
+	    visual = ag_visual;
+	else
+#endif
+	visual = ancwopt->visual;
+    }
+
+    /* Find out if the depth and visual are acceptable for this Screen */
+    if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+    {
+	fOK = FALSE;
+	for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+	{
+	    pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+	    if ((depth == pDepth->depth) || (depth == 0))
+	    {
+		for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+		{
+		    if (visual == pDepth->vids[ivisual])
+		    {
+			fOK = TRUE;
+			break;
+		    }
+		}
+	    }
+	}
+	if (fOK == FALSE)
+	{
+	    *error = BadMatch;
+	    return NullWindow;
+	}
+    }
+
+    if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+	(class != InputOnly) &&
+	(depth != pParent->drawable.depth))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    if (((vmask & CWColormap) == 0) &&
+	(class != InputOnly) &&
+	((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+    {
+	*error = BadMatch;
+	return NullWindow;
+    }
+
+    pWin = AllocateWindow(pScreen);
+    if (!pWin)
+    {
+	*error = BadAlloc;
+	return NullWindow;
+    }
+    pWin->drawable = pParent->drawable;
+    pWin->drawable.depth = depth;
+    if (depth == pParent->drawable.depth)
+	pWin->drawable.bitsPerPixel = pParent->drawable.bitsPerPixel;
+    else
+    {
+	for (format = screenInfo.formats; format->depth != depth; format++)
+	    ;
+	pWin->drawable.bitsPerPixel = format->bitsPerPixel;
+    }
+    if (class == InputOnly)
+	pWin->drawable.type = (short) UNDRAWABLE_WINDOW;
+    pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+    pWin->drawable.id = wid;
+    pWin->drawable.class = class;
+
+    pWin->parent = pParent;
+    SetWindowToDefaults(pWin);
+
+    if (visual != ancwopt->visual)
+    {
+	if (!MakeWindowOptional (pWin))
+	{
+	    xfree (pWin);
+	    *error = BadAlloc;
+	    return NullWindow;
+	}
+	pWin->optional->visual = visual;
+	pWin->optional->colormap = None;
+    }
+
+    pWin->borderWidth = bw;
+#ifdef XCSECURITY
+    /*  can't let untrusted clients have background None windows;
+     *  they make it too easy to steal window contents
+     */
+    if (client->trustLevel != XSecurityClientTrusted)
+    {
+	pWin->backgroundState = BackgroundPixel;
+	pWin->background.pixel = 0;
+    }
+    else
+#endif
+    pWin->backgroundState = None;
+
+    pWin->borderIsPixel = pParent->borderIsPixel;
+    pWin->border = pParent->border;
+    if (pWin->borderIsPixel == FALSE)
+	pWin->border.pixmap->refcnt++;
+		
+    pWin->origin.x = x + (int)bw;
+    pWin->origin.y = y + (int)bw;
+    pWin->drawable.width = w;
+    pWin->drawable.height = h;
+    pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+    pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+	/* set up clip list correctly for unobscured WindowPtr */
+    REGION_NULL(pScreen, &pWin->clipList);
+    REGION_NULL(pScreen, &pWin->borderClip);
+    REGION_NULL(pScreen, &pWin->winSize);
+    REGION_NULL(pScreen, &pWin->borderSize);
+
+    pHead = RealChildHead(pParent);
+    if (pHead)
+    {
+	pWin->nextSib = pHead->nextSib;
+	if (pHead->nextSib)
+	    pHead->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pHead->nextSib = pWin;
+	pWin->prevSib = pHead;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    /* We SHOULD check for an error value here XXX */
+    if (!(*pScreen->CreateWindow)(pWin))
+    {
+	*error = BadAlloc;
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+
+    if (!(vmask & CWEventMask))
+	RecalculateDeliverableEvents(pWin);
+
+    if (vmask)
+	*error = ChangeWindowAttributes(pWin, vmask, vlist, wClient (pWin));
+    else
+	*error = Success;
+
+    if (*error != Success)
+    {
+	DeleteWindow(pWin, None);
+	return NullWindow;
+    }
+    if (!(vmask & CWBackingStore) && (defaultBackingStore != NotUseful))
+    {
+	XID value = defaultBackingStore;
+	(void)ChangeWindowAttributes(pWin, CWBackingStore, &value, wClient (pWin));
+	pWin->forcedBS = TRUE;
+    }
+
+    if (SubSend(pParent))
+    {
+	event.u.u.type = CreateNotify;
+	event.u.createNotify.window = wid;
+	event.u.createNotify.parent = pParent->drawable.id;
+	event.u.createNotify.x = x;
+	event.u.createNotify.y = y;
+	event.u.createNotify.width = w;
+	event.u.createNotify.height = h;
+	event.u.createNotify.borderWidth = bw;
+	event.u.createNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pParent, &event, 1, NullWindow);		
+    }
+    return pWin;
+}
+
+static void
+FreeWindowResources(register WindowPtr pWin)
+{
+    register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DeleteWindowFromAnySaveSet(pWin);
+    DeleteWindowFromAnySelections(pWin);
+    DeleteWindowFromAnyEvents(pWin, TRUE);
+    REGION_UNINIT(pScreen, &pWin->clipList);
+    REGION_UNINIT(pScreen, &pWin->winSize);
+    REGION_UNINIT(pScreen, &pWin->borderClip);
+    REGION_UNINIT(pScreen, &pWin->borderSize);
+#ifdef SHAPE
+    if (wBoundingShape (pWin))
+	REGION_DESTROY(pScreen, wBoundingShape (pWin));
+    if (wClipShape (pWin))
+	REGION_DESTROY(pScreen, wClipShape (pWin));
+    if (wInputShape (pWin))
+	REGION_DESTROY(pScreen, wInputShape (pWin));
+#endif
+    if (pWin->borderIsPixel == FALSE)
+	(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+    if (pWin->backgroundState == BackgroundPixmap)
+	(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+
+    DeleteAllWindowProperties(pWin);
+    /* We SHOULD check for an error value here XXX */
+    (*pScreen->DestroyWindow)(pWin);
+    DisposeWindowOptional (pWin);
+}
+
+static void
+CrushTree(WindowPtr pWin)
+{
+    register WindowPtr pChild, pSib, pParent;
+    UnrealizeWindowProcPtr UnrealizeWindow;
+    xEvent event;
+
+    if (!(pChild = pWin->firstChild))
+	return;
+    UnrealizeWindow = pWin->drawable.pScreen->UnrealizeWindow;
+    while (1)
+    {
+	if (pChild->firstChild)
+	{
+	    pChild = pChild->firstChild;
+	    continue;
+	}
+	while (1)
+	{
+	    pParent = pChild->parent;
+	    if (SubStrSend(pChild, pParent))
+	    {
+		event.u.u.type = DestroyNotify;
+		event.u.destroyNotify.window = pChild->drawable.id;
+		DeliverEvents(pChild, &event, 1, NullWindow);		
+	    }
+	    FreeResource(pChild->drawable.id, RT_WINDOW);
+	    pSib = pChild->nextSib;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder && pChild->viewable)
+		deltaSaveUndersViewable--;
+#endif
+	    pChild->viewable = FALSE;
+	    if (pChild->realized)
+	    {
+		pChild->realized = FALSE;
+		(*UnrealizeWindow)(pChild);
+	    }
+	    FreeWindowResources(pChild);
+	    xfree(pChild);
+	    if ( (pChild = pSib) )
+		break;
+	    pChild = pParent;
+	    pChild->firstChild = NullWindow;
+	    pChild->lastChild = NullWindow;
+	    if (pChild == pWin)
+		return;
+	}
+    }
+}
+	
+/*****
+ *  DeleteWindow
+ *	 Deletes child of window then window itself
+ *	 If wid is None, don't send any events
+ *****/
+
+int
+DeleteWindow(pointer value, XID wid)
+ {
+    register WindowPtr pParent;
+    register WindowPtr pWin = (WindowPtr)value;
+    xEvent event;
+
+    UnmapWindow(pWin, FALSE);
+
+    CrushTree(pWin);
+
+    pParent = pWin->parent;
+    if (wid && pParent && SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = DestroyNotify;
+	event.u.destroyNotify.window = pWin->drawable.id;
+	DeliverEvents(pWin, &event, 1, NullWindow);		
+    }
+
+    FreeWindowResources(pWin);
+    if (pParent)
+    {
+	if (pParent->firstChild == pWin)
+	    pParent->firstChild = pWin->nextSib;
+	if (pParent->lastChild == pWin)
+	    pParent->lastChild = pWin->prevSib;
+	if (pWin->nextSib)
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	if (pWin->prevSib)
+	    pWin->prevSib->nextSib = pWin->nextSib;
+    }
+    xfree(pWin);
+    return Success;
+}
+
+void
+DestroySubwindows(register WindowPtr pWin, ClientPtr client)
+{
+    /* XXX
+     * The protocol is quite clear that each window should be
+     * destroyed in turn, however, unmapping all of the first
+     * eliminates most of the calls to ValidateTree.  So,
+     * this implementation is incorrect in that all of the
+     * UnmapNotifies occur before all of the DestroyNotifies.
+     * If you care, simply delete the call to UnmapSubwindows.
+     */
+    UnmapSubwindows(pWin);
+    while (pWin->lastChild)
+	FreeResource(pWin->lastChild->drawable.id, RT_NONE);
+}
+
+#define DeviceEventMasks (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
+    ButtonReleaseMask | PointerMotionMask)
+
+/*****
+ *  ChangeWindowAttributes
+ *   
+ *  The value-mask specifies which attributes are to be changed; the
+ *  value-list contains one value for each one bit in the mask, from least
+ *  to most significant bit in the mask.  
+ *****/
+ 
+int
+ChangeWindowAttributes(register WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
+{
+    register Mask index2;
+    register XID *pVlist;
+    PixmapPtr pPixmap;
+    Pixmap pixID;
+    CursorPtr pCursor, pOldCursor;
+    Cursor cursorID;
+    WindowPtr pChild;
+    Colormap cmap;
+    ColormapPtr	pCmap;
+    xEvent xE;
+    int result;
+    register ScreenPtr pScreen;
+    Mask vmaskCopy = 0;
+    register Mask tmask;
+    unsigned int val;
+    int error;
+    Bool checkOptional = FALSE;
+    Bool borderRelative = FALSE;
+    WindowPtr pLayerWin;
+
+    if ((pWin->drawable.class == InputOnly) && (vmask & (~INPUTONLY_LEGAL_MASK)))
+	return BadMatch;
+
+    error = Success;
+    pScreen = pWin->drawable.pScreen;
+    pVlist = vlist;
+    tmask = vmask;
+    while (tmask)
+    {
+	index2 = (Mask) lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBackPixmap:
+	    pixID = (Pixmap )*pVlist;
+	    pVlist++;
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pixID == None)
+	    {
+#ifdef XCSECURITY
+		/*  can't let untrusted clients have background None windows */
+		if (client->trustLevel == XSecurityClientTrusted)
+		{
+#endif
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = None;
+#ifdef XCSECURITY
+		}
+		else
+		{ /* didn't change the background to None, so don't tell ddx */
+		    index2 = 0; 
+		}
+#endif
+	    }
+	    else if (pixID == ParentRelative)
+	    {
+		if (pWin->parent &&
+		    pWin->drawable.depth != pWin->parent->drawable.depth)
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->backgroundState == BackgroundPixmap)
+		    (*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		if (!pWin->parent)
+		    MakeRootTile(pWin);
+		else
+		    pWin->backgroundState = ParentRelative;
+		borderRelative = TRUE;
+		/* Note that the parent's backgroundTile's refcnt is NOT
+		 * incremented. */
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+						RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap != (PixmapPtr) NULL)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->backgroundState == BackgroundPixmap)
+			(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+		    pWin->backgroundState = BackgroundPixmap;
+		    pWin->background.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBackPixel:
+	    if (pWin->backgroundState == ParentRelative)
+		borderRelative = TRUE;
+	    if (pWin->backgroundState == BackgroundPixmap)
+		(*pScreen->DestroyPixmap)(pWin->background.pixmap);
+	    pWin->backgroundState = BackgroundPixel;
+	    pWin->background.pixel = (CARD32 ) *pVlist;
+		   /* background pixel overrides background pixmap,
+		      so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBackPixmap;
+	    pVlist++;
+	    break;
+	  case CWBorderPixmap:
+	    pixID = (Pixmap ) *pVlist;
+	    pVlist++;
+	    if (pixID == CopyFromParent)
+	    {
+		if (!pWin->parent ||
+		    (pWin->drawable.depth != pWin->parent->drawable.depth))
+		{
+		    error = BadMatch;
+		    goto PatchUp;
+		}
+		if (pWin->borderIsPixel == FALSE)
+		    (*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		pWin->border = pWin->parent->border;
+		if ((pWin->borderIsPixel = pWin->parent->borderIsPixel) == TRUE)
+		{
+		    index2 = CWBorderPixel;
+		}
+		else
+		{
+		    pWin->parent->border.pixmap->refcnt++;
+		}
+	    }
+	    else
+	    {	
+		pPixmap = (PixmapPtr)SecurityLookupIDByType(client, pixID,
+					RT_PIXMAP, SecurityReadAccess);
+		if (pPixmap)
+		{
+		    if	((pPixmap->drawable.depth != pWin->drawable.depth) ||
+			 (pPixmap->drawable.pScreen != pScreen))
+		    {
+			error = BadMatch;
+			goto PatchUp;
+		    }
+		    if (pWin->borderIsPixel == FALSE)
+			(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+		    pWin->borderIsPixel = FALSE;
+		    pWin->border.pixmap = pPixmap;
+		    pPixmap->refcnt++;
+		}
+		else
+		{
+		    error = BadPixmap;
+		    client->errorValue = pixID;
+		    goto PatchUp;
+		}
+	    }
+	    break;
+	  case CWBorderPixel:
+	    if (pWin->borderIsPixel == FALSE)
+		(*pScreen->DestroyPixmap)(pWin->border.pixmap);
+	    pWin->borderIsPixel = TRUE;
+	    pWin->border.pixel = (CARD32) *pVlist;
+		    /* border pixel overrides border pixmap,
+		       so don't let the ddx layer see both bits */
+	    vmaskCopy &= ~CWBorderPixmap;
+	    pVlist++;
+	    break;
+	  case CWBitGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->bitGravity = val;
+	    break;
+	  case CWWinGravity:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if (val > StaticGravity)
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->winGravity = val;
+	    break;
+	  case CWBackingStore:
+	    val = (CARD8 )*pVlist;
+	    pVlist++;
+	    if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->backingStore = val;
+	    pWin->forcedBS = FALSE;
+	    break;
+	  case CWBackingPlanes:
+	    if (pWin->optional || ((CARD32)*pVlist != (CARD32)~0L)) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingBitPlanes = (CARD32) *pVlist;
+		if ((CARD32)*pVlist == (CARD32)~0L)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWBackingPixel:
+	    if (pWin->optional || (CARD32) *pVlist) {
+		if (!pWin->optional && !MakeWindowOptional (pWin))
+		{
+		    error = BadAlloc;
+		    goto PatchUp;
+		}
+		pWin->optional->backingPixel = (CARD32) *pVlist;
+		if (!*pVlist)
+		    checkOptional = TRUE;
+	    }
+	    pVlist++;
+	    break;
+	  case CWSaveUnder:
+	    val = (BOOL) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (pWin->parent && (pWin->saveUnder != val) && (pWin->viewable) &&
+		DO_SAVE_UNDERS(pWin))
+	    {
+		/*
+		 * Re-check all siblings and inferiors for obscurity or
+		 * exposition (hee hee).
+		 */
+		if (pWin->saveUnder)
+		    deltaSaveUndersViewable--;
+		else
+		    deltaSaveUndersViewable++;
+		pWin->saveUnder = val;
+
+		if (pWin->firstChild)
+		{
+                    pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+                   if ((*pScreen->ChangeSaveUnder)(pLayerWin->parent, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pLayerWin->parent,
+                                                       pWin->nextSib);
+               }
+               else
+               {
+                   if ((*pScreen->ChangeSaveUnder)(pWin, pWin->nextSib))
+                       (*pScreen->PostChangeSaveUnder)(pWin,
+                                                       pWin->nextSib);
+               }                                   
+	    }
+	    else
+	    {
+		/*  If we're changing the saveUnder attribute of the root 
+		 *  window, all we do is set pWin->saveUnder so that
+		 *  GetWindowAttributes returns the right value.  We don't
+		 *  do the "normal" save-under processing (as above).
+		 *  Hope that doesn't cause any problems.
+		 */
+		pWin->saveUnder = val;
+	    }
+#else
+	    pWin->saveUnder = val;
+#endif /* DO_SAVE_UNDERS */
+	    break;
+	  case CWEventMask:
+	    result = EventSelectForWindow(pWin, client, (Mask )*pVlist);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWDontPropagate:
+	    result = EventSuppressForWindow(pWin, client, (Mask )*pVlist,
+					    &checkOptional);
+	    if (result)
+	    {
+		error = result;
+		goto PatchUp;
+	    }
+	    pVlist++;
+	    break;
+	  case CWOverrideRedirect:
+	    val = (BOOL ) *pVlist;
+	    pVlist++;
+	    if ((val != xTrue) && (val != xFalse))
+	    {
+		error = BadValue;
+		client->errorValue = val;
+		goto PatchUp;
+	    }
+	    pWin->overrideRedirect = val;
+	    break;
+	  case CWColormap:
+	    cmap = (Colormap) *pVlist;
+	    pVlist++;
+	    if (cmap == CopyFromParent)
+	    {
+#ifdef XAPPGROUP
+		Colormap ag_colormap;
+		ClientPtr win_owner;
+
+		/*
+		 * win_owner == client for CreateWindow, other clients
+		 * can ChangeWindowAttributes
+		 */
+		win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+
+		if ( win_owner && win_owner->appgroup &&
+		    !pWin->parent->parent &&
+		    (ag_colormap = XagDefaultColormap (win_owner)))
+		    cmap = ag_colormap;
+		else
+#endif
+		if (pWin->parent &&
+		    (!pWin->optional ||
+		     pWin->optional->visual == wVisual (pWin->parent)))
+		{
+		    cmap = wColormap (pWin->parent);
+		}
+		else
+		    cmap = None;
+	    }
+	    if (cmap == None)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    pCmap = (ColormapPtr)SecurityLookupIDByType(client, cmap,
+					      RT_COLORMAP, SecurityReadAccess);
+	    if (!pCmap)
+	    {
+		error = BadColor;
+		client->errorValue = cmap;
+		goto PatchUp;
+	    }
+	    if (pCmap->pVisual->vid != wVisual (pWin) ||
+		pCmap->pScreen != pScreen)
+	    {
+		error = BadMatch;
+		goto PatchUp;
+	    }
+	    if (cmap != wColormap (pWin))
+	    {
+		if (!pWin->optional)
+		{
+		    if (!MakeWindowOptional (pWin))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+		else if (pWin->parent && cmap == wColormap (pWin->parent))
+		    checkOptional = TRUE;
+
+		/*
+		 * propagate the original colormap to any children
+		 * inheriting it
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pWin->optional->colormap = cmap;
+
+		/*
+		 * check on any children now matching the new colormap
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (pChild->optional->colormap == cmap)
+			CheckWindowOptionalNeed (pChild);
+		}
+	
+		xE.u.u.type = ColormapNotify;
+		xE.u.colormap.window = pWin->drawable.id;
+		xE.u.colormap.colormap = cmap;
+		xE.u.colormap.new = xTrue;
+		xE.u.colormap.state = IsMapInstalled(cmap, pWin);
+		DeliverEvents(pWin, &xE, 1, NullWindow);
+	    }
+	    break;
+	  case CWCursor:
+	    cursorID = (Cursor ) *pVlist;
+	    pVlist++;
+	    /*
+	     * install the new
+	     */
+	    if ( cursorID == None)
+	    {
+		if (pWin == WindowTable[pWin->drawable.pScreen->myNum])
+		    pCursor = rootCursor;
+		else
+		    pCursor = (CursorPtr) None;
+	    }
+	    else
+	    {
+		pCursor = (CursorPtr)SecurityLookupIDByType(client, cursorID,
+						RT_CURSOR, SecurityReadAccess);
+		if (!pCursor)
+		{
+		    error = BadCursor;
+		    client->errorValue = cursorID;
+		    goto PatchUp;
+		}
+	    }
+
+	    if (pCursor != wCursor (pWin))
+	    {
+		/*
+		 * patch up child windows so they don't lose cursors.
+		 */
+
+		for (pChild = pWin->firstChild; pChild; pChild=pChild->nextSib)
+		{
+		    if (!pChild->optional && !pChild->cursorIsNone &&
+			!MakeWindowOptional (pChild))
+		    {
+			error = BadAlloc;
+			goto PatchUp;
+		    }
+		}
+
+		pOldCursor = 0;
+		if (pCursor == (CursorPtr) None)
+		{
+		    pWin->cursorIsNone = TRUE;
+		    if (pWin->optional)
+		    {
+			pOldCursor = pWin->optional->cursor;
+			pWin->optional->cursor = (CursorPtr) None;
+			checkOptional = TRUE;
+		    }
+		} else {
+		    if (!pWin->optional)
+		    {
+			if (!MakeWindowOptional (pWin))
+			{
+			    error = BadAlloc;
+			    goto PatchUp;
+			}
+		    }
+		    else if (pWin->parent && pCursor == wCursor (pWin->parent))
+			checkOptional = TRUE;
+		    pOldCursor = pWin->optional->cursor;
+		    pWin->optional->cursor = pCursor;
+		    pCursor->refcnt++;
+		    pWin->cursorIsNone = FALSE;
+		    /*
+		     * check on any children now matching the new cursor
+		     */
+
+		    for (pChild=pWin->firstChild; pChild; pChild=pChild->nextSib)
+		    {
+			if (pChild->optional &&
+			    (pChild->optional->cursor == pCursor))
+			    CheckWindowOptionalNeed (pChild);
+		    }
+		}
+
+		if (pWin->realized)
+		    WindowHasNewCursor( pWin);
+
+		/* Can't free cursor until here - old cursor
+		 * is needed in WindowHasNewCursor
+		 */
+		if (pOldCursor)
+		    FreeCursor (pOldCursor, (Cursor)0);
+	    }
+	    break;
+	 default:
+	    error = BadValue;
+	    client->errorValue = vmask;
+	    goto PatchUp;
+      }
+      vmaskCopy |= index2;
+    }
+PatchUp:
+    if (checkOptional)
+	CheckWindowOptionalNeed (pWin);
+
+	/* We SHOULD check for an error value here XXX */
+    (*pScreen->ChangeWindowAttributes)(pWin, vmaskCopy);
+
+    /* 
+	If the border contents have changed, redraw the border. 
+	Note that this has to be done AFTER pScreen->ChangeWindowAttributes
+	for the tile to be rotated, and the correct function selected.
+    */
+    if (((vmaskCopy & (CWBorderPixel | CWBorderPixmap)) || borderRelative)
+	&& pWin->viewable && HasBorder (pWin))
+    {
+	RegionRec exposed;
+
+	REGION_NULL(pScreen, &exposed);
+	REGION_SUBTRACT(pScreen, &exposed, &pWin->borderClip, &pWin->winSize);
+	(*pWin->drawable.pScreen->PaintWindowBorder)(pWin, &exposed, PW_BORDER);
+	REGION_UNINIT(pScreen, &exposed);
+    }
+    return error;
+}
+
+
+/*****
+ * GetWindowAttributes
+ *    Notice that this is different than ChangeWindowAttributes
+ *****/
+
+void
+GetWindowAttributes(register WindowPtr pWin, ClientPtr client, xGetWindowAttributesReply *wa)
+{
+    wa->type = X_Reply;
+    wa->bitGravity = pWin->bitGravity;
+    wa->winGravity = pWin->winGravity;
+    if (pWin->forcedBS && pWin->backingStore != Always)
+	wa->backingStore = NotUseful;
+    else
+	wa->backingStore = pWin->backingStore;
+    wa->length = (sizeof(xGetWindowAttributesReply) -
+		 sizeof(xGenericReply)) >> 2;
+    wa->sequenceNumber = client->sequence;
+    wa->backingBitPlanes =  wBackingBitPlanes (pWin);
+    wa->backingPixel =  wBackingPixel (pWin);
+    wa->saveUnder = (BOOL)pWin->saveUnder;
+    wa->override = pWin->overrideRedirect;
+    if (!pWin->mapped)
+	wa->mapState = IsUnmapped;
+    else if (pWin->realized)
+	wa->mapState = IsViewable;
+    else
+	wa->mapState = IsUnviewable;
+
+    wa->colormap =  wColormap (pWin);
+    wa->mapInstalled = (wa->colormap == None) ? xFalse
+				: IsMapInstalled(wa->colormap, pWin);
+
+    wa->yourEventMask = EventMaskForClient(pWin, client);
+    wa->allEventMasks = pWin->eventMask | wOtherEventMasks (pWin);
+    wa->doNotPropagateMask = wDontPropagateMask (pWin);
+    wa->class = pWin->drawable.class;
+    wa->visualID = wVisual (pWin);
+}
+
+
+WindowPtr
+MoveWindowInStack(register WindowPtr pWin, register WindowPtr pNextSib)
+{
+    register WindowPtr pParent = pWin->parent;
+    WindowPtr pFirstChange = pWin; /* highest window where list changes */
+
+    if (pWin->nextSib != pNextSib)
+    {
+	WindowPtr pOldNextSib = pWin->nextSib;
+
+	if (!pNextSib)	      /* move to bottom */
+	{
+	    if (pParent->firstChild == pWin)
+		pParent->firstChild = pWin->nextSib;
+	    /* if (pWin->nextSib) */	 /* is always True: pNextSib == NULL
+					  * and pWin->nextSib != pNextSib
+					  * therefore pWin->nextSib != NULL */
+	    pFirstChange = pWin->nextSib;
+	    pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pParent->lastChild->nextSib = pWin;
+	    pWin->prevSib = pParent->lastChild;
+	    pWin->nextSib = NullWindow;
+	    pParent->lastChild = pWin;
+	}
+	else if (pParent->firstChild == pNextSib) /* move to top */
+	{
+	    pFirstChange = pWin;
+	    if (pParent->lastChild == pWin)
+	       pParent->lastChild = pWin->prevSib;
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pParent->firstChild;
+	    pWin->prevSib = (WindowPtr ) NULL;
+	    pNextSib->prevSib = pWin;
+	    pParent->firstChild = pWin;
+	}
+	else			/* move in middle of list */
+	{
+	    WindowPtr pOldNext = pWin->nextSib;
+
+	    pFirstChange = NullWindow;
+	    if (pParent->firstChild == pWin)
+		pFirstChange = pParent->firstChild = pWin->nextSib;
+	    if (pParent->lastChild == pWin) {
+	       pFirstChange = pWin;
+	       pParent->lastChild = pWin->prevSib;
+	    }
+	    if (pWin->nextSib)
+		pWin->nextSib->prevSib = pWin->prevSib;
+	    if (pWin->prevSib)
+		pWin->prevSib->nextSib = pWin->nextSib;
+	    pWin->nextSib = pNextSib;
+	    pWin->prevSib = pNextSib->prevSib;
+	    if (pNextSib->prevSib)
+		pNextSib->prevSib->nextSib = pWin;
+	    pNextSib->prevSib = pWin;
+	    if (!pFirstChange) {		     /* do we know it yet? */
+		pFirstChange = pParent->firstChild;  /* no, search from top */
+		while ((pFirstChange != pWin) && (pFirstChange != pOldNext))
+		     pFirstChange = pFirstChange->nextSib;
+	    }
+	}
+	if(pWin->drawable.pScreen->RestackWindow)
+	    (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib);
+    }
+
+#ifdef ROOTLESS
+    /*
+     * In rootless mode we can't optimize away window restacks.
+     * There may be non-X windows around, so even if the window
+     * is in the correct position from X's point of view,
+     * the underlying window system may want to reorder it.
+     */
+    else if (pWin->drawable.pScreen->RestackWindow)
+        (*pWin->drawable.pScreen->RestackWindow)(pWin, pWin->nextSib);
+#endif
+
+    return( pFirstChange );
+}
+
+RegionPtr
+CreateUnclippedWinSize (register WindowPtr pWin)
+{
+    RegionPtr	pRgn;
+    BoxRec	box;
+
+    box.x1 = pWin->drawable.x;
+    box.y1 = pWin->drawable.y;
+    box.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+    box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+    pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	ScreenPtr pScreen = pWin->drawable.pScreen;
+
+	REGION_TRANSLATE(pScreen, pRgn, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x, pWin->drawable.y);
+    }
+#endif
+    return pRgn;
+}
+
+void
+SetWinSize (register WindowPtr pWin)
+{
+#ifdef COMPOSITE
+    if (pWin->redirectDraw)
+    {
+	BoxRec	box;
+
+	box.x1 = pWin->drawable.x;
+	box.y1 = pWin->drawable.y;
+	box.x2 = pWin->drawable.x + pWin->drawable.width;
+	box.y2 = pWin->drawable.y + pWin->drawable.height;
+	REGION_RESET (pScreen, &pWin->winSize, &box);
+    }
+    else
+#endif
+    ClippedRegionFromBox(pWin->parent, &pWin->winSize,
+			 pWin->drawable.x, pWin->drawable.y,
+			 (int)pWin->drawable.width,
+			 (int)pWin->drawable.height);
+#ifdef SHAPE
+    if (wBoundingShape (pWin) || wClipShape (pWin)) {
+	ScreenPtr pScreen = pWin->drawable.pScreen;
+
+	REGION_TRANSLATE(pScreen, &pWin->winSize, - pWin->drawable.x,
+			 - pWin->drawable.y);
+	if (wBoundingShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wBoundingShape (pWin));
+	if (wClipShape (pWin))
+	    REGION_INTERSECT(pScreen, &pWin->winSize, &pWin->winSize,
+			     wClipShape (pWin));
+	REGION_TRANSLATE(pScreen, &pWin->winSize, pWin->drawable.x,
+			 pWin->drawable.y);
+    }
+#endif
+}
+
+void
+SetBorderSize (register WindowPtr pWin)
+{
+    int	bw;
+
+    if (HasBorder (pWin)) {
+	bw = wBorderWidth (pWin);
+#ifdef COMPOSITE
+	if (pWin->redirectDraw)
+	{
+	    BoxRec	box;
+
+	    box.x1 = pWin->drawable.x - bw;
+	    box.y1 = pWin->drawable.y - bw;
+	    box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
+	    box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
+	    REGION_RESET (pScreen, &pWin->borderSize, &box);
+	}
+	else
+#endif
+	ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
+		pWin->drawable.x - bw, pWin->drawable.y - bw,
+		(int)(pWin->drawable.width + (bw<<1)),
+		(int)(pWin->drawable.height + (bw<<1)));
+#ifdef SHAPE
+	if (wBoundingShape (pWin)) {
+	    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, - pWin->drawable.x,
+			     - pWin->drawable.y);
+	    REGION_INTERSECT(pScreen, &pWin->borderSize, &pWin->borderSize,
+			     wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, &pWin->borderSize, pWin->drawable.x,
+			     pWin->drawable.y);
+	    REGION_UNION(pScreen, &pWin->borderSize, &pWin->borderSize,
+			 &pWin->winSize);
+	}
+#endif
+    } else {
+	REGION_COPY(pWin->drawable.pScreen, &pWin->borderSize,
+					       &pWin->winSize);
+    }
+}
+
+/**
+ *
+ *  \param x,y          new window position
+ *  \param oldx,oldy    old window position
+ *  \param destx,desty  position relative to gravity
+ */
+
+void
+GravityTranslate (register int x, register int y, int oldx, int oldy,
+                  int dw, int dh, unsigned gravity,
+                  register int *destx, register int *desty)
+{
+    switch (gravity) {
+    case NorthGravity:
+	*destx = x + dw / 2;
+	*desty = y;
+	break;
+    case NorthEastGravity:
+	*destx = x + dw;
+	*desty = y;
+	break;
+    case WestGravity:
+	*destx = x;
+	*desty = y + dh / 2;
+	break;
+    case CenterGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh / 2;
+	break;
+    case EastGravity:
+	*destx = x + dw;
+	*desty = y + dh / 2;
+	break;
+    case SouthWestGravity:
+	*destx = x;
+	*desty = y + dh;
+	break;
+    case SouthGravity:
+	*destx = x + dw / 2;
+	*desty = y + dh;
+	break;
+    case SouthEastGravity:
+	*destx = x + dw;
+	*desty = y + dh;
+	break;
+    case StaticGravity:
+	*destx = oldx;
+	*desty = oldy;
+	break;
+    default:
+	*destx = x;
+	*desty = y;
+	break;
+    }
+}
+
+/* XXX need to retile border on each window with ParentRelative origin */
+void
+ResizeChildrenWinSize(register WindowPtr pWin, int dx, int dy, int dw, int dh)
+{
+    register ScreenPtr pScreen;
+    register WindowPtr pSib, pChild;
+    Bool resized = (dw || dh);
+
+    pScreen = pWin->drawable.pScreen;
+
+    for (pSib = pWin->firstChild; pSib; pSib = pSib->nextSib)
+    {
+	if (resized && (pSib->winGravity > NorthWestGravity))
+	{
+	    int cwsx, cwsy;
+
+	    cwsx = pSib->origin.x;
+	    cwsy = pSib->origin.y;
+	    GravityTranslate (cwsx, cwsy, cwsx - dx, cwsy - dy, dw, dh,
+			pSib->winGravity, &cwsx, &cwsy);
+	    if (cwsx != pSib->origin.x || cwsy != pSib->origin.y)
+	    {
+		xEvent event;
+
+		event.u.u.type = GravityNotify;
+		event.u.gravity.window = pSib->drawable.id;
+		event.u.gravity.x = cwsx - wBorderWidth (pSib);
+		event.u.gravity.y = cwsy - wBorderWidth (pSib);
+		DeliverEvents (pSib, &event, 1, NullWindow);
+		pSib->origin.x = cwsx;
+		pSib->origin.y = cwsy;
+	    }
+	}
+	pSib->drawable.x = pWin->drawable.x + pSib->origin.x;
+	pSib->drawable.y = pWin->drawable.y + pSib->origin.y;
+	SetWinSize (pSib);
+	SetBorderSize (pSib);
+	(*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y);
+
+	if ( (pChild = pSib->firstChild) )
+	{
+	    while (1)
+	    {
+		pChild->drawable.x = pChild->parent->drawable.x +
+				     pChild->origin.x;
+		pChild->drawable.y = pChild->parent->drawable.y +
+				     pChild->origin.y;
+		SetWinSize (pChild);
+		SetBorderSize (pChild);
+		(*pScreen->PositionWindow)(pChild,
+				    pChild->drawable.x, pChild->drawable.y);
+		if (pChild->firstChild)
+		{
+		    pChild = pChild->firstChild;
+		    continue;
+		}
+		while (!pChild->nextSib && (pChild != pSib))
+		    pChild = pChild->parent;
+		if (pChild == pSib)
+		    break;
+		pChild = pChild->nextSib;
+	    }
+	}
+    }
+}
+
+#define GET_INT16(m, f) \
+	if (m & mask) \
+	  { \
+	     f = (INT16) *pVlist;\
+	    pVlist++; \
+	 }
+#define GET_CARD16(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD16) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define GET_CARD8(m, f) \
+	if (m & mask) \
+	 { \
+	    f = (CARD8) *pVlist;\
+	    pVlist++;\
+	 }
+
+#define ChangeMask ((Mask)(CWX | CWY | CWWidth | CWHeight))
+
+#define IllegalInputOnlyConfigureMask (CWBorderWidth)
+
+/*
+ * IsSiblingAboveMe
+ *     returns Above if pSib above pMe in stack or Below otherwise 
+ */
+
+static int
+IsSiblingAboveMe(
+    register WindowPtr pMe,
+    register WindowPtr pSib)
+{
+    register WindowPtr pWin;
+
+    pWin = pMe->parent->firstChild;
+    while (pWin)
+    {
+	if (pWin == pSib)
+	    return(Above);
+	else if (pWin == pMe)
+	    return(Below);
+	pWin = pWin->nextSib;
+    }
+    return(Below);
+}
+
+static BoxPtr
+WindowExtents(
+    register WindowPtr pWin,
+    register BoxPtr pBox)
+{
+    pBox->x1 = pWin->drawable.x - wBorderWidth (pWin);
+    pBox->y1 = pWin->drawable.y - wBorderWidth (pWin);
+    pBox->x2 = pWin->drawable.x + (int)pWin->drawable.width
+	       + wBorderWidth (pWin);
+    pBox->y2 = pWin->drawable.y + (int)pWin->drawable.height
+	       + wBorderWidth (pWin);
+    return(pBox);
+}
+
+#ifdef SHAPE
+#define IS_SHAPED(pWin)	(wBoundingShape (pWin) != (RegionPtr) NULL)
+
+static RegionPtr
+MakeBoundingRegion (
+    register WindowPtr	pWin,
+    BoxPtr	pBox)
+{
+    RegionPtr	pRgn;
+    ScreenPtr   pScreen = pWin->drawable.pScreen;
+
+    pRgn = REGION_CREATE(pScreen, pBox, 1);
+    if (wBoundingShape (pWin)) {
+	    REGION_TRANSLATE(pScreen, pRgn, -pWin->origin.x,
+						  -pWin->origin.y);
+	    REGION_INTERSECT(pScreen, pRgn, pRgn, wBoundingShape (pWin));
+	    REGION_TRANSLATE(pScreen, pRgn, pWin->origin.x,
+						  pWin->origin.y);
+    }
+    return pRgn;
+}
+
+static Bool
+ShapeOverlap (
+    WindowPtr	pWin,
+    BoxPtr	pWinBox,
+    WindowPtr	pSib,
+    BoxPtr	pSibBox)
+{
+    RegionPtr	pWinRgn, pSibRgn;
+    register ScreenPtr	pScreen;
+    Bool	ret;
+
+    if (!IS_SHAPED(pWin) && !IS_SHAPED(pSib))
+	return TRUE;
+    pScreen = pWin->drawable.pScreen;
+    pWinRgn = MakeBoundingRegion (pWin, pWinBox);
+    pSibRgn = MakeBoundingRegion (pSib, pSibBox);
+    REGION_INTERSECT(pScreen, pWinRgn, pWinRgn, pSibRgn);
+    ret = REGION_NOTEMPTY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pWinRgn);
+    REGION_DESTROY(pScreen, pSibRgn);
+    return ret;
+}
+#endif
+
+static Bool
+AnyWindowOverlapsMe(
+    WindowPtr pWin,
+    WindowPtr pHead,
+    register BoxPtr box)
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->prevSib; pSib != pHead; pSib = pSib->prevSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+static Bool
+IOverlapAnyWindow(
+    WindowPtr pWin,
+    register BoxPtr box)
+{
+    register WindowPtr pSib;
+    BoxRec sboxrec;
+    register BoxPtr sbox;
+
+    for (pSib = pWin->nextSib; pSib; pSib = pSib->nextSib)
+    {
+	if (pSib->mapped)
+	{
+	    sbox = WindowExtents(pSib, &sboxrec);
+	    if (BOXES_OVERLAP(sbox, box)
+#ifdef SHAPE
+	    && ShapeOverlap (pWin, box, pSib, sbox)
+#endif
+	    )
+		return(TRUE);
+	}
+    }
+    return(FALSE);
+}
+
+/*
+ *   WhereDoIGoInTheStack() 
+ *	  Given pWin and pSib and the relationshipe smode, return
+ *	  the window that pWin should go ABOVE.
+ *	  If a pSib is specified:
+ *	      Above:  pWin is placed just above pSib
+ *	      Below:  pWin is placed just below pSib
+ *	      TopIf:  if pSib occludes pWin, then pWin is placed
+ *		      at the top of the stack
+ *	      BottomIf:	 if pWin occludes pSib, then pWin is 
+ *			 placed at the bottom of the stack
+ *	      Opposite: if pSib occludes pWin, then pWin is placed at the
+ *			top of the stack, else if pWin occludes pSib, then
+ *			pWin is placed at the bottom of the stack
+ *
+ *	  If pSib is NULL:
+ *	      Above:  pWin is placed at the top of the stack
+ *	      Below:  pWin is placed at the bottom of the stack
+ *	      TopIf:  if any sibling occludes pWin, then pWin is placed at
+ *		      the top of the stack
+ *	      BottomIf: if pWin occludes any sibline, then pWin is placed at
+ *			the bottom of the stack
+ *	      Opposite: if any sibling occludes pWin, then pWin is placed at
+ *			the top of the stack, else if pWin occludes any
+ *			sibling, then pWin is placed at the bottom of the stack
+ *
+ */
+
+static WindowPtr
+WhereDoIGoInTheStack(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    short x,
+    short y,
+    unsigned short w,
+    unsigned short h,
+    int smode)
+{
+    BoxRec box;
+    register ScreenPtr pScreen;
+    WindowPtr pHead, pFirst;
+
+    if ((pWin == pWin->parent->firstChild) &&
+	(pWin == pWin->parent->lastChild))
+	return((WindowPtr ) NULL);
+    pHead = RealChildHead(pWin->parent);
+    pFirst = pHead ? pHead->nextSib : pWin->parent->firstChild;
+    pScreen = pWin->drawable.pScreen;
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = x + (int)w;
+    box.y2 = y + (int)h;
+    switch (smode)
+    {
+      case Above:
+	if (pSib)
+	   return(pSib);
+	else if (pWin == pFirst)
+	    return(pWin->nextSib);
+	else
+	    return(pFirst);
+      case Below:
+	if (pSib)
+	    if (pSib->nextSib != pWin)
+		return(pSib->nextSib);
+	    else
+		return(pWin->nextSib);
+	else
+	    return NullWindow;
+      case TopIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Above) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return(pFirst);
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	    return(pFirst);
+	else
+	    return(pWin->nextSib);
+      case BottomIf:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if ((IsSiblingAboveMe(pWin, pSib) == Below) &&
+		(RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT))
+		return NullWindow;
+	    else
+		return(pWin->nextSib);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return(pWin->nextSib);
+      case Opposite:
+	if ((!pWin->mapped || (pSib && !pSib->mapped)) && !permitOldBugs)
+	    return(pWin->nextSib);
+	else if (pSib)
+	{
+	    if (RECT_IN_REGION(pScreen, &pSib->borderSize, &box) != rgnOUT)
+	    {
+		if (IsSiblingAboveMe(pWin, pSib) == Above)
+		    return(pFirst);
+		else
+		    return NullWindow;
+	    }
+	    else
+		return(pWin->nextSib);
+	}
+	else if (AnyWindowOverlapsMe(pWin, pHead, &box))
+	{
+	    /* If I'm occluded, I can't possibly be the first child
+	     * if (pWin == pWin->parent->firstChild)
+	     *	  return pWin->nextSib;
+	     */
+	    return(pFirst);
+	}
+	else if (IOverlapAnyWindow(pWin, &box))
+	    return NullWindow;
+	else
+	    return pWin->nextSib;
+      default:
+      {
+	ErrorF("Internal error in ConfigureWindow, smode == %d\n",smode );
+	return pWin->nextSib;
+      }
+    }
+}
+
+static void
+ReflectStackChange(
+    register WindowPtr pWin,
+    register WindowPtr pSib,
+    VTKind  kind)
+{
+/* Note that pSib might be NULL */
+
+    Bool WasViewable = (Bool)pWin->viewable;
+    Bool anyMarked;
+    WindowPtr pFirstChange;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    /* if this is a root window, can't be restacked */
+    if (!pWin->parent)
+	return;
+
+    pFirstChange = MoveWindowInStack(pWin, pSib);
+
+    if (WasViewable)
+    {
+	anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+						      &pLayerWin);
+	if (pLayerWin != pWin) pFirstChange = pLayerWin;
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, kind);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pWin->drawable.pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange, kind);
+    }
+    if (pWin->realized)
+	WindowsRestructured ();
+}
+
+/*****
+ * ConfigureWindow
+ *****/
+
+int
+ConfigureWindow(register WindowPtr pWin, register Mask mask, XID *vlist, ClientPtr client)
+{
+#define RESTACK_WIN    0
+#define MOVE_WIN       1
+#define RESIZE_WIN     2
+#define REBORDER_WIN   3
+    register WindowPtr pSib = NullWindow;
+    register WindowPtr pParent = pWin->parent;
+    Window sibwid = 0;
+    Mask index2, tmask;
+    register XID *pVlist;
+    short x,   y, beforeX, beforeY;
+    unsigned short w = pWin->drawable.width,
+		   h = pWin->drawable.height,
+		   bw = pWin->borderWidth;
+    int action, smode = Above;
+#ifdef XAPPGROUP
+    ClientPtr win_owner;
+    ClientPtr ag_leader = NULL;
+#endif
+    xEvent event;
+
+    if ((pWin->drawable.class == InputOnly) && (mask & IllegalInputOnlyConfigureMask))
+	return(BadMatch);
+
+    if ((mask & CWSibling) && !(mask & CWStackMode))
+	return(BadMatch);
+
+    pVlist = vlist;
+
+    if (pParent)
+    {
+	x = pWin->drawable.x - pParent->drawable.x - (int)bw;
+	y = pWin->drawable.y - pParent->drawable.y - (int)bw;
+    }
+    else
+    {
+	x = pWin->drawable.x;
+	y = pWin->drawable.y;
+    }
+    beforeX = x;
+    beforeY = y;
+    action = RESTACK_WIN;	
+    if ((mask & (CWX | CWY)) && (!(mask & (CWHeight | CWWidth))))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	action = MOVE_WIN;
+    }
+	/* or should be resized */
+    else if (mask & (CWX |  CWY | CWWidth | CWHeight))
+    {
+	GET_INT16(CWX, x);
+	GET_INT16(CWY, y);
+	GET_CARD16(CWWidth, w);
+	GET_CARD16 (CWHeight, h);
+	if (!w || !h)
+	{
+	    client->errorValue = 0;
+	    return BadValue;
+	}
+	action = RESIZE_WIN;
+    }
+    tmask = mask & ~ChangeMask;
+    while (tmask)
+    {
+	index2 = (Mask)lowbit (tmask);
+	tmask &= ~index2;
+	switch (index2)
+	{
+	  case CWBorderWidth:
+	    GET_CARD16(CWBorderWidth, bw);
+	    break;
+	  case CWSibling:
+	    sibwid = (Window ) *pVlist;
+	    pVlist++;
+	    pSib = (WindowPtr )SecurityLookupIDByType(client, sibwid,
+						RT_WINDOW, SecurityReadAccess);
+	    if (!pSib)
+	    {
+		client->errorValue = sibwid;
+		return(BadWindow);
+	    }
+	    if (pSib->parent != pParent)
+		return(BadMatch);
+	    if (pSib == pWin)
+		return(BadMatch);
+	    break;
+	  case CWStackMode:
+	    GET_CARD8(CWStackMode, smode);
+	    if ((smode != TopIf) && (smode != BottomIf) &&
+		(smode != Opposite) && (smode != Above) && (smode != Below))
+	    {
+		client->errorValue = smode;
+		return(BadValue);
+	    }
+	    break;
+	  default:
+	    client->errorValue = mask;
+	    return(BadValue);
+	}
+    }
+	/* root really can't be reconfigured, so just return */
+    if (!pParent)
+	return Success;
+
+	/* Figure out if the window should be moved.  Doesnt
+	   make the changes to the window if event sent */
+
+    if (mask & CWStackMode)
+	pSib = WhereDoIGoInTheStack(pWin, pSib, pParent->drawable.x + x,
+				    pParent->drawable.y + y,
+				    w + (bw << 1), h + (bw << 1), smode);
+    else
+	pSib = pWin->nextSib;
+
+#ifdef XAPPGROUP
+    win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+    ag_leader = XagLeader (win_owner);
+#endif
+
+    if ((!pWin->overrideRedirect) && 
+	(RedirectSend(pParent)
+#ifdef XAPPGROUP
+	|| (win_owner->appgroup && ag_leader && 
+	    XagIsControlledRoot (client, pParent))
+#endif
+	))
+    {
+	event.u.u.type = ConfigureRequest;
+	event.u.configureRequest.window = pWin->drawable.id;
+	if (mask & CWSibling)
+	   event.u.configureRequest.sibling = sibwid;
+	else
+	    event.u.configureRequest.sibling = None;
+	if (mask & CWStackMode)
+	   event.u.u.detail = smode;
+	else
+	    event.u.u.detail = Above;
+	event.u.configureRequest.x = x;
+	event.u.configureRequest.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+            event.u.configureRequest.x += panoramiXdataPtr[0].x;
+            event.u.configureRequest.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureRequest.width = w;
+	event.u.configureRequest.height = h;
+	event.u.configureRequest.borderWidth = bw;
+	event.u.configureRequest.valueMask = mask;
+#ifdef XAPPGROUP
+	/* make sure if the ag_leader maps the window it goes to the wm */
+	if (ag_leader && ag_leader != client && 
+	    XagIsControlledRoot (client, pParent)) {
+	    event.u.configureRequest.parent = XagId (win_owner);
+	    (void) TryClientEvents (ag_leader, &event, 1,
+				    NoEventMask, NoEventMask, NullGrab);
+	    return Success;
+	}
+#endif
+	event.u.configureRequest.parent = pParent->drawable.id;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+    if (action == RESIZE_WIN)
+    {
+	Bool size_change = (w != pWin->drawable.width)
+			|| (h != pWin->drawable.height);
+	if (size_change && ((pWin->eventMask|wOtherEventMasks(pWin)) & ResizeRedirectMask))
+	{
+	    xEvent eventT;
+	    eventT.u.u.type = ResizeRequest;
+	    eventT.u.resizeRequest.window = pWin->drawable.id;
+	    eventT.u.resizeRequest.width = w;
+	    eventT.u.resizeRequest.height = h;
+	    if (MaybeDeliverEventsToClient(pWin, &eventT, 1,
+				       ResizeRedirectMask, client) == 1)
+	    {
+		/* if event is delivered, leave the actual size alone. */
+		w = pWin->drawable.width;
+		h = pWin->drawable.height;
+		size_change = FALSE;
+	    }
+	}
+	if (!size_change)
+	{
+	    if (mask & (CWX | CWY))
+		action = MOVE_WIN;
+	    else if (mask & (CWStackMode | CWBorderWidth))
+		action = RESTACK_WIN;
+	    else   /* really nothing to do */
+		return(Success) ;
+	}
+    }
+
+    if (action == RESIZE_WIN)
+	    /* we've already checked whether there's really a size change */
+	    goto ActuallyDoSomething;
+    if ((mask & CWX) && (x != beforeX))
+	    goto ActuallyDoSomething;
+    if ((mask & CWY) && (y != beforeY))
+	    goto ActuallyDoSomething;
+    if ((mask & CWBorderWidth) && (bw != wBorderWidth (pWin)))
+	    goto ActuallyDoSomething;
+    if (mask & CWStackMode)
+    {
+#ifndef ROOTLESS
+        /* See above for why we always reorder in rootless mode. */
+	if (pWin->nextSib != pSib)
+#endif
+	    goto ActuallyDoSomething;
+    }
+    return(Success);
+
+ActuallyDoSomething:
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = ConfigureNotify;
+	event.u.configureNotify.window = pWin->drawable.id;
+	if (pSib)
+	    event.u.configureNotify.aboveSibling = pSib->drawable.id;
+	else
+	    event.u.configureNotify.aboveSibling = None;
+	event.u.configureNotify.x = x;
+	event.u.configureNotify.y = y;
+#ifdef PANORAMIX
+	if(!noPanoramiXExtension && (!pParent || !pParent->parent)) {
+	    event.u.configureNotify.x += panoramiXdataPtr[0].x;
+            event.u.configureNotify.y += panoramiXdataPtr[0].y;
+	}
+#endif
+	event.u.configureNotify.width = w;
+	event.u.configureNotify.height = h;
+	event.u.configureNotify.borderWidth = bw;
+	event.u.configureNotify.override = pWin->overrideRedirect;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (mask & CWBorderWidth)
+    {
+	if (action == RESTACK_WIN)
+	{
+	    action = MOVE_WIN;
+	    pWin->borderWidth = bw;
+	}
+	else if ((action == MOVE_WIN) &&
+		 (beforeX + wBorderWidth (pWin) == x + (int)bw) &&
+		 (beforeY + wBorderWidth (pWin) == y + (int)bw))
+	{
+	    action = REBORDER_WIN;
+	    (*pWin->drawable.pScreen->ChangeBorderWidth)(pWin, bw);
+	}
+	else
+	    pWin->borderWidth = bw;
+    }
+    if (action == MOVE_WIN)
+	(*pWin->drawable.pScreen->MoveWindow)(pWin, x, y, pSib,
+		   (mask & CWBorderWidth) ? VTOther : VTMove);
+    else if (action == RESIZE_WIN)
+	(*pWin->drawable.pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+    else if (mask & CWStackMode)
+	ReflectStackChange(pWin, pSib, VTOther);
+
+    if (action != RESTACK_WIN)
+	CheckCursorConfinement(pWin);
+    return(Success);
+#undef RESTACK_WIN
+#undef MOVE_WIN
+#undef RESIZE_WIN
+#undef REBORDER_WIN
+}
+
+
+/******
+ *
+ * CirculateWindow
+ *    For RaiseLowest, raises the lowest mapped child (if any) that is
+ *    obscured by another child to the top of the stack.  For LowerHighest,
+ *    lowers the highest mapped child (if any) that is obscuring another
+ *    child to the bottom of the stack.	 Exposure processing is performed 
+ *
+ ******/
+
+int
+CirculateWindow(WindowPtr pParent, int direction, ClientPtr client)
+{
+    register WindowPtr pWin, pHead, pFirst;
+    xEvent event;
+    BoxRec box;
+
+    pHead = RealChildHead(pParent);
+    pFirst = pHead ? pHead->nextSib : pParent->firstChild;
+    if (direction == RaiseLowest)
+    {
+	for (pWin = pParent->lastChild;
+	     (pWin != pHead) &&
+	     !(pWin->mapped &&
+	       AnyWindowOverlapsMe(pWin, pHead, WindowExtents(pWin, &box)));
+	     pWin = pWin->prevSib) ;
+	if (pWin == pHead)
+	    return Success;
+    }
+    else
+    {
+	for (pWin = pFirst;
+	     pWin &&
+	     !(pWin->mapped &&
+	       IOverlapAnyWindow(pWin, WindowExtents(pWin, &box)));
+	     pWin = pWin->nextSib) ;
+	if (!pWin)
+	    return Success;
+    }
+
+    event.u.circulate.window = pWin->drawable.id;
+    event.u.circulate.parent = pParent->drawable.id;
+    event.u.circulate.event = pParent->drawable.id;
+    if (direction == RaiseLowest)
+	event.u.circulate.place = PlaceOnTop;
+    else
+	event.u.circulate.place = PlaceOnBottom;
+
+    if (RedirectSend(pParent))
+    {
+	event.u.u.type = CirculateRequest;
+	if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+	    return(Success);
+    }
+
+    event.u.u.type = CirculateNotify;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+    ReflectStackChange(pWin,
+		       (direction == RaiseLowest) ? pFirst : NullWindow,
+		       VTStack);
+
+    return(Success);
+}
+
+static int
+CompareWIDs(
+    WindowPtr pWin,
+    pointer   value) /* must conform to VisitWindowProcPtr */
+{
+    Window *wid = (Window *)value;
+
+    if (pWin->drawable.id == *wid)
+       return(WT_STOPWALKING);
+    else
+       return(WT_WALKCHILDREN);
+}
+
+/*****
+ *  ReparentWindow
+ *****/
+
+int
+ReparentWindow(register WindowPtr pWin, register WindowPtr pParent,
+               int x, int y, ClientPtr client)
+{
+    WindowPtr pPrev, pPriorParent;
+    Bool WasMapped = (Bool)(pWin->mapped);
+    xEvent event;
+    int bw = wBorderWidth (pWin);
+    register ScreenPtr pScreen;
+
+    pScreen = pWin->drawable.pScreen;
+    if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
+	return(BadMatch);		
+    if (!MakeWindowOptional(pWin))
+	return(BadAlloc);
+
+    if (WasMapped)
+       UnmapWindow(pWin, FALSE);
+
+    event.u.u.type = ReparentNotify;
+    event.u.reparent.window = pWin->drawable.id;
+    event.u.reparent.parent = pParent->drawable.id;
+    event.u.reparent.x = x;
+    event.u.reparent.y = y;
+#ifdef PANORAMIX
+    if(!noPanoramiXExtension && !pParent->parent) {
+	event.u.reparent.x += panoramiXdataPtr[0].x;
+	event.u.reparent.y += panoramiXdataPtr[0].y;
+    }
+#endif
+    event.u.reparent.override = pWin->overrideRedirect;
+    DeliverEvents(pWin, &event, 1, pParent);
+
+    /* take out of sibling chain */
+
+    pPriorParent = pPrev = pWin->parent;
+    if (pPrev->firstChild == pWin)
+	pPrev->firstChild = pWin->nextSib;
+    if (pPrev->lastChild == pWin)
+	pPrev->lastChild = pWin->prevSib;
+
+    if (pWin->nextSib)
+	pWin->nextSib->prevSib = pWin->prevSib;
+    if (pWin->prevSib)
+	pWin->prevSib->nextSib = pWin->nextSib;
+
+    /* insert at begining of pParent */
+    pWin->parent = pParent;
+    pPrev = RealChildHead(pParent);
+    if (pPrev)
+    {
+	pWin->nextSib = pPrev->nextSib;
+	if (pPrev->nextSib)
+	    pPrev->nextSib->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pPrev->nextSib = pWin;
+	pWin->prevSib = pPrev;
+    }
+    else
+    {
+	pWin->nextSib = pParent->firstChild;
+	pWin->prevSib = NullWindow;
+	if (pParent->firstChild)
+	    pParent->firstChild->prevSib = pWin;
+	else
+	    pParent->lastChild = pWin;
+	pParent->firstChild = pWin;
+    }
+
+    pWin->origin.x = x + bw;
+    pWin->origin.y = y + bw;
+    pWin->drawable.x = x + bw + pParent->drawable.x;
+    pWin->drawable.y = y + bw + pParent->drawable.y;
+
+    /* clip to parent */
+    SetWinSize (pWin);
+    SetBorderSize (pWin);
+
+    if (pScreen->ReparentWindow)
+	(*pScreen->ReparentWindow)(pWin, pPriorParent);
+    (*pScreen->PositionWindow)(pWin, pWin->drawable.x, pWin->drawable.y);
+    ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+    CheckWindowOptionalNeed(pWin);
+
+    if (WasMapped)
+	MapWindow(pWin, client);
+    RecalculateDeliverableEvents(pWin);
+    return(Success);
+}
+
+static void
+RealizeTree(WindowPtr pWin)
+{
+    register WindowPtr pChild;
+    RealizeWindowProcPtr Realize;
+
+    Realize = pWin->drawable.pScreen->RealizeWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->mapped)
+	{
+	    pChild->realized = TRUE;
+#ifdef DO_SAVE_UNDERS
+	    if (pChild->saveUnder)
+		deltaSaveUndersViewable++;
+#endif
+	    pChild->viewable = (pChild->drawable.class == InputOutput);
+	    (* Realize)(pChild);
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * MapWindow
+ *    If some other client has selected SubStructureReDirect on the parent
+ *    and override-redirect is xFalse, then a MapRequest event is generated,
+ *    but the window remains unmapped.	Otherwise, the window is mapped and a
+ *    MapNotify event is generated.
+ *****/
+
+int
+MapWindow(register WindowPtr pWin, ClientPtr client)
+{
+    register ScreenPtr pScreen;
+
+    register WindowPtr pParent;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr  pLayerWin;
+
+    if (pWin->mapped)
+	return(Success);
+
+#ifdef XCSECURITY
+    /*  don't let an untrusted client map a child-of-trusted-window, InputOnly
+     *  window; too easy to steal device input
+     */
+    if ( (client->trustLevel != XSecurityClientTrusted) &&
+	 (pWin->drawable.class == InputOnly) &&
+	 (wClient(pWin->parent)->trustLevel == XSecurityClientTrusted) )
+	 return Success;
+#endif	
+
+    pScreen = pWin->drawable.pScreen;
+    if ( (pParent = pWin->parent) )
+    {
+	xEvent event;
+	Bool anyMarked;
+#ifdef XAPPGROUP
+	ClientPtr win_owner = clients[CLIENT_ID(pWin->drawable.id)];
+	ClientPtr ag_leader = XagLeader (win_owner);
+#endif
+
+	if ((!pWin->overrideRedirect) && 
+	    (RedirectSend(pParent)
+#ifdef XAPPGROUP
+	    || (win_owner->appgroup && ag_leader &&
+		XagIsControlledRoot (client, pParent))
+#endif
+	))
+	{
+	    event.u.u.type = MapRequest;
+	    event.u.mapRequest.window = pWin->drawable.id;
+#ifdef XAPPGROUP
+	    /* make sure if the ag_leader maps the window it goes to the wm */
+	    if (ag_leader && ag_leader != client &&
+		XagIsControlledRoot (client, pParent)) {
+		event.u.mapRequest.parent = XagId (win_owner);
+		(void) TryClientEvents (ag_leader, &event, 1,
+					NoEventMask, NoEventMask, NullGrab);
+		return Success;
+	    }
+#endif
+	    event.u.mapRequest.parent = pParent->drawable.id;
+
+	    if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		SubstructureRedirectMask, client) == 1)
+		return(Success);
+	}
+
+	pWin->mapped = TRUE;
+	if (SubStrSend(pWin, pParent))
+	{
+	    event.u.u.type = MapNotify;
+	    event.u.mapNotify.window = pWin->drawable.id;
+	    event.u.mapNotify.override = pWin->overrideRedirect;
+	    DeliverEvents(pWin, &event, 1, NullWindow);
+	}
+
+	if (!pParent->realized)
+	    return(Success);
+	RealizeTree(pWin);
+	if (pWin->viewable)
+	{
+	    anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							  &pLayerWin);
+#ifdef DO_SAVE_UNDERS
+	    if (DO_SAVE_UNDERS(pWin))
+	    {
+		dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+#endif /* DO_SAVE_UNDERS */
+	    if (anyMarked)
+	    {
+		(*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+		(*pScreen->HandleExposures)(pLayerWin->parent);
+	    }
+#ifdef DO_SAVE_UNDERS
+	    if (dosave)
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTMap);
+	}
+	WindowsRestructured ();
+    }
+    else
+    {
+	RegionRec   temp;
+
+	pWin->mapped = TRUE;
+	pWin->realized = TRUE;	   /* for roots */
+	pWin->viewable = pWin->drawable.class == InputOutput;
+	/* We SHOULD check for an error value here XXX */
+	(*pScreen->RealizeWindow)(pWin);
+	if (pScreen->ClipNotify)
+	    (*pScreen->ClipNotify) (pWin, 0, 0);
+	if (pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(NullWindow, pWin, VTMap);
+	REGION_NULL(pScreen, &temp);
+	REGION_COPY(pScreen, &temp, &pWin->clipList);
+	(*pScreen->WindowExposures) (pWin, &temp, NullRegion);
+	REGION_UNINIT(pScreen, &temp);
+    }
+
+    return(Success);
+}
+
+
+/*****
+ * MapSubwindows
+ *    Performs a MapWindow all unmapped children of the window, in top
+ *    to bottom stacking order.
+ *****/
+
+void
+MapSubwindows(register WindowPtr pParent, ClientPtr client)
+{
+    register WindowPtr	pWin;
+    WindowPtr		pFirstMapped = NullWindow;
+#ifdef DO_SAVE_UNDERS
+    WindowPtr		pFirstSaveUndered = NullWindow;
+#endif
+    register ScreenPtr	pScreen;
+    register Mask	parentRedirect;
+    register Mask	parentNotify;
+    xEvent		event;
+    Bool		anyMarked;
+#ifdef DO_SAVE_UNDERS
+    Bool	dosave = FALSE;
+#endif
+    WindowPtr		pLayerWin;
+
+    pScreen = pParent->drawable.pScreen;
+    parentRedirect = RedirectSend(pParent);
+    parentNotify = SubSend(pParent);
+    anyMarked = FALSE;
+    for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+    {
+	if (!pWin->mapped)
+	{
+	    if (parentRedirect && !pWin->overrideRedirect)
+	    {
+		event.u.u.type = MapRequest;
+		event.u.mapRequest.window = pWin->drawable.id;
+		event.u.mapRequest.parent = pParent->drawable.id;
+    
+		if (MaybeDeliverEventsToClient(pParent, &event, 1,
+		    SubstructureRedirectMask, client) == 1)
+		    continue;
+	    }
+    
+	    pWin->mapped = TRUE;
+	    if (parentNotify || StrSend(pWin))
+	    {
+		event.u.u.type = MapNotify;
+		event.u.mapNotify.window = pWin->drawable.id;
+		event.u.mapNotify.override = pWin->overrideRedirect;
+		DeliverEvents(pWin, &event, 1, NullWindow);
+	    }
+    
+	    if (!pFirstMapped)
+		pFirstMapped = pWin;
+	    if (pParent->realized)
+	    {
+		RealizeTree(pWin);
+		if (pWin->viewable)
+		{
+		    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+							(WindowPtr *)NULL);
+#ifdef DO_SAVE_UNDERS
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave = TRUE;
+		    }
+#endif /* DO_SAVE_UNDERS */
+		}
+	    }
+	}
+    }
+
+    if (pFirstMapped)
+    {
+	pLayerWin = (*pScreen->GetLayerWindow)(pParent);
+	if (pLayerWin->parent != pParent) {
+	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pLayerWin,
+							   pLayerWin,
+							   (WindowPtr *)NULL);
+	    pFirstMapped = pLayerWin;
+	}
+        if (anyMarked)
+        {
+#ifdef DO_SAVE_UNDERS
+	    if (pLayerWin->parent != pParent)
+	    {
+		if (dosave || (DO_SAVE_UNDERS(pLayerWin)))
+		{
+		    dosave = (*pScreen->ChangeSaveUnder)(pLayerWin,
+							 pLayerWin);
+		}
+	    }
+	    else if (dosave)
+	    {
+		dosave = FALSE;
+		for (pWin = pParent->firstChild; pWin; pWin = pWin->nextSib)
+		{
+		    if (DO_SAVE_UNDERS(pWin))
+		    {
+			dosave |= (*pScreen->ChangeSaveUnder)(pWin,
+							      pWin->nextSib);
+			if (dosave && !pFirstSaveUndered)
+			    pFirstSaveUndered = pWin;
+		    }
+		}
+            }
+#endif /* DO_SAVE_UNDERS */
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pFirstMapped, VTMap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+        if (dosave)
+	    (*pScreen->PostChangeSaveUnder)(pLayerWin,
+					    pFirstSaveUndered->nextSib);
+#endif /* DO_SAVE_UNDERS */
+        if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstMapped,
+					 VTMap);
+        WindowsRestructured ();
+    }
+}
+
+static void
+UnrealizeTree(
+    WindowPtr pWin,
+    Bool fromConfigure)
+{
+    register WindowPtr pChild;
+    UnrealizeWindowProcPtr Unrealize;
+    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+    Unrealize = pWin->drawable.pScreen->UnrealizeWindow;
+    MarkUnrealizedWindow = pWin->drawable.pScreen->MarkUnrealizedWindow;
+    pChild = pWin;
+    while (1)
+    {
+	if (pChild->realized)
+	{
+	    pChild->realized = FALSE;
+	    pChild->visibility = VisibilityNotViewable;
+#ifdef PANORAMIX
+	    if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) {
+		PanoramiXRes *win;
+		win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id,
+							XRT_WINDOW);
+		if(win)
+		   win->u.win.visibility = VisibilityNotViewable;
+	    } 
+#endif
+	    (* Unrealize)(pChild);
+	    DeleteWindowFromAnyEvents(pChild, FALSE);
+	    if (pChild->viewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		if (pChild->saveUnder)
+		    deltaSaveUndersViewable--;
+#endif
+		pChild->viewable = FALSE;
+		if (pChild->backStorage)
+		    (*pChild->drawable.pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+		(* MarkUnrealizedWindow)(pChild, pWin, fromConfigure);
+		pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+	    }
+	    if (pChild->firstChild)
+	    {
+		pChild = pChild->firstChild;
+		continue;
+	    }
+	}
+	while (!pChild->nextSib && (pChild != pWin))
+	    pChild = pChild->parent;
+	if (pChild == pWin)
+	    return;
+	pChild = pChild->nextSib;
+    }
+}
+
+/*****
+ * UnmapWindow
+ *    If the window is already unmapped, this request has no effect.
+ *    Otherwise, the window is unmapped and an UnMapNotify event is
+ *    generated.  Cannot unmap a root window.
+ *****/
+
+int
+UnmapWindow(register WindowPtr pWin, Bool fromConfigure)
+{
+    register WindowPtr pParent;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    if ((!pWin->mapped) || (!(pParent = pWin->parent)))
+	return(Success);
+    if (SubStrSend(pWin, pParent))
+    {
+	event.u.u.type = UnmapNotify;
+	event.u.unmapNotify.window = pWin->drawable.id;
+	event.u.unmapNotify.fromConfigure = fromConfigure;
+	DeliverEvents(pWin, &event, 1, NullWindow);
+    }
+    if (wasViewable && !fromConfigure)
+    {
+	pWin->valdata = UnmapValData;
+	(*pScreen->MarkOverlappedWindows)(pWin, pWin->nextSib, &pLayerWin);
+	(*pScreen->MarkWindow)(pLayerWin->parent);
+    }
+    pWin->mapped = FALSE;
+    if (wasRealized)
+	UnrealizeTree(pWin, fromConfigure);
+    if (wasViewable)
+    {
+	if (!fromConfigure)
+	{
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib) )
+	    {
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+	    }
+	}
+	pWin->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+	if (!fromConfigure && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pWin, VTUnmap);
+    }
+    if (wasRealized && !fromConfigure)
+	WindowsRestructured ();
+    return(Success);
+}
+
+/*****
+ * UnmapSubwindows
+ *    Performs an UnmapWindow request with the specified mode on all mapped
+ *    children of the window, in bottom to top stacking order.
+ *****/
+
+void
+UnmapSubwindows(register WindowPtr pWin)
+{
+    register WindowPtr pChild, pHead;
+    xEvent event;
+    Bool wasRealized = (Bool)pWin->realized;
+    Bool wasViewable = (Bool)pWin->viewable;
+    Bool anyMarked = FALSE;
+    Mask parentNotify;
+    WindowPtr pLayerWin = NULL;
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    if (!pWin->firstChild)
+	return;
+    parentNotify = SubSend(pWin);
+    pHead = RealChildHead(pWin);
+
+    if (wasViewable)
+	pLayerWin = (*pScreen->GetLayerWindow)(pWin);
+
+    for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+    {
+	if (pChild->mapped)
+	{
+	    if (parentNotify || StrSend(pChild))
+	    {
+		event.u.u.type = UnmapNotify;
+		event.u.unmapNotify.window = pChild->drawable.id;
+		event.u.unmapNotify.fromConfigure = xFalse;
+		DeliverEvents(pChild, &event, 1, NullWindow);
+	    }
+	    if (pChild->viewable)
+	    {
+		pChild->valdata = UnmapValData;
+		anyMarked = TRUE;
+	    }
+	    pChild->mapped = FALSE;
+	    if (pChild->realized)
+		UnrealizeTree(pChild, FALSE);
+	    if (wasViewable)
+	    {
+#ifdef DO_SAVE_UNDERS
+		pChild->DIXsaveUnder = FALSE;
+#endif /* DO_SAVE_UNDERS */
+		if (pChild->backStorage)
+		    (*pScreen->SaveDoomedAreas)(
+					    pChild, &pChild->clipList, 0, 0);
+	    }
+	}
+    }
+    if (wasViewable)
+    {
+	if (anyMarked)
+	{
+	    if (pLayerWin->parent == pWin)
+		(*pScreen->MarkWindow)(pWin);
+	    else
+	    {
+		WindowPtr ptmp;
+                (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+						  (WindowPtr *)NULL);
+		(*pScreen->MarkWindow)(pLayerWin->parent);
+		
+		/* Windows between pWin and pLayerWin may not have been marked */
+		ptmp = pWin;
+ 
+		while (ptmp != pLayerWin->parent)
+		{
+		    (*pScreen->MarkWindow)(ptmp);
+		    ptmp = ptmp->parent;
+		}
+                pHead = pWin->firstChild;
+	    }
+	    (*pScreen->ValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+	    (*pScreen->HandleExposures)(pLayerWin->parent);
+	}
+#ifdef DO_SAVE_UNDERS
+	if (DO_SAVE_UNDERS(pWin))
+	{
+	    if ( (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin))
+		(*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+	}
+#endif /* DO_SAVE_UNDERS */
+	if (anyMarked && pScreen->PostValidateTree)
+	    (*pScreen->PostValidateTree)(pLayerWin->parent, pHead, VTUnmap);
+    }
+    if (wasRealized)
+	WindowsRestructured ();
+}
+
+
+void
+HandleSaveSet(register ClientPtr client)
+{
+    register WindowPtr pParent, pWin;
+    register int j;
+
+    for (j=0; j<client->numSaved; j++)
+    {
+	pWin = SaveSetWindow(client->saveSet[j]);
+#ifdef XFIXES
+	if (SaveSetToRoot(client->saveSet[j]))
+	    pParent = WindowTable[pWin->drawable.pScreen->myNum];
+	else
+#endif
+	{
+	    pParent = pWin->parent;
+	    while (pParent && (wClient (pParent) == client))
+		pParent = pParent->parent;
+	}
+	if (pParent)
+	{
+	    if (pParent != pWin->parent)
+	    {
+		ReparentWindow(pWin, pParent,
+			       pWin->drawable.x - wBorderWidth (pWin) - pParent->drawable.x,
+			       pWin->drawable.y - wBorderWidth (pWin) - pParent->drawable.y,
+			       client);
+		if(!pWin->realized && pWin->mapped)
+		    pWin->mapped = FALSE;
+	    }
+#ifdef XFIXES
+	    if (SaveSetRemap (client->saveSet[j]))
+#endif
+		MapWindow(pWin, client);
+	}
+    }
+    xfree(client->saveSet);
+    client->numSaved = 0;
+    client->saveSet = (SaveSetElt *)NULL;
+}
+
+/**
+ *
+ *  \param x,y  in root
+ *  \param box  "return" value
+ */
+Bool
+VisibleBoundingBoxFromPoint(register WindowPtr pWin, int x, int y, BoxPtr box)
+{
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->clipList, x, y, box))
+	return(TRUE);
+    return(FALSE);
+}
+
+/**
+ *
+ * \param x,y  in root
+ */
+Bool
+PointInWindowIsVisible(register WindowPtr pWin, int x, int y)
+{
+    BoxRec box;
+
+    if (!pWin->realized)
+	return (FALSE);
+    if (POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderClip,
+						  x, y, &box)
+	&& (!wInputShape(pWin) ||
+	    POINT_IN_REGION(pWin->drawable.pScreen,
+			    wInputShape(pWin),
+			    x - pWin->drawable.x, 
+			    y - pWin->drawable.y, &box)))
+	return(TRUE);
+    return(FALSE);
+}
+
+
+RegionPtr
+NotClippedByChildren(register WindowPtr pWin)
+{
+    register ScreenPtr pScreen;
+    RegionPtr pReg;
+
+    pScreen = pWin->drawable.pScreen;
+    pReg = REGION_CREATE(pScreen, NullBox, 1);
+    if (pWin->parent ||
+	screenIsSaved != SCREEN_SAVER_ON ||
+	!HasSaverWindow (pWin->drawable.pScreen->myNum))
+    {
+	REGION_INTERSECT(pScreen, pReg, &pWin->borderClip, &pWin->winSize);
+    }
+    return(pReg);
+}
+
+void
+SendVisibilityNotify(WindowPtr pWin)
+{
+    xEvent event;
+#ifndef NO_XINERAMA_PORT
+    unsigned int visibility = pWin->visibility;
+#endif
+#ifdef PANORAMIX
+    /* This is not quite correct yet, but it's close */
+    if(!noPanoramiXExtension) {
+	PanoramiXRes *win;
+	WindowPtr pWin2;
+	int i, Scrnum;
+
+	Scrnum = pWin->drawable.pScreen->myNum;
+	
+	win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum);
+
+	if(!win || (win->u.win.visibility == visibility))
+	    return;
+
+	switch(visibility) {
+	case VisibilityUnobscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+
+		if (pWin2) {
+		    if(pWin2->visibility == VisibilityPartiallyObscured)
+		   	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	case VisibilityPartiallyObscured:
+	    if(Scrnum) {
+	        pWin2 = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW);
+		if (pWin2) pWin = pWin2;
+	    }
+	    break;
+	case VisibilityFullyObscured:
+	    for(i = 0; i < PanoramiXNumScreens; i++) {
+		if(i == Scrnum) continue;
+
+		pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW);
+		
+		if (pWin2) {
+		    if(pWin2->visibility != VisibilityFullyObscured)
+		    	return;
+
+		    if(!i) pWin = pWin2;
+		}
+	    }
+	    break;
+	}
+	
+	win->u.win.visibility = visibility;
+    }
+#endif
+
+    event.u.u.type = VisibilityNotify;
+    event.u.visibility.window = pWin->drawable.id;
+    event.u.visibility.state = visibility;
+    DeliverEvents(pWin, &event, 1, NullWindow);
+}
+
+
+#define RANDOM_WIDTH 32
+
+#ifndef NOLOGOHACK
+static void DrawLogo(
+    WindowPtr pWin
+);
+#endif
+
+void
+SaveScreens(int on, int mode)
+{
+    int i;
+    int what;
+    int type;
+
+    if (on == SCREEN_SAVER_FORCER)
+    {
+	UpdateCurrentTimeIf();
+	lastDeviceEventTime = currentTime;
+	if (mode == ScreenSaverReset)
+	    what = SCREEN_SAVER_OFF;
+	else
+	    what = SCREEN_SAVER_ON;
+	type = what;
+    }
+    else
+    {
+	what = on;
+	type = what;
+	if (what == screenIsSaved)
+	    type = SCREEN_SAVER_CYCLE;
+    }
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+	if (on == SCREEN_SAVER_FORCER)
+	   (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], on);
+	if (savedScreenInfo[i].ExternalScreenSaver)
+	{
+	    if ((*savedScreenInfo[i].ExternalScreenSaver)
+		(screenInfo.screens[i], type, on == SCREEN_SAVER_FORCER))
+		continue;
+	}
+	if (type == screenIsSaved)
+	    continue;
+	switch (type) {
+	case SCREEN_SAVER_OFF:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+	       (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						      what);
+	    }
+	    else if (HasSaverWindow (i))
+	    {
+		savedScreenInfo[i].pWindow = NullWindow;
+		FreeResource(savedScreenInfo[i].wid, RT_NONE);
+	    }
+	    break;
+	case SCREEN_SAVER_CYCLE:
+	    if (savedScreenInfo[i].blanked == SCREEN_IS_TILED)
+	    {
+		WindowPtr pWin = savedScreenInfo[i].pWindow;
+		/* make it look like screen saver is off, so that
+		 * NotClippedByChildren will compute a clip list
+		 * for the root window, so miPaintWindow works
+		 */
+		screenIsSaved = SCREEN_SAVER_OFF;
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, FALSE);
+#endif
+		(*pWin->drawable.pScreen->MoveWindow)(pWin,
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   (short)(-(rand() % RANDOM_WIDTH)),
+			   pWin->nextSib, VTMove);
+#ifndef NOLOGOHACK
+		if (logoScreenSaver)
+		    DrawLogo(pWin);
+#endif
+		screenIsSaved = SCREEN_SAVER_ON;
+	    }
+	    /*
+	     * Call the DDX saver in case it wants to do something
+	     * at cycle time
+	     */
+	    else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED)
+	    {
+		(* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i],
+						       type);
+	    }
+	    break;
+	case SCREEN_SAVER_ON:
+	    if (ScreenSaverBlanking != DontPreferBlanking)
+	    {
+		if ((* screenInfo.screens[i]->SaveScreen)
+		   (screenInfo.screens[i], what))
+		{
+		   savedScreenInfo[i].blanked = SCREEN_IS_BLANKED;
+		   continue;
+		}
+		if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		    TileScreenSaver(i, SCREEN_IS_BLACK))
+		{
+		    savedScreenInfo[i].blanked = SCREEN_IS_BLACK;
+		    continue;
+		}
+	    }
+	    if ((ScreenSaverAllowExposures != DontAllowExposures) &&
+		TileScreenSaver(i, SCREEN_IS_TILED))
+	    {
+		savedScreenInfo[i].blanked = SCREEN_IS_TILED;
+	    }
+	    else
+		savedScreenInfo[i].blanked = SCREEN_ISNT_SAVED;
+	    break;
+	}
+    }
+    screenIsSaved = what;
+    if (mode == ScreenSaverReset)
+       SetScreenSaverTimer();
+}
+
+static Bool
+TileScreenSaver(int i, int kind)
+{
+    int j;
+    int result;
+    XID attributes[3];
+    Mask mask;
+    WindowPtr pWin;		
+    CursorMetricRec cm;
+    unsigned char *srcbits, *mskbits;
+    CursorPtr cursor;
+    XID	cursorID = 0;
+    int	attri;
+
+    mask = 0;
+    attri = 0;
+    switch (kind) {
+    case SCREEN_IS_TILED:
+	switch (WindowTable[i]->backgroundState) {
+	case BackgroundPixel:
+	    attributes[attri++] = WindowTable[i]->background.pixel;
+	    mask |= CWBackPixel;
+	    break;
+	case BackgroundPixmap:
+	    attributes[attri++] = None;
+	    mask |= CWBackPixmap;
+	    break;
+	default:
+	    break;
+	}
+	break;
+    case SCREEN_IS_BLACK:
+	attributes[attri++] = WindowTable[i]->drawable.pScreen->blackPixel;
+	mask |= CWBackPixel;
+	break;
+    }
+    mask |= CWOverrideRedirect;
+    attributes[attri++] = xTrue;
+
+    /*
+     * create a blank cursor
+     */
+
+    cm.width=16;
+    cm.height=16;
+    cm.xhot=8;
+    cm.yhot=8;
+    srcbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    mskbits = (unsigned char *)xalloc( BitmapBytePad(32)*16);
+    if (!srcbits || !mskbits)
+    {
+	xfree(srcbits);
+	xfree(mskbits);
+	cursor = 0;
+    }
+    else
+    {
+	for (j=0; j<BitmapBytePad(32)*16; j++)
+	    srcbits[j] = mskbits[j] = 0x0;
+	cursor = AllocCursor(srcbits, mskbits, &cm, 0, 0, 0, 0, 0, 0);
+	if (cursor)
+	{
+	    cursorID = FakeClientID(0);
+	    if (AddResource (cursorID, RT_CURSOR, (pointer) cursor))
+	    {
+		attributes[attri] = cursorID;
+		mask |= CWCursor;
+	    }
+	    else
+		cursor = 0;
+	}
+	else
+	{
+	    xfree (srcbits);
+	    xfree (mskbits);
+	}
+    }
+
+    pWin = savedScreenInfo[i].pWindow =
+	 CreateWindow(savedScreenInfo[i].wid,
+	      WindowTable[i],
+	      -RANDOM_WIDTH, -RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->width + RANDOM_WIDTH,
+	      (unsigned short)screenInfo.screens[i]->height + RANDOM_WIDTH,
+	      0, InputOutput, mask, attributes, 0, serverClient,
+	      wVisual (WindowTable[i]), &result);
+
+    if (cursor)
+	FreeResource (cursorID, RT_NONE);
+
+    if (!pWin)
+	return FALSE;
+
+    if (!AddResource(pWin->drawable.id, RT_WINDOW,
+		     (pointer)savedScreenInfo[i].pWindow))
+	return FALSE;
+
+    if (mask & CWBackPixmap)
+    {
+	MakeRootTile (pWin);
+	(*pWin->drawable.pScreen->ChangeWindowAttributes)(pWin, CWBackPixmap);
+    }
+    MapWindow(pWin, serverClient);
+#ifndef NOLOGOHACK
+    if (kind == SCREEN_IS_TILED && logoScreenSaver)
+	DrawLogo(pWin);
+#endif
+    return TRUE;
+}
+
+/*
+ * FindWindowWithOptional
+ *
+ * search ancestors of the given window for an entry containing
+ * a WindowOpt structure.  Assumptions:	 some parent will
+ * contain the structure.
+ */
+
+WindowPtr
+FindWindowWithOptional (register WindowPtr w)
+{
+    do
+	w = w->parent;
+    while (!w->optional);
+    return w;
+}
+
+/*
+ * CheckWindowOptionalNeed
+ *
+ * check each optional entry in the given window to see if
+ * the value is satisfied by the default rules.	 If so,
+ * release the optional record
+ */
+
+void
+CheckWindowOptionalNeed (register WindowPtr w)
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (!w->parent)
+	return;
+    optional = w->optional;
+    if (optional->dontPropagateMask != DontPropagateMasks[w->dontPropagate])
+	return;
+    if (optional->otherEventMasks != 0)
+	return;
+    if (optional->otherClients != NULL)
+	return;
+    if (optional->passiveGrabs != NULL)
+	return;
+    if (optional->userProps != NULL)
+	return;
+    if (optional->backingBitPlanes != ~0L)
+	return;
+    if (optional->backingPixel != 0)
+	return;
+#ifdef SHAPE
+    if (optional->boundingShape != NULL)
+	return;
+    if (optional->clipShape != NULL)
+	return;
+    if (optional->inputShape != NULL)
+	return;
+#endif
+#ifdef XINPUT
+    if (optional->inputMasks != NULL)
+	return;
+#endif
+    parentOptional = FindWindowWithOptional(w)->optional;
+    if (optional->visual != parentOptional->visual)
+	return;
+    if (optional->cursor != None &&
+	(optional->cursor != parentOptional->cursor ||
+	 w->parent->cursorIsNone))
+	return;
+    if (optional->colormap != parentOptional->colormap)
+	return;
+    DisposeWindowOptional (w);
+}
+
+/*
+ * MakeWindowOptional
+ *
+ * create an optional record and initialize it with the default
+ * values.
+ */
+
+Bool
+MakeWindowOptional (register WindowPtr pWin)
+{
+    register WindowOptPtr optional;
+    register WindowOptPtr parentOptional;
+
+    if (pWin->optional)
+	return TRUE;
+    optional = (WindowOptPtr) xalloc (sizeof (WindowOptRec));
+    if (!optional)
+	return FALSE;
+    optional->dontPropagateMask = DontPropagateMasks[pWin->dontPropagate];
+    optional->otherEventMasks = 0;
+    optional->otherClients = NULL;
+    optional->passiveGrabs = NULL;
+    optional->userProps = NULL;
+    optional->backingBitPlanes = ~0L;
+    optional->backingPixel = 0;
+#ifdef SHAPE
+    optional->boundingShape = NULL;
+    optional->clipShape = NULL;
+    optional->inputShape = NULL;
+#endif
+#ifdef XINPUT
+    optional->inputMasks = NULL;
+#endif
+    parentOptional = FindWindowWithOptional(pWin)->optional;
+    optional->visual = parentOptional->visual;
+    if (!pWin->cursorIsNone)
+    {
+	optional->cursor = parentOptional->cursor;
+	optional->cursor->refcnt++;
+    }
+    else
+    {
+	optional->cursor = None;
+    }
+    optional->colormap = parentOptional->colormap;
+    pWin->optional = optional;
+    return TRUE;
+}
+
+void
+DisposeWindowOptional (register WindowPtr pWin)
+{
+    if (!pWin->optional)
+	return;
+    /*
+     * everything is peachy.  Delete the optional record
+     * and clean up
+     */
+    /*
+     * TOG changed this code to:
+     *
+     *	    if (pWin->cursorIsNone == FALSE)
+     *		FreeCursor (pWin->optional->cursor, (Cursor)0);
+     *	    pWin->cursorIsNone = TRUE;
+     *
+     * This is blatently wrong; windows without optionals can have
+     * two different cursor values, either None or sharing their
+     * parents cursor.  This difference is controlled by the
+     * cursorIsNone value; when TRUE, the window has no cursor,
+     * when false, it shares its cursor with its parent; TOG
+     * made it impossible for a window to have a cursor without
+     * an optional record.
+     */
+    if (pWin->optional->cursor)
+    {
+	FreeCursor (pWin->optional->cursor, (Cursor)0);
+	pWin->cursorIsNone = FALSE;
+    }
+    else
+	pWin->cursorIsNone = TRUE;
+    xfree (pWin->optional);
+    pWin->optional = NULL;
+}
+
+#ifndef NOLOGOHACK
+static void
+DrawLogo(WindowPtr pWin)
+{
+    DrawablePtr pDraw;
+    ScreenPtr pScreen;
+    int x, y;
+    unsigned int width, height, size;
+    GC *pGC;
+    int thin, gap, d31;
+    DDXPointRec poly[4];
+    ChangeGCVal fore[2], back[2];
+    xrgb rgb[2];
+    BITS32 fmask, bmask;
+    ColormapPtr cmap;
+
+    pDraw = (DrawablePtr)pWin;
+    pScreen = pDraw->pScreen;
+    x = -pWin->origin.x;
+    y = -pWin->origin.y;
+    width = pScreen->width;
+    height = pScreen->height;
+    pGC = GetScratchGC(pScreen->rootDepth, pScreen);
+    if (!pGC)
+	return;
+
+    if ((rand() % 100) <= 17) /* make the probability for white fairly low */
+	fore[0].val = pScreen->whitePixel;
+    else
+	fore[0].val = pScreen->blackPixel;
+    if ((pWin->backgroundState == BackgroundPixel) &&
+	(cmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP))) {
+	Pixel querypixels[2];
+
+	querypixels[0] = fore[0].val;
+	querypixels[1] = pWin->background.pixel;
+	QueryColors(cmap, 2, querypixels, rgb);
+	if ((rgb[0].red == rgb[1].red) &&
+	    (rgb[0].green == rgb[1].green) &&
+	    (rgb[0].blue == rgb[1].blue)) {
+	    if (fore[0].val == pScreen->blackPixel)
+		fore[0].val = pScreen->whitePixel;
+	    else
+		fore[0].val = pScreen->blackPixel;
+	}
+    }
+    fore[1].val = FillSolid;
+    fmask = GCForeground|GCFillStyle;
+    if (pWin->backgroundState == BackgroundPixel) {
+	back[0].val = pWin->background.pixel;
+	back[1].val = FillSolid;
+	bmask = GCForeground|GCFillStyle;
+    } else {
+	back[0].val = 0;
+	back[1].val = 0;
+	dixChangeGC(NullClient, pGC, GCTileStipXOrigin|GCTileStipYOrigin,
+		    NULL, back);
+	back[0].val = FillTiled;
+	back[1].ptr = pWin->background.pixmap;
+	bmask = GCFillStyle|GCTile;
+    }
+
+    /* should be the same as the reference function XmuDrawLogo() */
+
+    size = width;
+    if (height < width)
+	 size = height;
+    size = RANDOM_WIDTH + rand() % (size - RANDOM_WIDTH);
+    size &= ~1;
+    x += rand() % (width - size);
+    y += rand() % (height - size);
+
+/*
+ * Draw what will be the thin strokes.
+ *
+ *           -----
+ *          /    /
+ *         /    /
+ *        /    /
+ *       /    /
+ *      /____/
+ *           d
+ *
+ * Point d is 9/44 (~1/5) of the way across.
+ */
+
+    thin = (size / 11);
+    if (thin < 1) thin = 1;
+    gap = (thin+3) / 4;
+    d31 = thin + thin + gap;
+    poly[0].x = x + size;	       poly[0].y = y;
+    poly[1].x = x + size-d31;	       poly[1].y = y;
+    poly[2].x = x + 0;		       poly[2].y = y + size;
+    poly[3].x = x + d31;	       poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for lower thin stroke.
+ *
+ *           ------
+ *          /	  /
+ *         /  __ /
+ *        /  /	/
+ *       /  /  /
+ *      /__/__/
+ */
+
+    poly[0].x = x + d31/2;			 poly[0].y = y + size;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)+(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + d31;			 poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase area not needed for upper thin stroke.
+ *
+ *	     ------
+ *	    /  /  /
+ *	   /--/	 /
+ *	  /	/
+ *	 /     /
+ *	/_____/
+ */
+
+    poly[0].x = x + size - d31/2;		 poly[0].y = y;
+    poly[1].x = x + size / 2;			 poly[1].y = y + size/2;
+    poly[2].x = x + (size/2)-(d31-(d31/2));	 poly[2].y = y + size/2;
+    poly[3].x = x + size - d31;			 poly[3].y = y;
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Draw thick stroke.
+ * Point b is 1/4 of the way across.
+ *
+ *      b
+ * -----
+ * \	\
+ *  \	 \
+ *   \	  \
+ *    \	   \
+ *     \____\
+ */
+
+    poly[0].x = x;		       poly[0].y = y;
+    poly[1].x = x + size/4;	       poly[1].y = y;
+    poly[2].x = x + size;	       poly[2].y = y + size;
+    poly[3].x = x + size - size/4;     poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, fmask, NULL, fore);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+/*
+ * Erase to create gap.
+ *
+ *	    /
+ *	   /
+ *	  /
+ *	 /
+ *	/
+ */
+
+    poly[0].x = x + size- thin;	      poly[0].y = y;
+    poly[1].x = x + size-( thin+gap);  poly[1].y = y;
+    poly[2].x = x + thin;	      poly[2].y = y + size;
+    poly[3].x = x + thin + gap;	      poly[3].y = y + size;
+    dixChangeGC(NullClient, pGC, bmask, NULL, back);
+    ValidateGC(pDraw, pGC);
+    (*pGC->ops->FillPolygon)(pDraw, pGC, Convex, CoordModeOrigin, 4, poly);
+
+    FreeScratchGC(pGC);
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
new file mode 100644
index 000000000..15fdd9ff3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
@@ -0,0 +1,2286 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/Xext/xvdisp.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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/programs/Xserver/Xext/xvdisp.c,v 1.27 2003/07/16 01:38:31 dawes Exp $ */
+
+/*
+** File: 
+**
+**   xvdisp.c --- Xv server extension dispatch module.
+**
+** Author: 
+**
+**   David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+**   11.06.91 Carver
+**     - changed SetPortControl to SetPortAttribute
+**     - changed GetPortControl to GetPortAttribute
+**     - changed QueryBestSize
+**
+**   15.05.91 Carver
+**     - version 2.0 upgrade
+**
+**   24.01.91 Carver
+**     - version 1.4 upgrade
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+#include "xvdix.h"
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#endif
+
+#include "Trap.h"
+
+#undef  TEST
+#undef  DEBUG
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "xvdisp.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+		ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+		ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#define _WriteQueryAdaptorsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
+
+#define _WriteQueryExtensionReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
+
+#define _WriteQueryEncodingsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
+
+#define _WriteAdaptorInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
+
+#define _WriteAttributeInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
+
+#define _WriteEncodingInfo(_c,_d) \
+  if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
+
+#define _WriteFormat(_c,_d) \
+  if ((_c)->swapped) SWriteFormat(_c, _d); \
+  else WriteToClient(_c, sz_xvFormat, (char*)_d)
+
+#define _WriteGrabPortReply(_c,_d) \
+  if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
+
+#define _WriteGetPortAttributeReply(_c,_d) \
+  if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
+
+#define _WriteQueryBestSizeReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
+
+#define _WriteQueryPortAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
+
+#define _WriteQueryImageAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
+
+#define _WriteListImageFormatsReply(_c,_d) \
+  if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
+
+#define _WriteImageFormatInfo(_c,_d) \
+  if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
+
+#define _AllocatePort(_i,_p) \
+  ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+    case xv_PutVideo:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutVideo(client)); break;
+        else
+#endif
+            result = (ProcXvPutVideo(client)); break;
+    case xv_PutStill:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutStill(client)); break
+        else
+#endif
+    	    result = (ProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (ProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvStopVideo(client)); break;
+	else
+#endif
+	    result = (ProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvSetPortAttribute(client)); break;
+	else
+#endif
+	    result = (ProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvShmPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest);  break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
+    case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
+    case xv_PutStill: result = (SProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (SProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage: result = (SProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest); break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+static int
+ProcXvQueryExtension(ClientPtr client)
+{
+  xvQueryExtensionReply rep;
+  /* REQUEST(xvQueryExtensionReq); */
+  REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.version = XvVersion;
+  rep.revision = XvRevision;
+
+  _WriteQueryExtensionReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvQueryAdaptors(ClientPtr client)
+{
+  xvFormat format;
+  xvAdaptorInfo ainfo;
+  xvQueryAdaptorsReply rep;
+  int totalSize;
+  int na;
+  XvAdaptorPtr pa;
+  int nf;
+  XvFormatPtr pf;
+  WindowPtr pWin;
+  ScreenPtr pScreen;
+  XvScreenPtr pxvs;
+
+  REQUEST(xvQueryAdaptorsReq);
+  REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+  if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+    {
+      client->errorValue = stuff->window;
+      return (BadWindow);
+    }
+
+  pScreen = pWin->drawable.pScreen;
+  pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+  if (!pxvs)
+    {
+      rep.type = X_Reply;
+      rep.sequenceNumber = client->sequence;
+      rep.num_adaptors = 0;
+      rep.length = 0;
+
+      _WriteQueryAdaptorsReply(client, &rep);
+
+      return Success;
+    }
+
+  (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_adaptors = pxvs->nAdaptors;
+
+  /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
+
+  totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
+
+  /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+      totalSize += (strlen(pa->name) + 3) & ~3;
+      totalSize += pa->nFormats * sz_xvFormat;
+      pa++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryAdaptorsReply(client, &rep);
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+
+      ainfo.base_id = pa->base_id;
+      ainfo.num_ports = pa->nPorts;
+      ainfo.type = pa->type;
+      ainfo.name_size = strlen(pa->name);
+      ainfo.num_formats = pa->nFormats;
+
+      _WriteAdaptorInfo(client, &ainfo);
+
+      WriteToClient(client, ainfo.name_size, pa->name);
+
+      nf = pa->nFormats;
+      pf = pa->pFormats;
+      while (nf--)
+	{
+	  format.depth = pf->depth;
+	  format.visual = pf->visual;
+	  _WriteFormat(client, &format);
+	  pf++;
+	}
+
+      pa++;
+
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+  xvEncodingInfo einfo;
+  xvQueryEncodingsReply rep;
+  int totalSize;
+  XvPortPtr pPort;
+  int ne;
+  XvEncodingPtr pe;
+  int status;
+
+  REQUEST(xvQueryEncodingsReq);
+  REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_encodings = pPort->pAdaptor->nEncodings;
+
+  /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  totalSize = ne * sz_xvEncodingInfo;
+  while (ne--)
+    {
+      totalSize += (strlen(pe->name) + 3) & ~3;
+      pe++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryEncodingsReply(client, &rep);
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  while (ne--) 
+    {
+      einfo.encoding = pe->id;
+      einfo.name_size = strlen(pe->name);
+      einfo.width = pe->width;
+      einfo.height = pe->height;
+      einfo.rate.numerator = pe->rate.numerator;
+      einfo.rate.denominator = pe->rate.denominator;
+      _WriteEncodingInfo(client, &einfo);
+      WriteToClient(client, einfo.name_size, pe->name);
+      pe++;
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutVideoReq);
+  REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvPutStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutStillReq);
+  REQUEST_SIZE_MATCH(xvPutStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetVideoReq);
+  REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetStillReq);
+  REQUEST_SIZE_MATCH(xvGetStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvSelectVideoNotify(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  REQUEST(xvSelectVideoNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+  if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadWindow);
+    }
+
+  return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSelectPortNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+  int result, status;
+  XvPortPtr pPort;
+  xvGrabPortReply rep;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result);
+
+  if (status != Success)
+    {
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.result = result;
+
+  _WriteGrabPortReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvUngrabPort(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+  int status;
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  REQUEST(xvStopVideoReq);
+  REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadDrawable);
+    }
+
+  return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diSetPortAttribute)(client, pPort, 
+				    stuff->attribute, stuff->value);
+
+  if (status == BadMatch) 
+      client->errorValue = stuff->attribute;
+  else
+      client->errorValue = stuff->value;
+
+  return status;
+}
+
+static int
+ProcXvGetPortAttribute(ClientPtr client)
+{
+  INT32 value;
+  int status;
+  XvPortPtr pPort;
+  xvGetPortAttributeReply rep;
+  REQUEST(xvGetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value);
+  if (status != Success)
+    {
+      client->errorValue = stuff->attribute;
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.value = value;
+ 
+  _WriteGetPortAttributeReply(client, &rep);
+
+  return Success;
+}
+
+static int
+ProcXvQueryBestSize(ClientPtr client)
+{
+  int status;
+  unsigned int actual_width, actual_height;
+  XvPortPtr pPort;
+  xvQueryBestSizeReply rep;
+  REQUEST(xvQueryBestSizeReq);
+  REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+
+  (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
+				       stuff->vid_w, stuff->vid_h, 
+				       stuff->drw_w, stuff->drw_h, 
+				       &actual_width, &actual_height);
+
+  rep.actual_width = actual_width;
+  rep.actual_height = actual_height;
+ 
+  _WriteQueryBestSizeReply(client, &rep);
+
+  return Success;
+}
+
+
+static int
+ProcXvQueryPortAttributes(ClientPtr client)
+{
+  int status, size, i;
+  XvPortPtr pPort;
+  XvAttributePtr pAtt;
+  xvQueryPortAttributesReply rep;
+  xvAttributeInfo Info;
+  REQUEST(xvQueryPortAttributesReq);
+  REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_attributes = pPort->pAdaptor->nAttributes;
+  rep.text_size = 0;
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {    
+      rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+  }
+
+  rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+  rep.length >>= 2;
+
+  _WriteQueryPortAttributesReply(client, &rep);
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {
+      size = strlen(pAtt->name) + 1;  /* pass the NULL */
+      Info.flags = pAtt->flags;
+      Info.min = pAtt->min_value;
+      Info.max = pAtt->max_value;
+      Info.size = (size + 3) & ~3L;
+
+      _WriteAttributeInfo(client, &Info);
+
+      WriteToClient(client, size, pAtt->name);
+  }
+
+  return Success;
+}
+
+
+
+static int 
+ProcXvPutImage(ClientPtr client)
+{
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, i, size;
+  CARD16 width, height;
+
+  REQUEST(xvPutImageReq);
+  REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  width = stuff->width;
+  height = stuff->height;
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  size += sizeof(xvPutImageReq);
+  size = (size + 3) >> 2;
+  
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+
+  if(client->req_len < size)
+     return BadLength;
+
+  return XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h,
+			    pImage, (unsigned char*)(&stuff[1]), FALSE,
+			    stuff->width, stuff->height);
+}
+
+#ifdef MITSHM
+/* redefined here since it's not in any header file */
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+extern RESTYPE ShmSegType;
+extern int BadShmSegCode;
+extern int ShmCompletionCode;
+
+static int 
+ProcXvShmPutImage(ClientPtr client)
+{
+  ShmDescPtr shmdesc;
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, size_needed, i;
+  CARD16 width, height;
+
+  REQUEST(xvShmPutImageReq);
+  REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) 
+    {
+      client->errorValue = stuff->shmseg;
+      return BadShmSegCode;  
+    }	
+ 
+  width = stuff->width;
+  height = stuff->height;
+  size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  if((size_needed + stuff->offset) > shmdesc->size)
+      return BadAccess;
+
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+     
+  status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h, pImage,
+			    (unsigned char *)shmdesc->addr + stuff->offset, 
+			    stuff->send_event, stuff->width, stuff->height);
+
+  if((status == Success) && stuff->send_event) {
+        xShmCompletionEvent ev;
+
+        ev.type = ShmCompletionCode;
+        ev.drawable = stuff->drawable;
+        ev.sequenceNumber = client->sequence;
+        ev.minorEvent = xv_ShmPutImage;
+        ev.majorEvent = XvReqCode;
+        ev.shmseg = stuff->shmseg;
+        ev.offset = stuff->offset;
+        WriteEventsToClient(client, 1, (xEvent *) &ev);
+  }
+
+  return status;
+}
+#endif
+
+#ifdef XvMCExtension
+#include "xvmcext.h"
+#endif
+
+static int 
+ProcXvQueryImageAttributes(ClientPtr client)
+{
+  xvQueryImageAttributesReply rep;
+  int size, num_planes, i;
+  CARD16 width, height;
+  XvImagePtr pImage = NULL;
+  XvPortPtr pPort;
+  int *offsets;
+  int *pitches;
+  REQUEST(xvQueryImageAttributesReq);
+
+  REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+  
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+#ifdef XvMCExtension
+  if(!pImage)
+     pImage = XvMCFindXvImage(pPort, stuff->id);
+#endif
+
+  if(!pImage)
+     return BadMatch;
+
+  num_planes = pImage->num_planes;
+
+  if(!(offsets = xalloc(num_planes << 3)))
+	return BadAlloc;
+  pitches = offsets + num_planes;
+
+  width = stuff->width;
+  height = stuff->height;
+
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
+					&width, &height, offsets, pitches);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = num_planes << 1;
+  rep.num_planes = num_planes;
+  rep.width = width;
+  rep.height = height;
+  rep.data_size = size;
+ 
+  _WriteQueryImageAttributesReply(client, &rep);
+  if(client->swapped)
+    SwapLongs((CARD32*)offsets, rep.length);
+  WriteToClient(client, rep.length << 2, (char*)offsets);
+
+  xfree(offsets);
+
+  return Success;
+}
+
+static int 
+ProcXvListImageFormats(ClientPtr client)
+{
+  XvPortPtr pPort;
+  XvImagePtr pImage;
+  int i;
+  xvListImageFormatsReply rep;
+  xvImageFormatInfo info;
+  REQUEST(xvListImageFormatsReq);
+
+  REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_formats = pPort->pAdaptor->nImages;
+  rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+  _WriteListImageFormatsReply(client, &rep);
+
+  pImage = pPort->pAdaptor->pImages;
+  
+  for(i = 0; i < rep.num_formats; i++, pImage++) {
+     info.id = pImage->id; 	
+     info.type = pImage->type; 	
+     info.byte_order = pImage->byte_order; 
+     memcpy(&info.guid, pImage->guid, 16);	
+     info.bpp = pImage->bits_per_pixel; 	
+     info.num_planes = pImage->num_planes; 	
+     info.depth = pImage->depth; 	
+     info.red_mask = pImage->red_mask; 	
+     info.green_mask = pImage->green_mask; 	
+     info.blue_mask = pImage->blue_mask; 	
+     info.format = pImage->format; 	
+     info.y_sample_bits = pImage->y_sample_bits; 	
+     info.u_sample_bits = pImage->u_sample_bits; 	
+     info.v_sample_bits = pImage->v_sample_bits; 	
+     info.horz_y_period = pImage->horz_y_period; 	
+     info.horz_u_period = pImage->horz_u_period; 	
+     info.horz_v_period = pImage->horz_v_period; 	
+     info.vert_y_period = pImage->vert_y_period; 	
+     info.vert_u_period = pImage->vert_u_period; 	
+     info.vert_v_period = pImage->vert_v_period; 	
+     memcpy(&info.comp_order, pImage->component_order, 32);	
+     info.scanline_order = pImage->scanline_order;
+     _WriteImageFormatInfo(client, &info);
+  }  
+
+  return Success;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryExtensionReq);
+  swaps(&stuff->length, n);
+  return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryAdaptorsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->window, n);
+  return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryEncodingsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvUngrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvShmPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->shmseg, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->offset, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectVideoNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectPortNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvStopVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryBestSizeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryPortAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryImageAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->width, n);
+  return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvListImageFormatsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+   ClientPtr client,
+   xvQueryExtensionReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->version, n);
+  swaps(&rep->revision, n);
+  
+  (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryAdaptorsReply(
+   ClientPtr client,
+   xvQueryAdaptorsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_adaptors, n);
+  
+  (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryEncodingsReply(
+   ClientPtr client,
+   xvQueryEncodingsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_encodings, n);
+  
+  (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteAdaptorInfo(
+   ClientPtr client,
+   xvAdaptorInfo *pAdaptor
+){
+  register char n;
+
+  swapl(&pAdaptor->base_id, n);
+  swaps(&pAdaptor->name_size, n);
+  swaps(&pAdaptor->num_ports, n);
+  swaps(&pAdaptor->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
+
+  return Success;
+}
+
+static int
+SWriteEncodingInfo(
+   ClientPtr client,
+   xvEncodingInfo *pEncoding
+){
+  register char n;
+  
+  swapl(&pEncoding->encoding, n);
+  swaps(&pEncoding->name_size, n);
+  swaps(&pEncoding->width, n);
+  swaps(&pEncoding->height, n);
+  swapl(&pEncoding->rate.numerator, n);
+  swapl(&pEncoding->rate.denominator, n);
+  (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
+
+  return Success;
+}
+
+static int
+SWriteFormat(
+   ClientPtr client,
+   xvFormat *pFormat
+){
+  register char n;
+
+  swapl(&pFormat->visual, n);
+  (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+  return Success;
+}
+
+static int
+SWriteAttributeInfo(
+   ClientPtr client,
+   xvAttributeInfo *pAtt
+){
+  register char n;
+
+  swapl(&pAtt->flags, n);
+  swapl(&pAtt->size, n);
+  swapl(&pAtt->min, n);
+  swapl(&pAtt->max, n);
+  (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
+
+  return Success;
+}
+
+static int
+SWriteImageFormatInfo(
+   ClientPtr client,
+   xvImageFormatInfo *pImage
+){
+  register char n;
+
+  swapl(&pImage->id, n);
+  swapl(&pImage->red_mask, n);
+  swapl(&pImage->green_mask, n);
+  swapl(&pImage->blue_mask, n);
+  swapl(&pImage->y_sample_bits, n);
+  swapl(&pImage->u_sample_bits, n);
+  swapl(&pImage->v_sample_bits, n);
+  swapl(&pImage->horz_y_period, n);
+  swapl(&pImage->horz_u_period, n);
+  swapl(&pImage->horz_v_period, n);
+  swapl(&pImage->vert_y_period, n);
+  swapl(&pImage->vert_u_period, n);
+  swapl(&pImage->vert_v_period, n);
+
+  (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
+
+  return Success;
+}
+
+
+
+static int
+SWriteGrabPortReply(
+   ClientPtr client,
+   xvGrabPortReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+
+  (void)WriteToClient(client, sz_xvGrabPortReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteGetPortAttributeReply(
+   ClientPtr client,
+   xvGetPortAttributeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->value, n);
+
+  (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryBestSizeReply(
+   ClientPtr client,
+   xvQueryBestSizeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->actual_width, n);
+  swaps(&rep->actual_height, n);
+
+  (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryPortAttributesReply(
+   ClientPtr client,
+   xvQueryPortAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_attributes, n);
+  swapl(&rep->text_size, n);
+
+  (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryImageAttributesReply(
+   ClientPtr client,
+   xvQueryImageAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_planes, n);
+  swapl(&rep->data_size, n);
+  swaps(&rep->width, n);
+  swaps(&rep->height, n);
+
+  (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+
+static int
+SWriteListImageFormatsReply(
+   ClientPtr client,
+   xvListImageFormatsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+  return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+   int result = Success, i;
+   PanoramiXRes *draw, *port;
+   REQUEST(xvStopVideoReq);
+   REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+   if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+   if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+   FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   result = ProcXvStopVideo(client);
+     	}
+   }
+
+   return result;
+}
+
+static int
+XineramaXvSetPortAttribute(ClientPtr client)
+{
+    REQUEST(xvSetPortAttributeReq);
+    PanoramiXRes *port;
+    int result = Success, i;
+
+    REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->port = port->info[i].id;
+	   result = ProcXvSetPortAttribute(client);
+	}
+    }
+    return result;
+}
+
+
+#ifdef MITSHM
+static int 
+XineramaXvShmPutImage(ClientPtr client)
+{
+    REQUEST(xvShmPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool send_event = stuff->send_event;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+	   stuff->send_event = (send_event && !i) ? 1 : 0;
+
+	   result = ProcXvShmPutImage(client);
+	}
+    }
+    return result;
+}
+#endif
+
+static int 
+XineramaXvPutImage(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+		client, stuff->port, XvXRTPort, SecurityReadAccess)))
+	return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+
+	   result = ProcXvPutImage(client);
+	}
+    }
+    return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutVideo(client);
+        }
+    }
+    return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutStill(client);
+        }
+    }
+    return result;
+}
+
+
+void XineramifyXv(void)
+{
+   ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+   XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+   XvAdaptorPtr refAdapt, pAdapt;
+   XvAttributePtr pAttr;
+   XvScreenPtr xvsp;
+   Bool isOverlay, hasOverlay;
+   PanoramiXRes *port;
+   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   int i, j, k, l;
+
+   XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+   if(!xvsp0) return;
+   
+   for(i = 0; i < xvsp0->nAdaptors; i++) {
+      refAdapt = xvsp0->pAdaptors + i;
+
+      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+      
+      MatchingAdaptors[0] = refAdapt;
+   
+      if(!(refAdapt->type & XvInputMask)) continue;
+      
+      isOverlay = FALSE;
+      for(j = 0; j < refAdapt->nAttributes; j++) {
+         pAttr = refAdapt->pAttributes + j;
+         if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+	    isOverlay = TRUE;
+	    break;
+	 }
+      }
+   
+      for(j = 1; j < PanoramiXNumScreens; j++) {
+         pScreen = screenInfo.screens[j];
+	 xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+         /* Do not try to go on if xv is not supported on this screen */
+         if (xvsp==NULL) continue ;
+	 
+         /* if the adaptor has the same name it's a perfect match */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	   pAdapt = xvsp->pAdaptors + k;
+           if(!strcmp(refAdapt->name, pAdapt->name)) {
+	       MatchingAdaptors[j] = pAdapt;
+	       break;
+	   }
+         }
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* otherwise we only look for XvImage adaptors */
+	 if(!(refAdapt->type & XvImageMask)) continue;
+	 if(refAdapt->nImages <= 0) continue;
+	 
+	 /* prefer overlay/overlay non-overlay/non-overlay pairing */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      hasOverlay = FALSE;
+              for(l = 0; l < pAdapt->nAttributes; l++) {
+	         if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+		   hasOverlay = TRUE;
+		   break;
+		 }
+	      }
+	      if(isOverlay && hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+              else if(!isOverlay && !hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+	    }
+         }
+	 
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* but we'll take any XvImage pairing if we can get it */
+	 	 
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	    }
+         }
+      }
+
+      /* now create a resource for each port */
+      for(j = 0; j < refAdapt->nPorts; j++) {
+         if(!(port = xalloc(sizeof(PanoramiXRes))))
+	    break;
+	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
+	 AddResource(port->info[0].id, XvXRTPort, port);
+
+	 for(k = 1; k < PanoramiXNumScreens; k++) {
+	    if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 
+		port->info[k].id = MatchingAdaptors[k]->base_id + j;
+	    else
+		port->info[k].id = 0;
+	 } 
+      }
+   }
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
new file mode 100644
index 000000000..15fdd9ff3
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
@@ -0,0 +1,2286 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* $XdotOrg: xc/programs/Xserver/Xext/xvdisp.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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/programs/Xserver/Xext/xvdisp.c,v 1.27 2003/07/16 01:38:31 dawes Exp $ */
+
+/*
+** File: 
+**
+**   xvdisp.c --- Xv server extension dispatch module.
+**
+** Author: 
+**
+**   David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+**   11.06.91 Carver
+**     - changed SetPortControl to SetPortAttribute
+**     - changed GetPortControl to GetPortAttribute
+**     - changed QueryBestSize
+**
+**   15.05.91 Carver
+**     - version 2.0 upgrade
+**
+**   24.01.91 Carver
+**     - version 1.4 upgrade
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+#include "xvdix.h"
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#endif
+
+#include "Trap.h"
+
+#undef  TEST
+#undef  DEBUG
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "xvdisp.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+		ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+		ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#define _WriteQueryAdaptorsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
+
+#define _WriteQueryExtensionReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
+
+#define _WriteQueryEncodingsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
+
+#define _WriteAdaptorInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
+
+#define _WriteAttributeInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
+
+#define _WriteEncodingInfo(_c,_d) \
+  if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
+
+#define _WriteFormat(_c,_d) \
+  if ((_c)->swapped) SWriteFormat(_c, _d); \
+  else WriteToClient(_c, sz_xvFormat, (char*)_d)
+
+#define _WriteGrabPortReply(_c,_d) \
+  if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
+
+#define _WriteGetPortAttributeReply(_c,_d) \
+  if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
+
+#define _WriteQueryBestSizeReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
+
+#define _WriteQueryPortAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
+
+#define _WriteQueryImageAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
+
+#define _WriteListImageFormatsReply(_c,_d) \
+  if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
+
+#define _WriteImageFormatInfo(_c,_d) \
+  if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
+
+#define _AllocatePort(_i,_p) \
+  ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (ProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (ProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (ProcXvQueryEncodings(client)); break;
+    case xv_PutVideo:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutVideo(client)); break;
+        else
+#endif
+            result = (ProcXvPutVideo(client)); break;
+    case xv_PutStill:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            result = (XineramaXvPutStill(client)); break
+        else
+#endif
+    	    result = (ProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (ProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (ProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (ProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (ProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (ProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (ProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvStopVideo(client)); break;
+	else
+#endif
+	    result = (ProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvSetPortAttribute(client)); break;
+	else
+#endif
+	    result = (ProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (ProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (ProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (ProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    result = (XineramaXvShmPutImage(client)); break;
+	else
+#endif
+	    result = (ProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (ProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (ProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest);  break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+  int result;
+
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  /*
+   * Report upstream that we are
+   * dispatching a XVideo operation.
+   */
+
+  nxagentXvTrap = 1;
+
+  #ifdef TEST
+  fprintf(stderr, "SProcXvDispatch: Going to dispatch XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: result = (SProcXvQueryExtension(client)); break;
+    case xv_QueryAdaptors: result = (SProcXvQueryAdaptors(client)); break;
+    case xv_QueryEncodings: result = (SProcXvQueryEncodings(client)); break;
+    case xv_PutVideo: result = (SProcXvPutVideo(client)); break;
+    case xv_PutStill: result = (SProcXvPutStill(client)); break;
+    case xv_GetVideo: result = (SProcXvGetVideo(client)); break;
+    case xv_GetStill: result = (SProcXvGetStill(client)); break;
+    case xv_GrabPort: result = (SProcXvGrabPort(client)); break;
+    case xv_UngrabPort: result = (SProcXvUngrabPort(client)); break;
+    case xv_SelectVideoNotify: result = (SProcXvSelectVideoNotify(client)); break;
+    case xv_SelectPortNotify: result = (SProcXvSelectPortNotify(client)); break;
+    case xv_StopVideo: result = (SProcXvStopVideo(client)); break;
+    case xv_SetPortAttribute: result = (SProcXvSetPortAttribute(client)); break;
+    case xv_GetPortAttribute: result = (SProcXvGetPortAttribute(client)); break;
+    case xv_QueryBestSize: result = (SProcXvQueryBestSize(client)); break;
+    case xv_QueryPortAttributes: result = (SProcXvQueryPortAttributes(client)); break;
+    case xv_PutImage: result = (SProcXvPutImage(client)); break;
+#ifdef MITSHM
+    case xv_ShmPutImage: result = (SProcXvShmPutImage(client)); break;
+#endif
+    case xv_QueryImageAttributes: result = (SProcXvQueryImageAttributes(client)); break;
+    case xv_ListImageFormats: result = (SProcXvListImageFormats(client)); break;
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  result = (BadImplementation); break;
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  result = (BadRequest); break;
+	}
+    }
+
+  nxagentXvTrap = 0;
+
+  #ifdef TEST
+  fprintf(stderr, "ProcXvDispatch: Dispatched XVideo operation [%d] for client [%d].\n", 
+              stuff->data, client -> index);
+  #endif
+
+  return result;
+}
+
+static int
+ProcXvQueryExtension(ClientPtr client)
+{
+  xvQueryExtensionReply rep;
+  /* REQUEST(xvQueryExtensionReq); */
+  REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.version = XvVersion;
+  rep.revision = XvRevision;
+
+  _WriteQueryExtensionReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvQueryAdaptors(ClientPtr client)
+{
+  xvFormat format;
+  xvAdaptorInfo ainfo;
+  xvQueryAdaptorsReply rep;
+  int totalSize;
+  int na;
+  XvAdaptorPtr pa;
+  int nf;
+  XvFormatPtr pf;
+  WindowPtr pWin;
+  ScreenPtr pScreen;
+  XvScreenPtr pxvs;
+
+  REQUEST(xvQueryAdaptorsReq);
+  REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+  if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+    {
+      client->errorValue = stuff->window;
+      return (BadWindow);
+    }
+
+  pScreen = pWin->drawable.pScreen;
+  pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+  if (!pxvs)
+    {
+      rep.type = X_Reply;
+      rep.sequenceNumber = client->sequence;
+      rep.num_adaptors = 0;
+      rep.length = 0;
+
+      _WriteQueryAdaptorsReply(client, &rep);
+
+      return Success;
+    }
+
+  (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_adaptors = pxvs->nAdaptors;
+
+  /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
+
+  totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
+
+  /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+      totalSize += (strlen(pa->name) + 3) & ~3;
+      totalSize += pa->nFormats * sz_xvFormat;
+      pa++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryAdaptorsReply(client, &rep);
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+
+      ainfo.base_id = pa->base_id;
+      ainfo.num_ports = pa->nPorts;
+      ainfo.type = pa->type;
+      ainfo.name_size = strlen(pa->name);
+      ainfo.num_formats = pa->nFormats;
+
+      _WriteAdaptorInfo(client, &ainfo);
+
+      WriteToClient(client, ainfo.name_size, pa->name);
+
+      nf = pa->nFormats;
+      pf = pa->pFormats;
+      while (nf--)
+	{
+	  format.depth = pf->depth;
+	  format.visual = pf->visual;
+	  _WriteFormat(client, &format);
+	  pf++;
+	}
+
+      pa++;
+
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+  xvEncodingInfo einfo;
+  xvQueryEncodingsReply rep;
+  int totalSize;
+  XvPortPtr pPort;
+  int ne;
+  XvEncodingPtr pe;
+  int status;
+
+  REQUEST(xvQueryEncodingsReq);
+  REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_encodings = pPort->pAdaptor->nEncodings;
+
+  /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  totalSize = ne * sz_xvEncodingInfo;
+  while (ne--)
+    {
+      totalSize += (strlen(pe->name) + 3) & ~3;
+      pe++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryEncodingsReply(client, &rep);
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  while (ne--) 
+    {
+      einfo.encoding = pe->id;
+      einfo.name_size = strlen(pe->name);
+      einfo.width = pe->width;
+      einfo.height = pe->height;
+      einfo.rate.numerator = pe->rate.numerator;
+      einfo.rate.denominator = pe->rate.denominator;
+      _WriteEncodingInfo(client, &einfo);
+      WriteToClient(client, einfo.name_size, pe->name);
+      pe++;
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutVideoReq);
+  REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvPutStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutStillReq);
+  REQUEST_SIZE_MATCH(xvPutStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetVideoReq);
+  REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetStillReq);
+  REQUEST_SIZE_MATCH(xvGetStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvSelectVideoNotify(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  REQUEST(xvSelectVideoNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+  if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadWindow);
+    }
+
+  return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSelectPortNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+  int result, status;
+  XvPortPtr pPort;
+  xvGrabPortReply rep;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result);
+
+  if (status != Success)
+    {
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.result = result;
+
+  _WriteGrabPortReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvUngrabPort(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+  int status;
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  REQUEST(xvStopVideoReq);
+  REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadDrawable);
+    }
+
+  return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diSetPortAttribute)(client, pPort, 
+				    stuff->attribute, stuff->value);
+
+  if (status == BadMatch) 
+      client->errorValue = stuff->attribute;
+  else
+      client->errorValue = stuff->value;
+
+  return status;
+}
+
+static int
+ProcXvGetPortAttribute(ClientPtr client)
+{
+  INT32 value;
+  int status;
+  XvPortPtr pPort;
+  xvGetPortAttributeReply rep;
+  REQUEST(xvGetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value);
+  if (status != Success)
+    {
+      client->errorValue = stuff->attribute;
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.value = value;
+ 
+  _WriteGetPortAttributeReply(client, &rep);
+
+  return Success;
+}
+
+static int
+ProcXvQueryBestSize(ClientPtr client)
+{
+  int status;
+  unsigned int actual_width, actual_height;
+  XvPortPtr pPort;
+  xvQueryBestSizeReply rep;
+  REQUEST(xvQueryBestSizeReq);
+  REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+
+  (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
+				       stuff->vid_w, stuff->vid_h, 
+				       stuff->drw_w, stuff->drw_h, 
+				       &actual_width, &actual_height);
+
+  rep.actual_width = actual_width;
+  rep.actual_height = actual_height;
+ 
+  _WriteQueryBestSizeReply(client, &rep);
+
+  return Success;
+}
+
+
+static int
+ProcXvQueryPortAttributes(ClientPtr client)
+{
+  int status, size, i;
+  XvPortPtr pPort;
+  XvAttributePtr pAtt;
+  xvQueryPortAttributesReply rep;
+  xvAttributeInfo Info;
+  REQUEST(xvQueryPortAttributesReq);
+  REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_attributes = pPort->pAdaptor->nAttributes;
+  rep.text_size = 0;
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {    
+      rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+  }
+
+  rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+  rep.length >>= 2;
+
+  _WriteQueryPortAttributesReply(client, &rep);
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {
+      size = strlen(pAtt->name) + 1;  /* pass the NULL */
+      Info.flags = pAtt->flags;
+      Info.min = pAtt->min_value;
+      Info.max = pAtt->max_value;
+      Info.size = (size + 3) & ~3L;
+
+      _WriteAttributeInfo(client, &Info);
+
+      WriteToClient(client, size, pAtt->name);
+  }
+
+  return Success;
+}
+
+
+
+static int 
+ProcXvPutImage(ClientPtr client)
+{
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, i, size;
+  CARD16 width, height;
+
+  REQUEST(xvPutImageReq);
+  REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  width = stuff->width;
+  height = stuff->height;
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  size += sizeof(xvPutImageReq);
+  size = (size + 3) >> 2;
+  
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+
+  if(client->req_len < size)
+     return BadLength;
+
+  return XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h,
+			    pImage, (unsigned char*)(&stuff[1]), FALSE,
+			    stuff->width, stuff->height);
+}
+
+#ifdef MITSHM
+/* redefined here since it's not in any header file */
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+extern RESTYPE ShmSegType;
+extern int BadShmSegCode;
+extern int ShmCompletionCode;
+
+static int 
+ProcXvShmPutImage(ClientPtr client)
+{
+  ShmDescPtr shmdesc;
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, size_needed, i;
+  CARD16 width, height;
+
+  REQUEST(xvShmPutImageReq);
+  REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) 
+    {
+      client->errorValue = stuff->shmseg;
+      return BadShmSegCode;  
+    }	
+ 
+  width = stuff->width;
+  height = stuff->height;
+  size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  if((size_needed + stuff->offset) > shmdesc->size)
+      return BadAccess;
+
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+     
+  status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h, pImage,
+			    (unsigned char *)shmdesc->addr + stuff->offset, 
+			    stuff->send_event, stuff->width, stuff->height);
+
+  if((status == Success) && stuff->send_event) {
+        xShmCompletionEvent ev;
+
+        ev.type = ShmCompletionCode;
+        ev.drawable = stuff->drawable;
+        ev.sequenceNumber = client->sequence;
+        ev.minorEvent = xv_ShmPutImage;
+        ev.majorEvent = XvReqCode;
+        ev.shmseg = stuff->shmseg;
+        ev.offset = stuff->offset;
+        WriteEventsToClient(client, 1, (xEvent *) &ev);
+  }
+
+  return status;
+}
+#endif
+
+#ifdef XvMCExtension
+#include "xvmcext.h"
+#endif
+
+static int 
+ProcXvQueryImageAttributes(ClientPtr client)
+{
+  xvQueryImageAttributesReply rep;
+  int size, num_planes, i;
+  CARD16 width, height;
+  XvImagePtr pImage = NULL;
+  XvPortPtr pPort;
+  int *offsets;
+  int *pitches;
+  REQUEST(xvQueryImageAttributesReq);
+
+  REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+  
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+#ifdef XvMCExtension
+  if(!pImage)
+     pImage = XvMCFindXvImage(pPort, stuff->id);
+#endif
+
+  if(!pImage)
+     return BadMatch;
+
+  num_planes = pImage->num_planes;
+
+  if(!(offsets = xalloc(num_planes << 3)))
+	return BadAlloc;
+  pitches = offsets + num_planes;
+
+  width = stuff->width;
+  height = stuff->height;
+
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
+					&width, &height, offsets, pitches);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = num_planes << 1;
+  rep.num_planes = num_planes;
+  rep.width = width;
+  rep.height = height;
+  rep.data_size = size;
+ 
+  _WriteQueryImageAttributesReply(client, &rep);
+  if(client->swapped)
+    SwapLongs((CARD32*)offsets, rep.length);
+  WriteToClient(client, rep.length << 2, (char*)offsets);
+
+  xfree(offsets);
+
+  return Success;
+}
+
+static int 
+ProcXvListImageFormats(ClientPtr client)
+{
+  XvPortPtr pPort;
+  XvImagePtr pImage;
+  int i;
+  xvListImageFormatsReply rep;
+  xvImageFormatInfo info;
+  REQUEST(xvListImageFormatsReq);
+
+  REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_formats = pPort->pAdaptor->nImages;
+  rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+  _WriteListImageFormatsReply(client, &rep);
+
+  pImage = pPort->pAdaptor->pImages;
+  
+  for(i = 0; i < rep.num_formats; i++, pImage++) {
+     info.id = pImage->id; 	
+     info.type = pImage->type; 	
+     info.byte_order = pImage->byte_order; 
+     memcpy(&info.guid, pImage->guid, 16);	
+     info.bpp = pImage->bits_per_pixel; 	
+     info.num_planes = pImage->num_planes; 	
+     info.depth = pImage->depth; 	
+     info.red_mask = pImage->red_mask; 	
+     info.green_mask = pImage->green_mask; 	
+     info.blue_mask = pImage->blue_mask; 	
+     info.format = pImage->format; 	
+     info.y_sample_bits = pImage->y_sample_bits; 	
+     info.u_sample_bits = pImage->u_sample_bits; 	
+     info.v_sample_bits = pImage->v_sample_bits; 	
+     info.horz_y_period = pImage->horz_y_period; 	
+     info.horz_u_period = pImage->horz_u_period; 	
+     info.horz_v_period = pImage->horz_v_period; 	
+     info.vert_y_period = pImage->vert_y_period; 	
+     info.vert_u_period = pImage->vert_u_period; 	
+     info.vert_v_period = pImage->vert_v_period; 	
+     memcpy(&info.comp_order, pImage->component_order, 32);	
+     info.scanline_order = pImage->scanline_order;
+     _WriteImageFormatInfo(client, &info);
+  }  
+
+  return Success;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryExtensionReq);
+  swaps(&stuff->length, n);
+  return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryAdaptorsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->window, n);
+  return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryEncodingsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvUngrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvShmPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->shmseg, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->offset, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectVideoNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectPortNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvStopVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryBestSizeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryPortAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryImageAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->width, n);
+  return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvListImageFormatsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+   ClientPtr client,
+   xvQueryExtensionReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->version, n);
+  swaps(&rep->revision, n);
+  
+  (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryAdaptorsReply(
+   ClientPtr client,
+   xvQueryAdaptorsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_adaptors, n);
+  
+  (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryEncodingsReply(
+   ClientPtr client,
+   xvQueryEncodingsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_encodings, n);
+  
+  (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteAdaptorInfo(
+   ClientPtr client,
+   xvAdaptorInfo *pAdaptor
+){
+  register char n;
+
+  swapl(&pAdaptor->base_id, n);
+  swaps(&pAdaptor->name_size, n);
+  swaps(&pAdaptor->num_ports, n);
+  swaps(&pAdaptor->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
+
+  return Success;
+}
+
+static int
+SWriteEncodingInfo(
+   ClientPtr client,
+   xvEncodingInfo *pEncoding
+){
+  register char n;
+  
+  swapl(&pEncoding->encoding, n);
+  swaps(&pEncoding->name_size, n);
+  swaps(&pEncoding->width, n);
+  swaps(&pEncoding->height, n);
+  swapl(&pEncoding->rate.numerator, n);
+  swapl(&pEncoding->rate.denominator, n);
+  (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
+
+  return Success;
+}
+
+static int
+SWriteFormat(
+   ClientPtr client,
+   xvFormat *pFormat
+){
+  register char n;
+
+  swapl(&pFormat->visual, n);
+  (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+  return Success;
+}
+
+static int
+SWriteAttributeInfo(
+   ClientPtr client,
+   xvAttributeInfo *pAtt
+){
+  register char n;
+
+  swapl(&pAtt->flags, n);
+  swapl(&pAtt->size, n);
+  swapl(&pAtt->min, n);
+  swapl(&pAtt->max, n);
+  (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
+
+  return Success;
+}
+
+static int
+SWriteImageFormatInfo(
+   ClientPtr client,
+   xvImageFormatInfo *pImage
+){
+  register char n;
+
+  swapl(&pImage->id, n);
+  swapl(&pImage->red_mask, n);
+  swapl(&pImage->green_mask, n);
+  swapl(&pImage->blue_mask, n);
+  swapl(&pImage->y_sample_bits, n);
+  swapl(&pImage->u_sample_bits, n);
+  swapl(&pImage->v_sample_bits, n);
+  swapl(&pImage->horz_y_period, n);
+  swapl(&pImage->horz_u_period, n);
+  swapl(&pImage->horz_v_period, n);
+  swapl(&pImage->vert_y_period, n);
+  swapl(&pImage->vert_u_period, n);
+  swapl(&pImage->vert_v_period, n);
+
+  (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
+
+  return Success;
+}
+
+
+
+static int
+SWriteGrabPortReply(
+   ClientPtr client,
+   xvGrabPortReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+
+  (void)WriteToClient(client, sz_xvGrabPortReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteGetPortAttributeReply(
+   ClientPtr client,
+   xvGetPortAttributeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->value, n);
+
+  (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryBestSizeReply(
+   ClientPtr client,
+   xvQueryBestSizeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->actual_width, n);
+  swaps(&rep->actual_height, n);
+
+  (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryPortAttributesReply(
+   ClientPtr client,
+   xvQueryPortAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_attributes, n);
+  swapl(&rep->text_size, n);
+
+  (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryImageAttributesReply(
+   ClientPtr client,
+   xvQueryImageAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_planes, n);
+  swapl(&rep->data_size, n);
+  swaps(&rep->width, n);
+  swaps(&rep->height, n);
+
+  (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+
+static int
+SWriteListImageFormatsReply(
+   ClientPtr client,
+   xvListImageFormatsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+  return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+   int result = Success, i;
+   PanoramiXRes *draw, *port;
+   REQUEST(xvStopVideoReq);
+   REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+   if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+   if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+   FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   result = ProcXvStopVideo(client);
+     	}
+   }
+
+   return result;
+}
+
+static int
+XineramaXvSetPortAttribute(ClientPtr client)
+{
+    REQUEST(xvSetPortAttributeReq);
+    PanoramiXRes *port;
+    int result = Success, i;
+
+    REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->port = port->info[i].id;
+	   result = ProcXvSetPortAttribute(client);
+	}
+    }
+    return result;
+}
+
+
+#ifdef MITSHM
+static int 
+XineramaXvShmPutImage(ClientPtr client)
+{
+    REQUEST(xvShmPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool send_event = stuff->send_event;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+	   stuff->send_event = (send_event && !i) ? 1 : 0;
+
+	   result = ProcXvShmPutImage(client);
+	}
+    }
+    return result;
+}
+#endif
+
+static int 
+XineramaXvPutImage(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+		client, stuff->port, XvXRTPort, SecurityReadAccess)))
+	return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+
+	   result = ProcXvPutImage(client);
+	}
+    }
+    return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutVideo(client);
+        }
+    }
+    return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutStill(client);
+        }
+    }
+    return result;
+}
+
+
+void XineramifyXv(void)
+{
+   ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+   XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+   XvAdaptorPtr refAdapt, pAdapt;
+   XvAttributePtr pAttr;
+   XvScreenPtr xvsp;
+   Bool isOverlay, hasOverlay;
+   PanoramiXRes *port;
+   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   int i, j, k, l;
+
+   XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+   if(!xvsp0) return;
+   
+   for(i = 0; i < xvsp0->nAdaptors; i++) {
+      refAdapt = xvsp0->pAdaptors + i;
+
+      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+      
+      MatchingAdaptors[0] = refAdapt;
+   
+      if(!(refAdapt->type & XvInputMask)) continue;
+      
+      isOverlay = FALSE;
+      for(j = 0; j < refAdapt->nAttributes; j++) {
+         pAttr = refAdapt->pAttributes + j;
+         if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+	    isOverlay = TRUE;
+	    break;
+	 }
+      }
+   
+      for(j = 1; j < PanoramiXNumScreens; j++) {
+         pScreen = screenInfo.screens[j];
+	 xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+         /* Do not try to go on if xv is not supported on this screen */
+         if (xvsp==NULL) continue ;
+	 
+         /* if the adaptor has the same name it's a perfect match */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	   pAdapt = xvsp->pAdaptors + k;
+           if(!strcmp(refAdapt->name, pAdapt->name)) {
+	       MatchingAdaptors[j] = pAdapt;
+	       break;
+	   }
+         }
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* otherwise we only look for XvImage adaptors */
+	 if(!(refAdapt->type & XvImageMask)) continue;
+	 if(refAdapt->nImages <= 0) continue;
+	 
+	 /* prefer overlay/overlay non-overlay/non-overlay pairing */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      hasOverlay = FALSE;
+              for(l = 0; l < pAdapt->nAttributes; l++) {
+	         if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+		   hasOverlay = TRUE;
+		   break;
+		 }
+	      }
+	      if(isOverlay && hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+              else if(!isOverlay && !hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+	    }
+         }
+	 
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* but we'll take any XvImage pairing if we can get it */
+	 	 
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	    }
+         }
+      }
+
+      /* now create a resource for each port */
+      for(j = 0; j < refAdapt->nPorts; j++) {
+         if(!(port = xalloc(sizeof(PanoramiXRes))))
+	    break;
+	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
+	 AddResource(port->info[0].id, XvXRTPort, port);
+
+	 for(k = 1; k < PanoramiXNumScreens; k++) {
+	    if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 
+		port->info[k].id = MatchingAdaptors[k]->base_id + j;
+	    else
+		port->info[k].id = 0;
+	 } 
+      }
+   }
+}
+
+#endif
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original
new file mode 100644
index 000000000..21ab0b6a0
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.X.original
@@ -0,0 +1,2217 @@
+/* $XdotOrg: xc/programs/Xserver/Xext/xvdisp.c,v 1.6 2005/07/03 08:53:36 daniels Exp $ */
+/***********************************************************
+Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+                        All Rights Reserved
+
+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 names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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/programs/Xserver/Xext/xvdisp.c,v 1.27 2003/07/16 01:38:31 dawes Exp $ */
+
+/*
+** File: 
+**
+**   xvdisp.c --- Xv server extension dispatch module.
+**
+** Author: 
+**
+**   David Carver (Digital Workstation Engineering/Project Athena)
+**
+** Revisions:
+**
+**   11.06.91 Carver
+**     - changed SetPortControl to SetPortAttribute
+**     - changed GetPortControl to GetPortAttribute
+**     - changed QueryBestSize
+**
+**   15.05.91 Carver
+**     - version 2.0 upgrade
+**
+**   24.01.91 Carver
+**     - version 1.4 upgrade
+**
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+#include "xvdix.h"
+#ifdef MITSHM
+#define _XSHM_SERVER_
+#include <X11/extensions/shmstr.h>
+#endif
+
+#ifdef EXTMODULE
+#include "xf86_ansic.h"
+#endif
+
+#include "xvdisp.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+unsigned long XvXRTPort;
+
+#ifdef MITSHM
+static int XineramaXvShmPutImage(ClientPtr);
+#endif
+static int XineramaXvPutImage(ClientPtr);
+static int XineramaXvPutVideo(ClientPtr);
+static int XineramaXvPutStill(ClientPtr);
+static int XineramaXvSetPortAttribute(ClientPtr);
+static int XineramaXvStopVideo(ClientPtr);
+#endif
+
+/* INTERNAL */
+
+static int ProcXvQueryExtension(ClientPtr);
+static int ProcXvQueryAdaptors(ClientPtr);
+static int ProcXvQueryEncodings(ClientPtr);
+static int ProcXvPutVideo(ClientPtr);
+static int ProcXvPutStill(ClientPtr);
+static int ProcXvGetVideo(ClientPtr);
+static int ProcXvGetStill(ClientPtr);
+static int ProcXvGrabPort(ClientPtr);
+static int ProcXvUngrabPort(ClientPtr);
+static int ProcXvSelectVideoNotify(ClientPtr);
+static int ProcXvSelectPortNotify(ClientPtr);
+static int ProcXvStopVideo(ClientPtr);
+static int ProcXvSetPortAttribute(ClientPtr);
+static int ProcXvGetPortAttribute(ClientPtr);
+static int ProcXvQueryBestSize(ClientPtr);
+static int ProcXvQueryPortAttributes(ClientPtr);
+static int ProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int ProcXvShmPutImage(ClientPtr);
+#endif
+static int ProcXvQueryImageAttributes(ClientPtr);
+static int ProcXvListImageFormats(ClientPtr);
+
+static int SProcXvQueryExtension(ClientPtr);
+static int SProcXvQueryAdaptors(ClientPtr);
+static int SProcXvQueryEncodings(ClientPtr);
+static int SProcXvPutVideo(ClientPtr);
+static int SProcXvPutStill(ClientPtr);
+static int SProcXvGetVideo(ClientPtr);
+static int SProcXvGetStill(ClientPtr);
+static int SProcXvGrabPort(ClientPtr);
+static int SProcXvUngrabPort(ClientPtr);
+static int SProcXvSelectVideoNotify(ClientPtr);
+static int SProcXvSelectPortNotify(ClientPtr);
+static int SProcXvStopVideo(ClientPtr);
+static int SProcXvSetPortAttribute(ClientPtr);
+static int SProcXvGetPortAttribute(ClientPtr);
+static int SProcXvQueryBestSize(ClientPtr);
+static int SProcXvQueryPortAttributes(ClientPtr);
+static int SProcXvPutImage(ClientPtr);
+#ifdef MITSHM
+static int SProcXvShmPutImage(ClientPtr);
+#endif
+static int SProcXvQueryImageAttributes(ClientPtr);
+static int SProcXvListImageFormats(ClientPtr);
+
+static int SWriteQueryAdaptorsReply(ClientPtr, xvQueryAdaptorsReply *);
+static int SWriteQueryExtensionReply(ClientPtr, xvQueryExtensionReply *);
+static int SWriteQueryEncodingsReply(ClientPtr, xvQueryEncodingsReply *);
+static int SWriteAdaptorInfo(ClientPtr, xvAdaptorInfo *);
+static int SWriteEncodingInfo(ClientPtr, xvEncodingInfo *);
+static int SWriteFormat(ClientPtr, xvFormat *);
+static int SWriteAttributeInfo(ClientPtr, xvAttributeInfo *);
+static int SWriteGrabPortReply(ClientPtr, xvGrabPortReply *);
+static int SWriteGetPortAttributeReply(ClientPtr, xvGetPortAttributeReply *);
+static int SWriteQueryBestSizeReply(ClientPtr, xvQueryBestSizeReply *);
+static int SWriteQueryPortAttributesReply(
+		ClientPtr, xvQueryPortAttributesReply *);
+static int SWriteQueryImageAttributesReply(
+		ClientPtr, xvQueryImageAttributesReply*);
+static int SWriteListImageFormatsReply(ClientPtr, xvListImageFormatsReply*);
+static int SWriteImageFormatInfo(ClientPtr, xvImageFormatInfo*);
+
+#define _WriteQueryAdaptorsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryAdaptorsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryAdaptorsReply, (char*)_d)
+
+#define _WriteQueryExtensionReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryExtensionReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryExtensionReply, (char*)_d)
+
+#define _WriteQueryEncodingsReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryEncodingsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryEncodingsReply, (char*)_d)
+
+#define _WriteAdaptorInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAdaptorInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAdaptorInfo, (char*)_d)
+
+#define _WriteAttributeInfo(_c,_d) \
+  if ((_c)->swapped) SWriteAttributeInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvAttributeInfo, (char*)_d)
+
+#define _WriteEncodingInfo(_c,_d) \
+  if ((_c)->swapped) SWriteEncodingInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvEncodingInfo, (char*)_d)
+
+#define _WriteFormat(_c,_d) \
+  if ((_c)->swapped) SWriteFormat(_c, _d); \
+  else WriteToClient(_c, sz_xvFormat, (char*)_d)
+
+#define _WriteGrabPortReply(_c,_d) \
+  if ((_c)->swapped) SWriteGrabPortReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGrabPortReply, (char*)_d)
+
+#define _WriteGetPortAttributeReply(_c,_d) \
+  if ((_c)->swapped) SWriteGetPortAttributeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvGetPortAttributeReply, (char*)_d)
+
+#define _WriteQueryBestSizeReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryBestSizeReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryBestSizeReply,(char*) _d)
+
+#define _WriteQueryPortAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryPortAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryPortAttributesReply,(char*) _d)
+
+#define _WriteQueryImageAttributesReply(_c,_d) \
+  if ((_c)->swapped) SWriteQueryImageAttributesReply(_c, _d); \
+  else WriteToClient(_c, sz_xvQueryImageAttributesReply,(char*) _d)
+
+#define _WriteListImageFormatsReply(_c,_d) \
+  if ((_c)->swapped) SWriteListImageFormatsReply(_c, _d); \
+  else WriteToClient(_c, sz_xvListImageFormatsReply,(char*) _d)
+
+#define _WriteImageFormatInfo(_c,_d) \
+  if ((_c)->swapped) SWriteImageFormatInfo(_c, _d); \
+  else WriteToClient(_c, sz_xvImageFormatInfo, (char*)_d)
+
+#define _AllocatePort(_i,_p) \
+  ((_p)->id != _i) ? (* (_p)->pAdaptor->ddAllocatePort)(_i,_p,&_p) : Success
+
+/*
+** ProcXvDispatch
+**
+**
+**
+*/
+
+int
+ProcXvDispatch(ClientPtr client)
+{
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: return(ProcXvQueryExtension(client));
+    case xv_QueryAdaptors: return(ProcXvQueryAdaptors(client));
+    case xv_QueryEncodings: return(ProcXvQueryEncodings(client));
+    case xv_PutVideo:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            return(XineramaXvPutVideo(client));
+        else
+#endif
+            return(ProcXvPutVideo(client));
+    case xv_PutStill:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+            return(XineramaXvPutStill(client));
+        else
+#endif
+    	    return(ProcXvPutStill(client));
+    case xv_GetVideo: return(ProcXvGetVideo(client));
+    case xv_GetStill: return(ProcXvGetStill(client));
+    case xv_GrabPort: return(ProcXvGrabPort(client));
+    case xv_UngrabPort: return(ProcXvUngrabPort(client));
+    case xv_SelectVideoNotify: return(ProcXvSelectVideoNotify(client));
+    case xv_SelectPortNotify: return(ProcXvSelectPortNotify(client));
+    case xv_StopVideo: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvStopVideo(client));
+	else
+#endif
+	    return(ProcXvStopVideo(client));
+    case xv_SetPortAttribute: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvSetPortAttribute(client));
+	else
+#endif
+	    return(ProcXvSetPortAttribute(client));
+    case xv_GetPortAttribute: return(ProcXvGetPortAttribute(client));
+    case xv_QueryBestSize: return(ProcXvQueryBestSize(client));
+    case xv_QueryPortAttributes: return(ProcXvQueryPortAttributes(client));
+    case xv_PutImage:
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvPutImage(client));
+	else
+#endif
+	    return(ProcXvPutImage(client));
+#ifdef MITSHM
+    case xv_ShmPutImage: 
+#ifdef PANORAMIX
+        if(!noPanoramiXExtension)
+	    return(XineramaXvShmPutImage(client));
+	else
+#endif
+	    return(ProcXvShmPutImage(client));
+#endif
+    case xv_QueryImageAttributes: return(ProcXvQueryImageAttributes(client));
+    case xv_ListImageFormats: return(ProcXvListImageFormats(client));
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  return(BadImplementation);
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  return(BadRequest);
+	}
+    }
+}
+
+int
+SProcXvDispatch(ClientPtr client)
+{
+  REQUEST(xReq);
+
+  UpdateCurrentTime();
+
+  switch (stuff->data) 
+    {
+    case xv_QueryExtension: return(SProcXvQueryExtension(client));
+    case xv_QueryAdaptors: return(SProcXvQueryAdaptors(client));
+    case xv_QueryEncodings: return(SProcXvQueryEncodings(client));
+    case xv_PutVideo: return(SProcXvPutVideo(client));
+    case xv_PutStill: return(SProcXvPutStill(client));
+    case xv_GetVideo: return(SProcXvGetVideo(client));
+    case xv_GetStill: return(SProcXvGetStill(client));
+    case xv_GrabPort: return(SProcXvGrabPort(client));
+    case xv_UngrabPort: return(SProcXvUngrabPort(client));
+    case xv_SelectVideoNotify: return(SProcXvSelectVideoNotify(client));
+    case xv_SelectPortNotify: return(SProcXvSelectPortNotify(client));
+    case xv_StopVideo: return(SProcXvStopVideo(client));
+    case xv_SetPortAttribute: return(SProcXvSetPortAttribute(client));
+    case xv_GetPortAttribute: return(SProcXvGetPortAttribute(client));
+    case xv_QueryBestSize: return(SProcXvQueryBestSize(client));
+    case xv_QueryPortAttributes: return(SProcXvQueryPortAttributes(client));
+    case xv_PutImage: return(SProcXvPutImage(client));
+#ifdef MITSHM
+    case xv_ShmPutImage: return(SProcXvShmPutImage(client));
+#endif
+    case xv_QueryImageAttributes: return(SProcXvQueryImageAttributes(client));
+    case xv_ListImageFormats: return(SProcXvListImageFormats(client));
+    default:
+      if (stuff->data < xvNumRequests)
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, 
+			    BadImplementation);
+	  return(BadImplementation);
+	}
+      else
+	{
+	  SendErrorToClient(client, XvReqCode, stuff->data, 0, BadRequest);
+	  return(BadRequest);
+	}
+    }
+}
+
+static int
+ProcXvQueryExtension(ClientPtr client)
+{
+  xvQueryExtensionReply rep;
+  /* REQUEST(xvQueryExtensionReq); */
+  REQUEST_SIZE_MATCH(xvQueryExtensionReq);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.version = XvVersion;
+  rep.revision = XvRevision;
+
+  _WriteQueryExtensionReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvQueryAdaptors(ClientPtr client)
+{
+  xvFormat format;
+  xvAdaptorInfo ainfo;
+  xvQueryAdaptorsReply rep;
+  int totalSize;
+  int na;
+  XvAdaptorPtr pa;
+  int nf;
+  XvFormatPtr pf;
+  WindowPtr pWin;
+  ScreenPtr pScreen;
+  XvScreenPtr pxvs;
+
+  REQUEST(xvQueryAdaptorsReq);
+  REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);
+
+  if(!(pWin = (WindowPtr)LookupWindow(stuff->window, client) ))
+    {
+      client->errorValue = stuff->window;
+      return (BadWindow);
+    }
+
+  pScreen = pWin->drawable.pScreen;
+  pxvs = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+  if (!pxvs)
+    {
+      rep.type = X_Reply;
+      rep.sequenceNumber = client->sequence;
+      rep.num_adaptors = 0;
+      rep.length = 0;
+
+      _WriteQueryAdaptorsReply(client, &rep);
+
+      return Success;
+    }
+
+  (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_adaptors = pxvs->nAdaptors;
+
+  /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */
+
+  totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;
+
+  /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+      totalSize += (strlen(pa->name) + 3) & ~3;
+      totalSize += pa->nFormats * sz_xvFormat;
+      pa++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryAdaptorsReply(client, &rep);
+
+  na = pxvs->nAdaptors;
+  pa = pxvs->pAdaptors;
+  while (na--)
+    {
+
+      ainfo.base_id = pa->base_id;
+      ainfo.num_ports = pa->nPorts;
+      ainfo.type = pa->type;
+      ainfo.name_size = strlen(pa->name);
+      ainfo.num_formats = pa->nFormats;
+
+      _WriteAdaptorInfo(client, &ainfo);
+
+      WriteToClient(client, ainfo.name_size, pa->name);
+
+      nf = pa->nFormats;
+      pf = pa->pFormats;
+      while (nf--)
+	{
+	  format.depth = pf->depth;
+	  format.visual = pf->visual;
+	  _WriteFormat(client, &format);
+	  pf++;
+	}
+
+      pa++;
+
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvQueryEncodings(ClientPtr client)
+{
+  xvEncodingInfo einfo;
+  xvQueryEncodingsReply rep;
+  int totalSize;
+  XvPortPtr pPort;
+  int ne;
+  XvEncodingPtr pe;
+  int status;
+
+  REQUEST(xvQueryEncodingsReq);
+  REQUEST_SIZE_MATCH(xvQueryEncodingsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_encodings = pPort->pAdaptor->nEncodings;
+
+  /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  totalSize = ne * sz_xvEncodingInfo;
+  while (ne--)
+    {
+      totalSize += (strlen(pe->name) + 3) & ~3;
+      pe++;
+    }
+
+  rep.length = totalSize >> 2;
+
+  _WriteQueryEncodingsReply(client, &rep);
+
+  ne = pPort->pAdaptor->nEncodings;
+  pe = pPort->pAdaptor->pEncodings;
+  while (ne--) 
+    {
+      einfo.encoding = pe->id;
+      einfo.name_size = strlen(pe->name);
+      einfo.width = pe->width;
+      einfo.height = pe->height;
+      einfo.rate.numerator = pe->rate.numerator;
+      einfo.rate.denominator = pe->rate.denominator;
+      _WriteEncodingInfo(client, &einfo);
+      WriteToClient(client, einfo.name_size, pe->name);
+      pe++;
+    }
+
+  return (client->noClientException);
+
+}
+
+static int
+ProcXvPutVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutVideoReq);
+  REQUEST_SIZE_MATCH(xvPutVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvPutStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvPutStillReq);
+  REQUEST_SIZE_MATCH(xvPutStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvInputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diPutStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetVideo(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetVideoReq);
+  REQUEST_SIZE_MATCH(xvGetVideoReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvVideoMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetVideo)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+
+static int
+ProcXvGetStill(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  register GCPtr pGC;
+  int status;
+
+  REQUEST(xvGetStillReq);
+  REQUEST_SIZE_MATCH(xvGetStillReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvOutputMask) ||
+	!(pPort->pAdaptor->type & XvStillMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  return XVCALL(diGetStill)(client, pDraw, pPort, pGC,
+			    stuff->vid_x, stuff->vid_y,
+			    stuff->vid_w, stuff->vid_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h);
+
+}
+
+static int
+ProcXvSelectVideoNotify(ClientPtr client)
+{
+  register DrawablePtr pDraw;
+  REQUEST(xvSelectVideoNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);
+
+  if(!(pDraw = (DrawablePtr)LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadWindow);
+    }
+
+  return XVCALL(diSelectVideoNotify)(client, pDraw, stuff->onoff);
+
+}
+
+static int
+ProcXvSelectPortNotify(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSelectPortNotifyReq);
+  REQUEST_SIZE_MATCH(xvSelectPortNotifyReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diSelectPortNotify)(client, pPort, stuff->onoff);
+
+}
+
+static int
+ProcXvGrabPort(ClientPtr client)
+{
+  int result, status;
+  XvPortPtr pPort;
+  xvGrabPortReply rep;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  status = XVCALL(diGrabPort)(client, pPort, stuff->time, &result);
+
+  if (status != Success)
+    {
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.result = result;
+
+  _WriteGrabPortReply(client, &rep);
+
+  return Success;
+
+}
+
+static int
+ProcXvUngrabPort(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvGrabPortReq);
+  REQUEST_SIZE_MATCH(xvGrabPortReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  return XVCALL(diUngrabPort)(client, pPort, stuff->time);
+
+}
+
+
+static int
+ProcXvStopVideo(ClientPtr client)
+{
+  int status;
+  register DrawablePtr pDraw;
+  XvPortPtr pPort;
+  REQUEST(xvStopVideoReq);
+  REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if(!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client) ))
+    {
+      client->errorValue = stuff->drawable;
+      return (BadDrawable);
+    }
+
+  return XVCALL(diStopVideo)(client, pPort, pDraw);
+
+}
+
+static int
+ProcXvSetPortAttribute(ClientPtr client)
+{
+  int status;
+  XvPortPtr pPort;
+  REQUEST(xvSetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diSetPortAttribute)(client, pPort, 
+				    stuff->attribute, stuff->value);
+
+  if (status == BadMatch) 
+      client->errorValue = stuff->attribute;
+  else
+      client->errorValue = stuff->value;
+
+  return status;
+}
+
+static int
+ProcXvGetPortAttribute(ClientPtr client)
+{
+  INT32 value;
+  int status;
+  XvPortPtr pPort;
+  xvGetPortAttributeReply rep;
+  REQUEST(xvGetPortAttributeReq);
+  REQUEST_SIZE_MATCH(xvGetPortAttributeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!ValidAtom(stuff->attribute))
+    {
+      client->errorValue = stuff->attribute;
+      return(BadAtom);
+    }
+
+  status = XVCALL(diGetPortAttribute)(client, pPort, stuff->attribute, &value);
+  if (status != Success)
+    {
+      client->errorValue = stuff->attribute;
+      return status;
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+  rep.value = value;
+ 
+  _WriteGetPortAttributeReply(client, &rep);
+
+  return Success;
+}
+
+static int
+ProcXvQueryBestSize(ClientPtr client)
+{
+  int status;
+  unsigned int actual_width, actual_height;
+  XvPortPtr pPort;
+  xvQueryBestSizeReply rep;
+  REQUEST(xvQueryBestSizeReq);
+  REQUEST_SIZE_MATCH(xvQueryBestSizeReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = 0;
+
+  (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion,
+				       stuff->vid_w, stuff->vid_h, 
+				       stuff->drw_w, stuff->drw_h, 
+				       &actual_width, &actual_height);
+
+  rep.actual_width = actual_width;
+  rep.actual_height = actual_height;
+ 
+  _WriteQueryBestSizeReply(client, &rep);
+
+  return Success;
+}
+
+
+static int
+ProcXvQueryPortAttributes(ClientPtr client)
+{
+  int status, size, i;
+  XvPortPtr pPort;
+  XvAttributePtr pAtt;
+  xvQueryPortAttributesReply rep;
+  xvAttributeInfo Info;
+  REQUEST(xvQueryPortAttributesReq);
+  REQUEST_SIZE_MATCH(xvQueryPortAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_attributes = pPort->pAdaptor->nAttributes;
+  rep.text_size = 0;
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {    
+      rep.text_size += (strlen(pAtt->name) + 1 + 3) & ~3L;
+  }
+
+  rep.length = (rep.num_attributes * sz_xvAttributeInfo) + rep.text_size;
+  rep.length >>= 2;
+
+  _WriteQueryPortAttributesReply(client, &rep);
+
+  for(i = 0, pAtt = pPort->pAdaptor->pAttributes; 
+      i < rep.num_attributes; i++, pAtt++) 
+  {
+      size = strlen(pAtt->name) + 1;  /* pass the NULL */
+      Info.flags = pAtt->flags;
+      Info.min = pAtt->min_value;
+      Info.max = pAtt->max_value;
+      Info.size = (size + 3) & ~3L;
+
+      _WriteAttributeInfo(client, &Info);
+
+      WriteToClient(client, size, pAtt->name);
+  }
+
+  return Success;
+}
+
+
+
+static int 
+ProcXvPutImage(ClientPtr client)
+{
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, i, size;
+  CARD16 width, height;
+
+  REQUEST(xvPutImageReq);
+  REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  width = stuff->width;
+  height = stuff->height;
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  size += sizeof(xvPutImageReq);
+  size = (size + 3) >> 2;
+  
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+
+  if(client->req_len < size)
+     return BadLength;
+
+  return XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h,
+			    pImage, (unsigned char*)(&stuff[1]), FALSE,
+			    stuff->width, stuff->height);
+}
+
+#ifdef MITSHM
+/* redefined here since it's not in any header file */
+typedef struct _ShmDesc {
+    struct _ShmDesc *next;
+    int shmid;
+    int refcnt;
+    char *addr;
+    Bool writable;
+    unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+extern RESTYPE ShmSegType;
+extern int BadShmSegCode;
+extern int ShmCompletionCode;
+
+static int 
+ProcXvShmPutImage(ClientPtr client)
+{
+  ShmDescPtr shmdesc;
+  DrawablePtr pDraw;
+  XvPortPtr pPort;
+  XvImagePtr pImage = NULL;
+  GCPtr pGC;
+  int status, size_needed, i;
+  CARD16 width, height;
+
+  REQUEST(xvShmPutImageReq);
+  REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
+    {
+      client->errorValue = stuff->port;
+      return (status);
+    }
+
+  if (!(pPort->pAdaptor->type & XvImageMask) ||
+	!(pPort->pAdaptor->type & XvInputMask))
+    {
+      client->errorValue = stuff->port;
+      return (BadMatch);
+    }
+
+  status = XVCALL(diMatchPort)(pPort, pDraw);
+  if (status != Success)
+    {
+      return status;
+    }
+
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+  if(!pImage)
+     return BadMatch;
+
+  if(!(shmdesc = (ShmDescPtr)LookupIDByType(stuff->shmseg, ShmSegType))) 
+    {
+      client->errorValue = stuff->shmseg;
+      return BadShmSegCode;  
+    }	
+ 
+  width = stuff->width;
+  height = stuff->height;
+  size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
+			pPort, pImage, &width, &height, NULL, NULL);
+  if((size_needed + stuff->offset) > shmdesc->size)
+      return BadAccess;
+
+  if((width < stuff->width) || (height < stuff->height))
+     return BadValue;
+     
+  status = XVCALL(diPutImage)(client, pDraw, pPort, pGC, 
+			    stuff->src_x, stuff->src_y,
+			    stuff->src_w, stuff->src_h,
+			    stuff->drw_x, stuff->drw_y,
+			    stuff->drw_w, stuff->drw_h, pImage,
+			    (unsigned char *)shmdesc->addr + stuff->offset, 
+			    stuff->send_event, stuff->width, stuff->height);
+
+  if((status == Success) && stuff->send_event) {
+        xShmCompletionEvent ev;
+
+        ev.type = ShmCompletionCode;
+        ev.drawable = stuff->drawable;
+        ev.sequenceNumber = client->sequence;
+        ev.minorEvent = xv_ShmPutImage;
+        ev.majorEvent = XvReqCode;
+        ev.shmseg = stuff->shmseg;
+        ev.offset = stuff->offset;
+        WriteEventsToClient(client, 1, (xEvent *) &ev);
+  }
+
+  return status;
+}
+#endif
+
+#ifdef XvMCExtension
+#include "xvmcext.h"
+#endif
+
+static int 
+ProcXvQueryImageAttributes(ClientPtr client)
+{
+  xvQueryImageAttributesReply rep;
+  int size, num_planes, i;
+  CARD16 width, height;
+  XvImagePtr pImage = NULL;
+  XvPortPtr pPort;
+  int *offsets;
+  int *pitches;
+  REQUEST(xvQueryImageAttributesReq);
+
+  REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+  
+  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
+      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
+	  pImage = &(pPort->pAdaptor->pImages[i]);
+	  break;
+      }
+  }
+
+#ifdef XvMCExtension
+  if(!pImage)
+     pImage = XvMCFindXvImage(pPort, stuff->id);
+#endif
+
+  if(!pImage)
+     return BadMatch;
+
+  num_planes = pImage->num_planes;
+
+  if(!(offsets = xalloc(num_planes << 3)))
+	return BadAlloc;
+  pitches = offsets + num_planes;
+
+  width = stuff->width;
+  height = stuff->height;
+
+  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
+					&width, &height, offsets, pitches);
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.length = num_planes << 1;
+  rep.num_planes = num_planes;
+  rep.width = width;
+  rep.height = height;
+  rep.data_size = size;
+ 
+  _WriteQueryImageAttributesReply(client, &rep);
+  if(client->swapped)
+    SwapLongs((CARD32*)offsets, rep.length);
+  WriteToClient(client, rep.length << 2, (char*)offsets);
+
+  xfree(offsets);
+
+  return Success;
+}
+
+static int 
+ProcXvListImageFormats(ClientPtr client)
+{
+  XvPortPtr pPort;
+  XvImagePtr pImage;
+  int i;
+  xvListImageFormatsReply rep;
+  xvImageFormatInfo info;
+  REQUEST(xvListImageFormatsReq);
+
+  REQUEST_SIZE_MATCH(xvListImageFormatsReq);
+
+  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
+    {
+      client->errorValue = stuff->port;
+      return (_XvBadPort);
+    }
+
+  rep.type = X_Reply;
+  rep.sequenceNumber = client->sequence;
+  rep.num_formats = pPort->pAdaptor->nImages;
+  rep.length = rep.num_formats * sz_xvImageFormatInfo >> 2;
+
+  _WriteListImageFormatsReply(client, &rep);
+
+  pImage = pPort->pAdaptor->pImages;
+  
+  for(i = 0; i < rep.num_formats; i++, pImage++) {
+     info.id = pImage->id; 	
+     info.type = pImage->type; 	
+     info.byte_order = pImage->byte_order; 
+     memcpy(&info.guid, pImage->guid, 16);	
+     info.bpp = pImage->bits_per_pixel; 	
+     info.num_planes = pImage->num_planes; 	
+     info.depth = pImage->depth; 	
+     info.red_mask = pImage->red_mask; 	
+     info.green_mask = pImage->green_mask; 	
+     info.blue_mask = pImage->blue_mask; 	
+     info.format = pImage->format; 	
+     info.y_sample_bits = pImage->y_sample_bits; 	
+     info.u_sample_bits = pImage->u_sample_bits; 	
+     info.v_sample_bits = pImage->v_sample_bits; 	
+     info.horz_y_period = pImage->horz_y_period; 	
+     info.horz_u_period = pImage->horz_u_period; 	
+     info.horz_v_period = pImage->horz_v_period; 	
+     info.vert_y_period = pImage->vert_y_period; 	
+     info.vert_u_period = pImage->vert_u_period; 	
+     info.vert_v_period = pImage->vert_v_period; 	
+     memcpy(&info.comp_order, pImage->component_order, 32);	
+     info.scanline_order = pImage->scanline_order;
+     _WriteImageFormatInfo(client, &info);
+  }  
+
+  return Success;
+}
+
+
+
+/* Swapped Procs */
+
+static int
+SProcXvQueryExtension(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryExtensionReq);
+  swaps(&stuff->length, n);
+  return ProcXvQueryExtension(client);
+}
+
+static int
+SProcXvQueryAdaptors(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryAdaptorsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->window, n);
+  return ProcXvQueryAdaptors(client);
+}
+
+static int
+SProcXvQueryEncodings(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryEncodingsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryEncodings(client);
+}
+
+static int
+SProcXvGrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvGrabPort(client);
+}
+
+static int
+SProcXvUngrabPort(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvUngrabPortReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->time, n);
+  return ProcXvUngrabPort(client);
+}
+
+static int
+SProcXvPutVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutVideo(client);
+}
+
+static int
+SProcXvPutStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvPutStill(client);
+}
+
+static int
+SProcXvGetVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetVideo(client);
+}
+
+static int
+SProcXvGetStill(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetStillReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swaps(&stuff->vid_x, n);
+  swaps(&stuff->vid_y, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvGetStill(client);
+}
+
+static int
+SProcXvPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvPutImage(client);
+}
+
+#ifdef MITSHM
+static int
+SProcXvShmPutImage(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvShmPutImageReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  swapl(&stuff->gc, n);
+  swapl(&stuff->shmseg, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->src_x, n);
+  swaps(&stuff->src_y, n);
+  swaps(&stuff->src_w, n);
+  swaps(&stuff->src_h, n);
+  swaps(&stuff->drw_x, n);
+  swaps(&stuff->drw_y, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  swaps(&stuff->offset, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->height, n);
+  return ProcXvShmPutImage(client);
+}
+#endif
+
+
+static int
+SProcXvSelectVideoNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectVideoNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvSelectVideoNotify(client);
+}
+
+static int
+SProcXvSelectPortNotify(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSelectPortNotifyReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvSelectPortNotify(client);
+}
+
+static int
+SProcXvStopVideo(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvStopVideoReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->drawable, n);
+  return ProcXvStopVideo(client);
+}
+
+static int
+SProcXvSetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvSetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvSetPortAttribute(client);
+}
+
+static int
+SProcXvGetPortAttribute(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvGetPortAttributeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swapl(&stuff->attribute, n);
+  return ProcXvGetPortAttribute(client);
+}
+
+static int
+SProcXvQueryBestSize(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryBestSizeReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  swaps(&stuff->vid_w, n);
+  swaps(&stuff->vid_h, n);
+  swaps(&stuff->drw_w, n);
+  swaps(&stuff->drw_h, n);
+  return ProcXvQueryBestSize(client);
+}
+
+static int
+SProcXvQueryPortAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryPortAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvQueryPortAttributes(client);
+}
+
+static int
+SProcXvQueryImageAttributes(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvQueryImageAttributesReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->id, n);
+  swaps(&stuff->width, n);
+  swaps(&stuff->width, n);
+  return ProcXvQueryImageAttributes(client);
+}
+
+static int
+SProcXvListImageFormats(ClientPtr client)
+{
+  register char n;
+  REQUEST(xvListImageFormatsReq);
+  swaps(&stuff->length, n);
+  swapl(&stuff->port, n);
+  return ProcXvListImageFormats(client);
+}
+
+
+static int
+SWriteQueryExtensionReply(
+   ClientPtr client,
+   xvQueryExtensionReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->version, n);
+  swaps(&rep->revision, n);
+  
+  (void)WriteToClient(client, sz_xvQueryExtensionReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryAdaptorsReply(
+   ClientPtr client,
+   xvQueryAdaptorsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_adaptors, n);
+  
+  (void)WriteToClient(client, sz_xvQueryAdaptorsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryEncodingsReply(
+   ClientPtr client,
+   xvQueryEncodingsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->num_encodings, n);
+  
+  (void)WriteToClient(client, sz_xvQueryEncodingsReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteAdaptorInfo(
+   ClientPtr client,
+   xvAdaptorInfo *pAdaptor
+){
+  register char n;
+
+  swapl(&pAdaptor->base_id, n);
+  swaps(&pAdaptor->name_size, n);
+  swaps(&pAdaptor->num_ports, n);
+  swaps(&pAdaptor->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvAdaptorInfo, (char *)pAdaptor);
+
+  return Success;
+}
+
+static int
+SWriteEncodingInfo(
+   ClientPtr client,
+   xvEncodingInfo *pEncoding
+){
+  register char n;
+  
+  swapl(&pEncoding->encoding, n);
+  swaps(&pEncoding->name_size, n);
+  swaps(&pEncoding->width, n);
+  swaps(&pEncoding->height, n);
+  swapl(&pEncoding->rate.numerator, n);
+  swapl(&pEncoding->rate.denominator, n);
+  (void)WriteToClient(client, sz_xvEncodingInfo, (char *)pEncoding);
+
+  return Success;
+}
+
+static int
+SWriteFormat(
+   ClientPtr client,
+   xvFormat *pFormat
+){
+  register char n;
+
+  swapl(&pFormat->visual, n);
+  (void)WriteToClient(client, sz_xvFormat, (char *)pFormat);
+
+  return Success;
+}
+
+static int
+SWriteAttributeInfo(
+   ClientPtr client,
+   xvAttributeInfo *pAtt
+){
+  register char n;
+
+  swapl(&pAtt->flags, n);
+  swapl(&pAtt->size, n);
+  swapl(&pAtt->min, n);
+  swapl(&pAtt->max, n);
+  (void)WriteToClient(client, sz_xvAttributeInfo, (char *)pAtt);
+
+  return Success;
+}
+
+static int
+SWriteImageFormatInfo(
+   ClientPtr client,
+   xvImageFormatInfo *pImage
+){
+  register char n;
+
+  swapl(&pImage->id, n);
+  swapl(&pImage->red_mask, n);
+  swapl(&pImage->green_mask, n);
+  swapl(&pImage->blue_mask, n);
+  swapl(&pImage->y_sample_bits, n);
+  swapl(&pImage->u_sample_bits, n);
+  swapl(&pImage->v_sample_bits, n);
+  swapl(&pImage->horz_y_period, n);
+  swapl(&pImage->horz_u_period, n);
+  swapl(&pImage->horz_v_period, n);
+  swapl(&pImage->vert_y_period, n);
+  swapl(&pImage->vert_u_period, n);
+  swapl(&pImage->vert_v_period, n);
+
+  (void)WriteToClient(client, sz_xvImageFormatInfo, (char *)pImage);
+
+  return Success;
+}
+
+
+
+static int
+SWriteGrabPortReply(
+   ClientPtr client,
+   xvGrabPortReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+
+  (void)WriteToClient(client, sz_xvGrabPortReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteGetPortAttributeReply(
+   ClientPtr client,
+   xvGetPortAttributeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->value, n);
+
+  (void)WriteToClient(client, sz_xvGetPortAttributeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryBestSizeReply(
+   ClientPtr client,
+   xvQueryBestSizeReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swaps(&rep->actual_width, n);
+  swaps(&rep->actual_height, n);
+
+  (void)WriteToClient(client, sz_xvQueryBestSizeReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryPortAttributesReply(
+   ClientPtr client,
+   xvQueryPortAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_attributes, n);
+  swapl(&rep->text_size, n);
+
+  (void)WriteToClient(client, sz_xvQueryPortAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+static int
+SWriteQueryImageAttributesReply(
+   ClientPtr client,
+   xvQueryImageAttributesReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_planes, n);
+  swapl(&rep->data_size, n);
+  swaps(&rep->width, n);
+  swaps(&rep->height, n);
+
+  (void)WriteToClient(client, sz_xvQueryImageAttributesReply, (char *)&rep);
+
+  return Success;
+}
+
+
+static int
+SWriteListImageFormatsReply(
+   ClientPtr client,
+   xvListImageFormatsReply *rep
+){
+  register char n;
+
+  swaps(&rep->sequenceNumber, n);
+  swapl(&rep->length, n);
+  swapl(&rep->num_formats, n);
+
+  (void)WriteToClient(client, sz_xvListImageFormatsReply, (char *)&rep);
+
+  return Success;
+}
+
+
+#ifdef PANORAMIX
+
+
+
+
+static int
+XineramaXvStopVideo(ClientPtr client)
+{
+   int result = Success, i;
+   PanoramiXRes *draw, *port;
+   REQUEST(xvStopVideoReq);
+   REQUEST_SIZE_MATCH(xvStopVideoReq);
+
+   if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+   if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+   FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   result = ProcXvStopVideo(client);
+     	}
+   }
+
+   return result;
+}
+
+static int
+XineramaXvSetPortAttribute(ClientPtr client)
+{
+    REQUEST(xvSetPortAttributeReq);
+    PanoramiXRes *port;
+    int result = Success, i;
+
+    REQUEST_SIZE_MATCH(xvSetPortAttributeReq);
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->port = port->info[i].id;
+	   result = ProcXvSetPortAttribute(client);
+	}
+    }
+    return result;
+}
+
+
+#ifdef MITSHM
+static int 
+XineramaXvShmPutImage(ClientPtr client)
+{
+    REQUEST(xvShmPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool send_event = stuff->send_event;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_SIZE_MATCH(xvShmPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+	   stuff->send_event = (send_event && !i) ? 1 : 0;
+
+	   result = ProcXvShmPutImage(client);
+	}
+    }
+    return result;
+}
+#endif
+
+static int 
+XineramaXvPutImage(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;    
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+		client, stuff->port, XvXRTPort, SecurityReadAccess)))
+	return _XvBadPort;
+ 
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+	if(port->info[i].id) {
+	   stuff->drawable = draw->info[i].id;
+	   stuff->port = port->info[i].id;
+	   stuff->gc = gc->info[i].id;
+	   stuff->drw_x = x;
+	   stuff->drw_y = y;
+	   if(isRoot) {
+		stuff->drw_x -= panoramiXdataPtr[i].x;
+		stuff->drw_y -= panoramiXdataPtr[i].y;
+	   }
+
+	   result = ProcXvPutImage(client);
+	}
+    }
+    return result;
+}
+
+static int
+XineramaXvPutVideo(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutVideoReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutVideo(client);
+        }
+    }
+    return result;
+}
+
+static int
+XineramaXvPutStill(ClientPtr client)
+{
+    REQUEST(xvPutImageReq);
+    PanoramiXRes *draw, *gc, *port;
+    Bool isRoot;
+    int result = Success, i, x, y;
+
+    REQUEST_AT_LEAST_SIZE(xvPutImageReq);
+
+    if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
+                client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
+        return BadDrawable;
+
+    if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->gc, XRT_GC, SecurityReadAccess)))
+        return BadGC;
+
+    if(!(port = (PanoramiXRes *)SecurityLookupIDByType(
+                client, stuff->port, XvXRTPort, SecurityReadAccess)))
+        return _XvBadPort;
+
+    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+    x = stuff->drw_x;
+    y = stuff->drw_y;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        if(port->info[i].id) {
+           stuff->drawable = draw->info[i].id;
+           stuff->port = port->info[i].id;
+           stuff->gc = gc->info[i].id;
+           stuff->drw_x = x;
+           stuff->drw_y = y;
+           if(isRoot) {
+                stuff->drw_x -= panoramiXdataPtr[i].x;
+                stuff->drw_y -= panoramiXdataPtr[i].y;
+           }
+
+           result = ProcXvPutStill(client);
+        }
+    }
+    return result;
+}
+
+
+void XineramifyXv(void)
+{
+   ScreenPtr pScreen, screen0 = screenInfo.screens[0];
+   XvScreenPtr xvsp0 = (XvScreenPtr)screen0->devPrivates[XvScreenIndex].ptr;
+   XvAdaptorPtr refAdapt, pAdapt;
+   XvAttributePtr pAttr;
+   XvScreenPtr xvsp;
+   Bool isOverlay, hasOverlay;
+   PanoramiXRes *port;
+   XvAdaptorPtr MatchingAdaptors[MAXSCREENS];
+   int i, j, k, l;
+
+   XvXRTPort = CreateNewResourceType(XineramaDeleteResource);
+
+   if(!xvsp0) return;
+   
+   for(i = 0; i < xvsp0->nAdaptors; i++) {
+      refAdapt = xvsp0->pAdaptors + i;
+
+      bzero(MatchingAdaptors, sizeof(XvAdaptorPtr) * MAXSCREENS);
+      
+      MatchingAdaptors[0] = refAdapt;
+   
+      if(!(refAdapt->type & XvInputMask)) continue;
+      
+      isOverlay = FALSE;
+      for(j = 0; j < refAdapt->nAttributes; j++) {
+         pAttr = refAdapt->pAttributes + j;
+         if(!strcmp(pAttr->name, "XV_COLORKEY")) {
+	    isOverlay = TRUE;
+	    break;
+	 }
+      }
+   
+      for(j = 1; j < PanoramiXNumScreens; j++) {
+         pScreen = screenInfo.screens[j];
+	 xvsp = (XvScreenPtr)pScreen->devPrivates[XvScreenIndex].ptr;
+
+         /* Do not try to go on if xv is not supported on this screen */
+         if (xvsp==NULL) continue ;
+	 
+         /* if the adaptor has the same name it's a perfect match */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	   pAdapt = xvsp->pAdaptors + k;
+           if(!strcmp(refAdapt->name, pAdapt->name)) {
+	       MatchingAdaptors[j] = pAdapt;
+	       break;
+	   }
+         }
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* otherwise we only look for XvImage adaptors */
+	 if(!(refAdapt->type & XvImageMask)) continue;
+	 if(refAdapt->nImages <= 0) continue;
+	 
+	 /* prefer overlay/overlay non-overlay/non-overlay pairing */
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      hasOverlay = FALSE;
+              for(l = 0; l < pAdapt->nAttributes; l++) {
+	         if(!strcmp(pAdapt->name, "XV_COLORKEY")) {
+		   hasOverlay = TRUE;
+		   break;
+		 }
+	      }
+	      if(isOverlay && hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+              else if(!isOverlay && !hasOverlay) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	      }
+	    }
+         }
+	 
+	 if(MatchingAdaptors[j]) continue; /* found it */
+	 
+	 /* but we'll take any XvImage pairing if we can get it */
+	 	 
+	 for(k = 0; k < xvsp->nAdaptors; k++) {
+	    pAdapt = xvsp->pAdaptors + k;
+	    if((pAdapt->type & XvImageMask) && (pAdapt->nImages > 0)) {
+	      	 MatchingAdaptors[j] = pAdapt;
+		 break;
+	    }
+         }
+      }
+
+      /* now create a resource for each port */
+      for(j = 0; j < refAdapt->nPorts; j++) {
+         if(!(port = xalloc(sizeof(PanoramiXRes))))
+	    break;
+	 port->info[0].id = MatchingAdaptors[0]->base_id + j;
+	 AddResource(port->info[0].id, XvXRTPort, port);
+
+	 for(k = 1; k < PanoramiXNumScreens; k++) {
+	    if(MatchingAdaptors[k] && (MatchingAdaptors[k]->nPorts > j)) 
+		port->info[k].id = MatchingAdaptors[k]->base_id + j;
+	    else
+		port->info[k].id = 0;
+	 } 
+      }
+   }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
new file mode 100644
index 000000000..d35ac4ec1
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
@@ -0,0 +1,41 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/* XPM */ 
+static char *nxagentIconData[] = {
+"16 16 5 1",
+" 	c None",
+"!	c black",
+"#	c #FF0000",
+"$	c #424242",
+"%	c #750202",
+"                ",
+"############### ",
+"#             #$",
+"# #% #######% #$",
+"# #% #%%#%%#% #$",
+"# #% #% #% #% #$",
+"# #% #% #% #% #$",
+"# #% #% #% #% #$",
+"# %% #% #% #% #$",
+"#    #% #% #% #$",
+"# #% #% #% #% #$",
+"# %% %% %% %% #$",
+"#             #$",
+"###############$",
+" $$$$$$$$$$$$$$$",
+"                "};
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
new file mode 100644
index 000000000..497fa2511
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
@@ -0,0 +1,48 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+static char *placeholderXpm[] = {
+/* columns rows colors chars-per-pixel */
+"14 16 10 1",
+"  c #000000",
+". c #0000FF",
+"X c #008400",
+"o c #00FF00",
+"O c #00FFFF",
+"+ c #FF0000",
+"@ c #FF00FF",
+"# c #848484",
+"$ c #BDBDBD",
+"% c #FFFFFF",
+/* pixels */
+"          #%%%",
+" %%%%%%%%%##%%",
+" %$$$$$$$$#%#%",
+" %$$$XX$$$#%%#",
+" %$$XoX $$    ",
+" %$$XXX $$$$% ",
+" %$$$  $$$$$% ",
+" %$$$$$$... % ",
+" %$+$$$$.O. % ",
+" %$@+$$$... % ",
+" %$@@+$$   $% ",
+" %$@@@+$$$$$% ",
+" %$    +$$$$% ",
+" %$$$$$$$$$$% ",
+" %%%%%%%%%%%% ",
+"              "
+};
diff --git a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
new file mode 100644
index 000000000..81c479233
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
@@ -0,0 +1,402 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/*
+ * (c) Copyright 1996 by Sebastien Marineau
+ *			<marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a 
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation 
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+ * and/or sell copies of the Software, and to permit persons to whom the 
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * 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 
+ * HOLGER VEIT  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.
+ * 
+ * Except as contained in this notice, the name of Sebastien Marineau shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Sebastien Marineau.
+ *
+ */
+
+/* This below implements select() for calls in nxagent. It has been         */
+/* somewhat optimized for improved performance, but assumes a few */
+/* things so it cannot be used as a general select.                             */
+
+#define I_NEED_OS2_H
+#include "Xpoll.h"
+#include <stdio.h>
+#include <sys/select.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSNPIPES
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#undef BOOL
+#undef BYTE
+#include <os2.h>
+
+HEV hPipeSem;
+HMODULE hmod_so32dll;
+static int (*os2_tcp_select)(int*,int,int,int,long);
+ULONG os2_get_sys_millis();
+extern int _files[];
+
+#define MAX_TCP 256
+/* These lifted from sys/emx.h. Change if that changes there! */
+#define F_SOCKET 0x10000000
+#define F_PIPE 0x20000000
+
+struct select_data
+{
+   fd_set read_copy;
+   fd_set write_copy;
+   BOOL have_read;
+   BOOL have_write;
+   int tcp_select_mask[MAX_TCP];
+   int tcp_emx_handles[MAX_TCP];
+   int tcp_select_copy[MAX_TCP];
+   int socket_nread;
+   int socket_nwrite;
+   int socket_ntotal;
+   int pipe_ntotal;
+   int pipe_have_write;
+   int max_fds;
+};
+
+int os2PseudoSelect(int nfds, fd_set *readfds, fd_set *writefds,
+        fd_set *exceptfds, struct timeval *timeout)
+{
+static BOOL FirstTime=TRUE;
+static haveTCPIP=TRUE;
+ULONG timeout_ms;
+ULONG postCount, start_millis,now_millis;
+char faildata[16];
+struct select_data sd;
+BOOL any_ready;
+int np,ns, i,ready_handles,n;
+APIRET rc;
+
+sd.have_read=FALSE; sd.have_write=FALSE; 
+sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0;
+sd.max_fds=31; ready_handles=0; any_ready=FALSE;
+sd.pipe_ntotal=0; sd.pipe_have_write=FALSE;
+
+if(FirstTime){
+   /* First load the so32dll.dll module and get a pointer to the SELECT function */
+
+   if((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0){
+        fprintf(stderr, "Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata);
+        haveTCPIP=FALSE;
+        }
+   if((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0){
+        fprintf(stderr, "Could not query address of SELECT, rc = %d.\n",rc);
+        haveTCPIP=FALSE;
+        }
+   /* Call these a first time to set the semaphore */
+    /* rc = DosCreateEventSem(NULL, &hPipeSem, DC_SEM_SHARED, FALSE);
+    if(rc) { 
+             fprintf(stderr, "Could not create event semaphore, rc=%d\n",rc);
+             return(-1);
+             }
+    rc = DosResetEventSem(hPipeSem, &postCount); */ /* Done in xtrans code for servers*/
+
+fprintf(stderr, "Client select() done first-time stuff, sem handle %d.\n",hPipeSem);
+
+   FirstTime = FALSE;
+}
+
+/* Set up the time delay structs */
+
+    if(timeout!=NULL) {
+	timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000;
+	}
+    else { timeout_ms=1000000; }  /* This should be large enough... */
+    if(timeout_ms>0) start_millis=os2_get_sys_millis();
+
+/* Copy the masks */
+    {FD_ZERO(&sd.read_copy);}
+    {FD_ZERO(&sd.write_copy);}
+    if(readfds!=NULL){ XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE;}
+    if(writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy);sd.have_write=TRUE;}
+
+/* And zero the original masks */
+    if(sd.have_read){ FD_ZERO(readfds);}
+    if(sd.have_write) {FD_ZERO(writefds);}
+    if(exceptfds != NULL) {FD_ZERO(exceptfds);}
+
+/* Now we parse the fd_sets passed to select and separate pipe/sockets */
+        n = os2_parse_select(&sd,nfds);
+        if(n == -1) {
+           errno = EBADF;
+           return (-1);
+           }
+
+/* Now we have three cases: either we have sockets, pipes, or both */
+/* We handle all three cases differently to optimize things */
+
+/* Case 1: only pipes! */
+        if((sd.pipe_ntotal >0) && (!sd.socket_ntotal)){
+            np = os2_check_pipes(&sd,readfds,writefds);
+            if(np > 0){
+               return (np);
+               }
+            else if (np == -1) { return(-1); }
+            while(!any_ready){
+                 rc = DosWaitEventSem(hPipeSem, timeout_ms);
+                 /* if(rc) fprintf(stderr,"Sem-wait timeout, rc = %d\n",rc); */
+                 if(rc == 640)  {
+                     return(0);
+                     }
+                 if((rc != 0) && (rc != 95)) {errno= EBADF; return(-1);}
+                 np = os2_check_pipes(&sd,readfds,writefds);
+                 if (np > 0){
+                    return(np);
+                    }
+                 else if (np < 0){ return(-1); }
+                 }
+          }
+
+/* Case 2: only sockets. Just let the os/2 tcp select do the work */
+        if((sd.socket_ntotal > 0) && (!sd.pipe_ntotal)){
+                ns = os2_check_sockets(&sd, readfds, writefds, timeout_ms);
+                return (ns);
+                }
+
+/* Case 3: combination of both */
+        if((sd.socket_ntotal > 0) && (sd.pipe_ntotal)){
+           np = os2_check_pipes(&sd,readfds,writefds);
+              if(np > 0){
+                 any_ready=TRUE;
+                 ready_handles += np;
+                 }
+              else if (np == -1) { return(-1); }
+
+           ns = os2_check_sockets(&sd,readfds,writefds, 0);
+           if(ns>0){
+               ready_handles+=ns;
+               any_ready = TRUE;
+               }
+           else if (ns == -1) {return(-1);}
+
+           while (!any_ready && timeout_ms){
+
+                rc = DosWaitEventSem(hPipeSem, 10L);
+                if(rc == 0){
+                        np = os2_check_pipes(&sd,readfds,writefds);
+                        if(np > 0){
+                        ready_handles+=np;
+                        any_ready = TRUE;
+                        }
+                        else if (np == -1) { 
+                                return(-1); }
+                      }
+
+                 ns = os2_check_sockets(&sd,readfds,writefds,exceptfds, 0);
+                 if(ns>0){
+                      ready_handles+=ns;
+                      any_ready = TRUE;
+                     }
+                 else if (ns == -1) {return(-1);}
+
+                  if (i%8 == 0) { 
+                    now_millis = os2_get_sys_millis();
+                    if((now_millis-start_millis) > timeout_ms) timeout_ms = 0;
+                    }
+                   i++;
+                  }
+        }
+
+return(ready_handles);
+}
+
+
+ULONG os2_get_sys_millis()
+{
+   APIRET rc;
+   ULONG milli;
+
+   rc = DosQuerySysInfo(14, 14, &milli, sizeof(milli));
+   if(rc) {
+        fprintf(stderr,"Bad return code querying the millisecond counter! rc=%d\n",rc);
+        return(0);
+        }
+   return(milli);
+}
+
+int os2_parse_select(sd,nfds)
+struct select_data *sd;
+int nfds;
+{
+   int i;
+   APIRET rc;
+/* First we determine up to which descriptor we need to check.              */
+/* No need to check up to 256 if we don't have to (and usually we dont...)*/
+/* Note: stuff here is hardcoded for fd_sets which are int[8] as in EMX!    */
+
+  if(nfds > sd->max_fds){
+     for(i=0;i<((FD_SETSIZE+31)/32);i++){
+        if(sd->read_copy.fds_bits[i] ||
+            sd->write_copy.fds_bits[i])
+                        sd->max_fds=(i*32) +32;
+        }
+     }
+   else { sd->max_fds = nfds; }
+/* Check if result is greater than specified in select() call */
+  if(sd->max_fds > nfds) sd->max_fds = nfds;
+
+  if (sd->have_read)
+    {
+      for (i = 0; i < sd->max_fds; ++i) {
+        if (FD_ISSET (i, &sd->read_copy)){
+         if(_files[i] & F_SOCKET)
+           {
+            sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+            sd->tcp_emx_handles[sd->socket_ntotal]=i;
+            sd->socket_ntotal++; sd->socket_nread++;
+           }
+         else if (_files[i] & F_PIPE)
+          {
+            sd -> pipe_ntotal++;
+            /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i);
+            if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */
+          }
+        }
+      }
+    }
+
+  if (sd->have_write)
+    {
+      for (i = 0; i < sd->max_fds; ++i) {
+        if (FD_ISSET (i, &sd->write_copy)){
+         if(_files[i] & F_SOCKET)
+         {
+            sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+            sd->tcp_emx_handles[sd->socket_ntotal]=i;
+            sd->socket_ntotal++; sd->socket_nwrite++;
+         }
+         else if (_files[i] & F_PIPE)
+          {
+            sd -> pipe_ntotal++;
+            /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i);
+            if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */
+            sd -> pipe_have_write=TRUE;
+          }
+        }
+      }
+    }
+
+
+return(sd->socket_ntotal);
+}
+
+
+int os2_check_sockets(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+   int e,i;
+   int j,n;
+        memcpy(sd->tcp_select_copy,sd->tcp_select_mask,
+                sd->socket_ntotal*sizeof(int));
+ 
+        e = os2_tcp_select(sd->tcp_select_copy,sd->socket_nread,
+                sd->socket_nwrite, 0, 0);
+
+        if(e == 0) return(e);
+/* We have something ready? */
+        if(e>0){
+            j = 0; n = 0;
+            for (i = 0; i < sd->socket_nread; ++i, ++j)
+                 if (sd->tcp_select_copy[j] != -1)
+                    {
+                    FD_SET (sd->tcp_emx_handles[j], readfds);
+                    n ++;
+                    }
+             for (i = 0; i < sd->socket_nwrite; ++i, ++j)
+                  if (sd->tcp_select_copy[j] != -1)
+                     {
+                     FD_SET (sd->tcp_emx_handles[j], writefds);
+                     n ++;
+                     }
+               errno = 0;
+               
+               return n;
+              }
+        if(e<0){
+           /*Error -- TODO. EBADF is a good choice for now. */
+           fprintf(stderr,"Error in server select! e=%d\n",e);
+           errno = EBADF;
+           return (-1);
+           }
+ }
+
+/* Check to see if anything is ready on pipes */
+
+int os2_check_pipes(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+int i,e;
+ULONG ulPostCount;
+PIPESEMSTATE pipeSemState[128];
+APIRET rc;
+        e = 0;
+        rc = DosResetEventSem(hPipeSem,&ulPostCount);
+        rc = DosQueryNPipeSemState((HSEM) hPipeSem, (PPIPESEMSTATE)&pipeSemState, 
+                sizeof(pipeSemState));
+        if(rc) fprintf(stderr,"SELECT: rc from QueryNPipeSem: %d\n",rc);
+        i=0;
+        while (pipeSemState[i].fStatus != 0) {
+           /*fprintf(stderr,"SELECT: sem entry, stat=%d, flag=%d, key=%d,avail=%d\n",
+                pipeSemState[i].fStatus,pipeSemState[i].fFlag,pipeSemState[i].usKey,
+                pipeSemState[i].usAvail);  */
+           if((pipeSemState[i].fStatus == 1) &&
+                    (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy))){
+                FD_SET(pipeSemState[i].usKey,readfds);
+                e++;
+                }
+           else if((pipeSemState[i].fStatus == 2)  &&
+                    (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy))){
+                FD_SET(pipeSemState[i].usKey,writefds);
+                e++;
+                }
+            else if( (pipeSemState[i].fStatus == 3) &&
+                ( (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy)) ||
+                  (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy)) )){
+                errno = EBADF;
+                /* fprintf(stderr,"Pipe has closed down, fd=%d\n",pipeSemState[i].usKey); */
+                return (-1);
+                }
+            i++;
+            } /* endwhile */
+        /*fprintf(stderr,"Done listing pipe sem entries, total %d entries, total ready entries %d\n"i,e);*/
+errno = 0;
+return(e);
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/screensaver b/nx-X11/programs/Xserver/hw/nxagent/screensaver
new file mode 100644
index 000000000..b9408a2b7
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/screensaver
@@ -0,0 +1,703 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2003 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+#define screensaver_width 256
+#define screensaver_height 256
+static unsigned char screensaver_bits[] = {
+   0xa8, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x40, 0x55,
+   0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x50,
+   0x55, 0x05, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00,
+   0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0xa0,
+   0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x15, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+   0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0xaa,
+   0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0xa0,
+   0xaa, 0x0a, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x50,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xaa, 0x2a, 0x80, 0x02, 0x80, 0xaa, 0xaa, 0x82, 0x0a, 0xa8, 0x28, 0x80,
+   0x8a, 0x80, 0x2a, 0x80, 0x80, 0x8a, 0xa2, 0x82, 0x0a, 0xaa, 0x0a, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x2a, 0x02, 0x80, 0x82, 0x41, 0x40, 0x00, 0x50,
+   0x55, 0x41, 0x00, 0x00, 0x04, 0x00, 0x54, 0x40, 0x10, 0x00, 0x40, 0x00,
+   0x51, 0x55, 0x00, 0x15, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x41, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x8a, 0x02, 0x00, 0x02,
+   0x00, 0x20, 0xa2, 0x00, 0x80, 0x00, 0x08, 0x00, 0xaa, 0x2a, 0x00, 0x2a,
+   0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80,
+   0x01, 0x00, 0x01, 0x50, 0x45, 0x05, 0x00, 0x01, 0x10, 0x10, 0x40, 0x11,
+   0x40, 0x00, 0x44, 0x00, 0x50, 0x15, 0x01, 0x15, 0x04, 0x00, 0x40, 0x00,
+   0x05, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x50, 0x20, 0x00, 0x00, 0xa2,
+   0xaa, 0x2a, 0x00, 0x00, 0x02, 0x00, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00,
+   0xa2, 0xaa, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x20,
+   0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x01, 0x40, 0x44, 0x15, 0x10, 0x01,
+   0x10, 0x10, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x54, 0x55, 0x41, 0x45,
+   0x04, 0x00, 0x40, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x54,
+   0x20, 0x80, 0x00, 0x82, 0xaa, 0x0a, 0x00, 0x00, 0x22, 0x00, 0x80, 0x0a,
+   0x00, 0x00, 0x82, 0x00, 0xa0, 0x8a, 0x22, 0x02, 0x00, 0x08, 0x20, 0x00,
+   0xa8, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x2a, 0x10, 0x40, 0x00, 0x01,
+   0x54, 0x45, 0x10, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00,
+   0x50, 0x45, 0x05, 0x41, 0x00, 0x04, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x15, 0x00, 0x28, 0x00, 0xaa, 0xaa, 0x0a, 0x0a, 0x00,
+   0x20, 0x08, 0x00, 0x20, 0x00, 0x00, 0x80, 0x00, 0xa8, 0xa2, 0x22, 0x2a,
+   0x00, 0x00, 0x0a, 0x00, 0xa8, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0a,
+   0x50, 0x05, 0x00, 0x01, 0x55, 0x45, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40,
+   0x01, 0x00, 0x00, 0x00, 0x40, 0x55, 0x11, 0x00, 0x00, 0x54, 0x01, 0x00,
+   0x44, 0x01, 0x00, 0x00, 0x05, 0x40, 0x00, 0x05, 0x00, 0x08, 0x00, 0x80,
+   0xaa, 0xaa, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x80, 0x00,
+   0x80, 0xaa, 0x28, 0x20, 0x00, 0x00, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00,
+   0x28, 0x00, 0x80, 0x02, 0x10, 0x10, 0x00, 0x01, 0x54, 0x45, 0x01, 0x00,
+   0x41, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x10, 0x55, 0x14, 0x00,
+   0x00, 0x04, 0x04, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x40, 0x40, 0x01,
+   0x08, 0x00, 0x80, 0x00, 0xa8, 0xa2, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00,
+   0x20, 0xa0, 0xaa, 0x00, 0x80, 0x28, 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00,
+   0x80, 0x02, 0x00, 0x00, 0x80, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x14, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+   0x00, 0x40, 0x00, 0x00, 0x08, 0x20, 0x80, 0x00, 0x08, 0x08, 0x80, 0x80,
+   0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x00,
+   0x02, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,
+   0x10, 0x10, 0x00, 0x01, 0x10, 0x45, 0x55, 0x01, 0x00, 0x00, 0x10, 0x00,
+   0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00,
+   0x20, 0xa2, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+   0x00, 0x80, 0x00, 0x02, 0x04, 0x00, 0x40, 0x00, 0x04, 0x04, 0x40, 0x40,
+   0x00, 0x01, 0x00, 0x04, 0x04, 0x00, 0x00, 0x01, 0x00, 0x51, 0x45, 0x05,
+   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x45, 0x01,
+   0x2a, 0x80, 0xaa, 0xaa, 0x82, 0xaa, 0x2a, 0xa0, 0x02, 0x02, 0x80, 0xa8,
+   0x00, 0x2a, 0xa0, 0x02, 0x80, 0xa2, 0x00, 0xa0, 0xa0, 0x0a, 0xa0, 0x00,
+   0x00, 0x00, 0x80, 0x88, 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x50, 0x41, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+   0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa0, 0xaa, 0x0a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x20, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x54, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x2a, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+   0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x55, 0x55,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x05, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+   0x15, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0xa8, 0xaa,
+   0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x80, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+   0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x2a, 0x20, 0x00, 0x00, 0x41, 0x05, 0x55, 0x54, 0x11, 0x04, 0x00, 0x14,
+   0x40, 0x10, 0x44, 0x15, 0x15, 0x00, 0x00, 0x50, 0x01, 0x00, 0x50, 0x55,
+   0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x10, 0x50, 0x40,
+   0x82, 0x08, 0x02, 0x08, 0x20, 0x08, 0x00, 0x22, 0xa0, 0x20, 0x88, 0x00,
+   0x22, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x80, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0xaa, 0x08, 0x88, 0x20, 0x44, 0x10, 0x01, 0x04,
+   0x50, 0x04, 0x00, 0x41, 0x10, 0x11, 0x44, 0x00, 0x41, 0x00, 0x00, 0x54,
+   0x41, 0x00, 0x40, 0x55, 0x15, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00,
+   0x54, 0x11, 0x04, 0x11, 0x80, 0x20, 0x02, 0x08, 0xa0, 0x08, 0x00, 0x02,
+   0x88, 0x20, 0x88, 0x00, 0x82, 0x00, 0x00, 0x2a, 0x22, 0x00, 0x80, 0xaa,
+   0x2a, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x08, 0x20,
+   0x40, 0x10, 0x01, 0x04, 0x50, 0x04, 0x00, 0x01, 0x04, 0x41, 0x44, 0x00,
+   0x41, 0x00, 0x00, 0x15, 0x05, 0x14, 0x15, 0x50, 0x10, 0x05, 0x40, 0x41,
+   0x41, 0x10, 0x45, 0x05, 0x50, 0x04, 0x04, 0x10, 0x80, 0x20, 0x02, 0x08,
+   0xa0, 0x08, 0x00, 0x02, 0x08, 0x22, 0x82, 0x00, 0x82, 0x00, 0x00, 0x0a,
+   0x2a, 0x22, 0x8a, 0x22, 0x22, 0x08, 0x80, 0x22, 0x22, 0x88, 0x88, 0x02,
+   0x28, 0x02, 0x08, 0x20, 0x40, 0x10, 0x15, 0x54, 0x10, 0x05, 0x00, 0x14,
+   0x04, 0x41, 0x44, 0x05, 0x41, 0x00, 0x00, 0x05, 0x50, 0x01, 0x41, 0x04,
+   0x05, 0x11, 0x00, 0x05, 0x44, 0x44, 0x50, 0x00, 0x10, 0x05, 0x50, 0x10,
+   0x80, 0x0a, 0x02, 0x08, 0x20, 0x0a, 0x00, 0x20, 0xa8, 0x82, 0x82, 0x00,
+   0x2a, 0x00, 0x80, 0x02, 0x22, 0x02, 0x82, 0x20, 0x20, 0x08, 0x20, 0x88,
+   0x82, 0x88, 0x8a, 0x00, 0x88, 0x0a, 0x80, 0x20, 0x40, 0x04, 0x01, 0x04,
+   0x10, 0x05, 0x00, 0x40, 0x04, 0x41, 0x41, 0x00, 0x11, 0x00, 0x40, 0x01,
+   0x41, 0x41, 0x41, 0x14, 0x15, 0x11, 0x40, 0x44, 0x04, 0x44, 0x40, 0x00,
+   0x44, 0x15, 0x00, 0x11, 0x80, 0x08, 0x02, 0x08, 0x20, 0x0a, 0x00, 0x80,
+   0x08, 0x82, 0x82, 0x00, 0x22, 0x00, 0xa0, 0x00, 0x22, 0x22, 0x82, 0x20,
+   0x22, 0x0a, 0x20, 0x28, 0x82, 0x82, 0x88, 0x00, 0x88, 0x2a, 0x00, 0x22,
+   0x44, 0x10, 0x01, 0x04, 0x10, 0x04, 0x00, 0x41, 0x04, 0x01, 0x41, 0x00,
+   0x41, 0x00, 0x50, 0x01, 0x14, 0x14, 0x01, 0x55, 0x10, 0x15, 0x40, 0x45,
+   0x05, 0x01, 0x45, 0x00, 0x04, 0x55, 0x04, 0x11, 0x82, 0x20, 0x02, 0x08,
+   0x20, 0x08, 0x00, 0x22, 0x08, 0x82, 0x80, 0x00, 0x82, 0x00, 0xa8, 0x00,
+   0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x02, 0xaa, 0x88, 0x20, 0x41, 0x10, 0x55, 0x54, 0x11, 0x04, 0x00, 0x14,
+   0x04, 0x01, 0x41, 0x15, 0x41, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40,
+   0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x51, 0x40,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x15, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+   0x00, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xa8, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00,
+   0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+   0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15,
+   0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x15, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00,
+   0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+   0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00,
+   0x05, 0x14, 0x40, 0x01, 0x41, 0x40, 0x01, 0x14, 0x10, 0x01, 0x00, 0x40,
+   0x01, 0x04, 0x14, 0x14, 0x14, 0x10, 0x04, 0x00, 0xa0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x0a, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x82, 0xa0, 0x20, 0x82,
+   0xa2, 0x20, 0x02, 0x22, 0x28, 0x02, 0x00, 0x08, 0x8a, 0x22, 0x08, 0x08,
+   0x22, 0x28, 0x0a, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x54,
+   0x01, 0x00, 0x00, 0x40, 0x41, 0x40, 0x10, 0x04, 0x11, 0x11, 0x04, 0x41,
+   0x10, 0x04, 0x00, 0x04, 0x04, 0x40, 0x10, 0x00, 0x41, 0x10, 0x11, 0x00,
+   0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xaa, 0x02, 0x00, 0x00, 0xa0,
+   0x82, 0x80, 0x08, 0x08, 0x02, 0x08, 0x88, 0x80, 0x08, 0x08, 0x00, 0x08,
+   0x08, 0x20, 0x20, 0x80, 0x80, 0x20, 0x00, 0x00, 0x10, 0x50, 0x14, 0x14,
+   0x45, 0x05, 0x40, 0x05, 0x41, 0x14, 0x15, 0x50, 0x41, 0x01, 0x04, 0x00,
+   0x01, 0x04, 0x50, 0x00, 0x11, 0x04, 0x00, 0x14, 0x00, 0x40, 0x10, 0x44,
+   0x00, 0x11, 0x00, 0x00, 0xa0, 0x88, 0x22, 0xa2, 0x88, 0x08, 0x00, 0x2a,
+   0x82, 0x22, 0x22, 0xa8, 0x80, 0x0a, 0x08, 0x00, 0x02, 0xa8, 0x8a, 0xaa,
+   0x08, 0x08, 0x00, 0xa8, 0x00, 0x2a, 0x20, 0x80, 0xaa, 0x20, 0x00, 0x00,
+   0x00, 0x05, 0x04, 0x15, 0x55, 0x04, 0x40, 0x04, 0x50, 0x54, 0x01, 0x54,
+   0x00, 0x54, 0x04, 0x00, 0x01, 0x04, 0x40, 0x00, 0x10, 0x04, 0x00, 0x40,
+   0x05, 0x41, 0x40, 0x40, 0x00, 0x10, 0x00, 0x00, 0x80, 0x08, 0x02, 0x82,
+   0x80, 0x08, 0x80, 0x20, 0x02, 0x02, 0x02, 0x2a, 0x00, 0xa0, 0x08, 0x00,
+   0x02, 0x08, 0x80, 0x00, 0x08, 0x08, 0x00, 0x00, 0x8a, 0x20, 0x20, 0x82,
+   0x00, 0x20, 0x00, 0x00, 0x10, 0x45, 0x04, 0x11, 0x51, 0x04, 0x50, 0x44,
+   0x44, 0x44, 0x01, 0x15, 0x00, 0x40, 0x05, 0x00, 0x01, 0x04, 0x40, 0x00,
+   0x10, 0x04, 0x00, 0x00, 0x54, 0x40, 0x40, 0x41, 0x00, 0x10, 0x00, 0x00,
+   0xa0, 0x28, 0x02, 0x0a, 0x8a, 0x08, 0x20, 0x0a, 0x0a, 0x28, 0x02, 0x0a,
+   0x00, 0x80, 0x08, 0x00, 0x02, 0x08, 0x80, 0x00, 0x08, 0x08, 0x00, 0x00,
+   0x88, 0x20, 0x80, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x05, 0x40, 0x00, 0x11, 0x00,
+   0x01, 0x10, 0x10, 0x01, 0x11, 0x04, 0x00, 0x04, 0x50, 0x40, 0x41, 0x01,
+   0x01, 0x11, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa,
+   0xaa, 0x00, 0x80, 0x02, 0x80, 0x80, 0x20, 0x02, 0x02, 0x20, 0x08, 0x82,
+   0x08, 0x08, 0x00, 0x08, 0x88, 0x20, 0x80, 0x00, 0x82, 0x20, 0x00, 0x00,
+   0x00, 0x40, 0x01, 0x10, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x40, 0x01,
+   0x40, 0x14, 0x40, 0x41, 0x05, 0x40, 0x01, 0x14, 0x14, 0x14, 0x00, 0x44,
+   0x01, 0x45, 0x00, 0x00, 0x14, 0x54, 0x00, 0x00, 0x00, 0x80, 0x02, 0x08,
+   0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x50,
+   0x55, 0x05, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0xa8, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01,
+   0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xa0,
+   0xaa, 0x0a, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x15, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x55, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x8a, 0x02, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0xa8, 0xa2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x01, 0x05, 0x50, 0x00, 0x50, 0x40, 0x45, 0x11, 0x00, 0x50,
+   0x40, 0x41, 0x01, 0x00, 0x14, 0x00, 0x51, 0x40, 0x40, 0x00, 0x05, 0x14,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0a,
+   0x88, 0x02, 0xaa, 0xa8, 0x80, 0x00, 0x00, 0xaa, 0xa8, 0xa2, 0x02, 0x00,
+   0xa2, 0xa0, 0x22, 0xa8, 0xa0, 0xa0, 0x8a, 0x2a, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x14, 0x04, 0x01, 0x45, 0x51,
+   0x04, 0x40, 0x00, 0x45, 0x41, 0x51, 0x01, 0x00, 0x41, 0x50, 0x54, 0x50,
+   0x50, 0x50, 0x14, 0x14, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xa2, 0xa0, 0x02, 0xa0, 0x88, 0x82,
+   0xa0, 0x88, 0x02, 0x80, 0x82, 0x28, 0x28, 0xa0, 0x20, 0x28, 0x08, 0x8a,
+   0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x45, 0x54, 0x00,
+   0x14, 0x40, 0x41, 0x50, 0x05, 0x51, 0x10, 0x41, 0x41, 0x41, 0x01, 0x00,
+   0x05, 0x14, 0x10, 0x50, 0x40, 0x10, 0x14, 0x54, 0x04, 0x00, 0x41, 0x55,
+   0x04, 0x45, 0x01, 0x04, 0x20, 0x02, 0x08, 0x00, 0x2a, 0xa0, 0x00, 0xa0,
+   0x8a, 0x20, 0xa8, 0xa2, 0xa0, 0xa0, 0x00, 0x80, 0x0a, 0x28, 0x28, 0xa0,
+   0x20, 0x28, 0x0a, 0x2a, 0x00, 0x00, 0x22, 0x0a, 0x80, 0x88, 0x02, 0x88,
+   0x04, 0x50, 0x01, 0x00, 0x54, 0x40, 0x01, 0x50, 0x15, 0x10, 0x14, 0x51,
+   0x40, 0x41, 0x01, 0x00, 0x15, 0x14, 0x14, 0x40, 0x11, 0x14, 0x05, 0x14,
+   0x00, 0x40, 0x10, 0x00, 0x15, 0x45, 0x04, 0x01, 0x00, 0x00, 0x08, 0x00,
+   0xa8, 0xa0, 0x00, 0x28, 0x8a, 0x08, 0x0a, 0x28, 0xa0, 0xa0, 0x00, 0x00,
+   0x2a, 0x0a, 0x28, 0xa0, 0x08, 0x8a, 0x02, 0x0a, 0x00, 0x80, 0x00, 0x08,
+   0x80, 0x00, 0x00, 0x82, 0x44, 0x11, 0x00, 0x00, 0x50, 0x50, 0x00, 0x10,
+   0x05, 0x40, 0x15, 0x05, 0x50, 0x50, 0x00, 0x00, 0x14, 0x14, 0x14, 0x40,
+   0x11, 0x54, 0x00, 0x05, 0x00, 0x00, 0x11, 0x00, 0x01, 0x40, 0x04, 0x44,
+   0x80, 0x20, 0x0a, 0x00, 0xa0, 0xa0, 0x00, 0x88, 0x82, 0xa8, 0x0a, 0x00,
+   0xa0, 0xa0, 0x00, 0x00, 0x28, 0x0a, 0x0a, 0xa0, 0x08, 0x0a, 0x00, 0x0a,
+   0x00, 0x00, 0x22, 0x0a, 0xa2, 0x00, 0x00, 0x88, 0x01, 0x40, 0x15, 0x00,
+   0x50, 0x51, 0x40, 0x00, 0x01, 0x51, 0x15, 0x00, 0x50, 0x50, 0x00, 0x00,
+   0x54, 0x14, 0x54, 0x40, 0x05, 0x14, 0x00, 0x05, 0x00, 0x40, 0x41, 0x15,
+   0x14, 0x45, 0x04, 0x05, 0x00, 0x00, 0x00, 0x80, 0xa0, 0xa0, 0x20, 0x88,
+   0x80, 0xaa, 0x08, 0x82, 0x28, 0x28, 0x02, 0x20, 0x28, 0x0a, 0x2a, 0xa0,
+   0x02, 0x0a, 0x88, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x41, 0x40, 0x11, 0x44, 0x00, 0x55, 0x14, 0x44,
+   0x50, 0x50, 0x01, 0x40, 0x10, 0x54, 0x15, 0x40, 0x01, 0x14, 0x04, 0x45,
+   0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x22, 0xa0, 0x0a, 0x00, 0x00, 0x0a, 0x2a, 0x20, 0x28, 0xa8, 0x00, 0xa0,
+   0x08, 0xa8, 0x08, 0xa0, 0x00, 0xa8, 0x82, 0x82, 0x02, 0x08, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x05, 0x00,
+   0x00, 0x54, 0x55, 0x10, 0x50, 0x50, 0x00, 0x00, 0x05, 0x50, 0x04, 0x40,
+   0x00, 0x50, 0x40, 0x05, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x80, 0xaa, 0x2a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a,
+   0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x55, 0x55,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01,
+   0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa8, 0xaa,
+   0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
+   0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x50, 0x55,
+   0x05, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x28,
+   0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0a, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+   0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x50, 0x04, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x80, 0xaa,
+   0x2a, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x50, 0x15,
+   0x55, 0x11, 0x55, 0x00, 0x15, 0x00, 0x54, 0x01, 0x00, 0x54, 0x01, 0x40,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x50, 0x00, 0x20, 0x82, 0x20, 0x08, 0x82, 0x00, 0x22, 0x80,
+   0x08, 0x08, 0x28, 0xa2, 0x28, 0x20, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa2,
+   0x00, 0x04, 0x41, 0x10, 0x04, 0x11, 0x00, 0x40, 0x10, 0x14, 0x10, 0x54,
+   0x54, 0x11, 0x10, 0x00, 0x01, 0x00, 0x50, 0x14, 0x15, 0x05, 0x45, 0x01,
+   0x50, 0x50, 0x44, 0x14, 0x05, 0x00, 0x04, 0x40, 0x20, 0x02, 0x22, 0x02,
+   0x22, 0x08, 0x20, 0x20, 0x00, 0x08, 0x20, 0xa8, 0x28, 0x22, 0x08, 0x80,
+   0x02, 0x00, 0x88, 0x22, 0xa2, 0x88, 0x28, 0x02, 0x88, 0x80, 0x22, 0xa2,
+   0x08, 0x00, 0x08, 0x22, 0x00, 0x04, 0x41, 0x00, 0x04, 0x00, 0x01, 0x40,
+   0x00, 0x10, 0x40, 0x04, 0x11, 0x10, 0x04, 0x10, 0x05, 0x00, 0x10, 0x04,
+   0x01, 0x55, 0x45, 0x04, 0x10, 0x50, 0x44, 0x15, 0x01, 0x00, 0x14, 0x10,
+   0x00, 0x2a, 0xa0, 0x02, 0x2a, 0x20, 0x22, 0x80, 0x02, 0x22, 0x20, 0x02,
+   0x0a, 0xa0, 0x02, 0x08, 0x0a, 0x00, 0x20, 0x02, 0x82, 0x80, 0x20, 0x02,
+   0x80, 0x88, 0x28, 0x82, 0x00, 0x00, 0xa8, 0x20, 0x00, 0x44, 0x40, 0x01,
+   0x14, 0x00, 0x04, 0x00, 0x05, 0x10, 0x40, 0x00, 0x11, 0x10, 0x05, 0x04,
+   0x14, 0x00, 0x44, 0x44, 0x01, 0x51, 0x44, 0x04, 0x10, 0x45, 0x14, 0x11,
+   0x01, 0x00, 0x50, 0x11, 0x00, 0x82, 0x20, 0x02, 0x22, 0x20, 0x28, 0x20,
+   0x08, 0x2a, 0x80, 0x02, 0x02, 0x20, 0x08, 0x00, 0x00, 0x00, 0x28, 0x28,
+   0x02, 0x8a, 0x22, 0x02, 0xa0, 0xa8, 0x08, 0x8a, 0x00, 0x00, 0x80, 0x22,
+   0x00, 0x04, 0x41, 0x10, 0x04, 0x01, 0x10, 0x00, 0x10, 0x41, 0x40, 0x01,
+   0x11, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x51, 0x20, 0x82, 0x20, 0x00,
+   0x02, 0x20, 0x28, 0x20, 0x88, 0x20, 0x80, 0x00, 0x82, 0x20, 0x28, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x22, 0x10, 0x04, 0x45, 0x10, 0x04, 0x01, 0x10, 0x40,
+   0x04, 0x40, 0x00, 0x00, 0x41, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41,
+   0x8a, 0x0a, 0xaa, 0x8a, 0xaa, 0xa8, 0x20, 0xa0, 0x82, 0xa2, 0x80, 0x80,
+   0xaa, 0xa8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+   0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54,
+   0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xa0, 0xa2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x10, 0x50,
+   0x41, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x15, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0xa0, 0x80, 0x02, 0xa8, 0x28,
+   0x0a, 0xa0, 0x02, 0xa8, 0x00, 0x8a, 0x02, 0x28, 0x00, 0x00, 0x00, 0x0a,
+   0x28, 0x80, 0x2a, 0x80, 0x22, 0x80, 0x0a, 0x00, 0xa8, 0x00, 0x28, 0x2a,
+   0x00, 0x05, 0x00, 0x50, 0x00, 0x00, 0x55, 0x51, 0x14, 0x14, 0x54, 0x54,
+   0x01, 0x54, 0x01, 0x50, 0x50, 0x05, 0x00, 0x05, 0x00, 0x50, 0x55, 0x40,
+   0x51, 0x50, 0x15, 0x00, 0x54, 0x05, 0x14, 0x55, 0x00, 0x0a, 0x00, 0xa0,
+   0x00, 0x80, 0xaa, 0x2a, 0x2a, 0x08, 0x2a, 0xa8, 0x02, 0xaa, 0x02, 0xa0,
+   0xa0, 0x02, 0x00, 0x0a, 0x00, 0xa8, 0xaa, 0x80, 0x2a, 0xa8, 0x2a, 0x80,
+   0xaa, 0x0a, 0xa8, 0xaa, 0x01, 0x05, 0x00, 0x50, 0x05, 0x40, 0x55, 0x55,
+   0x14, 0x00, 0x14, 0x50, 0x05, 0x54, 0x01, 0x40, 0x51, 0x01, 0x00, 0x55,
+   0x00, 0x54, 0x55, 0x41, 0x15, 0x54, 0x55, 0x40, 0x55, 0x15, 0x54, 0x55,
+   0x02, 0x0a, 0x00, 0xa0, 0x0a, 0xa0, 0x02, 0x2a, 0x2a, 0x00, 0x0a, 0x88,
+   0x0a, 0x2a, 0x00, 0x80, 0xaa, 0x00, 0x00, 0xaa, 0x00, 0xaa, 0xa0, 0xa2,
+   0x0a, 0x2a, 0xa8, 0xa0, 0x0a, 0x0a, 0xaa, 0xa0, 0x01, 0x14, 0x01, 0x40,
+   0x55, 0x50, 0x01, 0x14, 0x14, 0x00, 0x05, 0x04, 0x15, 0x15, 0x00, 0x00,
+   0x51, 0x00, 0x00, 0x54, 0x05, 0x14, 0x40, 0x45, 0x05, 0x15, 0x50, 0x41,
+   0x01, 0x14, 0x54, 0x40, 0x02, 0xa8, 0x00, 0x80, 0xaa, 0xa8, 0x00, 0x2a,
+   0x28, 0x88, 0x02, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+   0x0a, 0x0a, 0xa0, 0xa2, 0x82, 0x0a, 0xa0, 0xa0, 0x00, 0x28, 0x2a, 0xa0,
+   0x01, 0x50, 0x00, 0x00, 0x55, 0x50, 0x00, 0x14, 0x54, 0x54, 0x05, 0x15,
+   0x14, 0x15, 0x00, 0x00, 0x11, 0x00, 0x00, 0x50, 0x05, 0x15, 0x00, 0x40,
+   0x01, 0x05, 0x40, 0x51, 0x00, 0x14, 0x14, 0x40, 0x00, 0xa8, 0x00, 0x00,
+   0xa8, 0x28, 0x00, 0x28, 0x28, 0xa8, 0x02, 0x80, 0x0a, 0x0a, 0x00, 0x80,
+   0x08, 0x00, 0x00, 0x80, 0x8a, 0x0a, 0x00, 0xa0, 0x80, 0xaa, 0xaa, 0xa8,
+   0xaa, 0x2a, 0x0a, 0xa0, 0x01, 0x44, 0x01, 0x00, 0x50, 0x55, 0x00, 0x14,
+   0x50, 0x14, 0x01, 0x00, 0x15, 0x05, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00,
+   0x15, 0x05, 0x00, 0x50, 0x41, 0x55, 0x55, 0x51, 0x55, 0x15, 0x15, 0x40,
+   0x00, 0x80, 0x02, 0x00, 0xa0, 0x28, 0x00, 0x0a, 0x28, 0x0a, 0x02, 0x00,
+   0x8a, 0x0a, 0x00, 0xa0, 0x2a, 0x00, 0x00, 0x00, 0x8a, 0x0a, 0x00, 0xa0,
+   0x80, 0xaa, 0xaa, 0xa8, 0xaa, 0x2a, 0x0a, 0xa0, 0x01, 0x40, 0x01, 0x00,
+   0x50, 0x55, 0x00, 0x14, 0x50, 0x05, 0x00, 0x00, 0x14, 0x05, 0x00, 0x50,
+   0x50, 0x00, 0x00, 0x00, 0x15, 0x05, 0x00, 0x50, 0x40, 0x55, 0x55, 0x51,
+   0x55, 0x15, 0x05, 0x50, 0x00, 0x80, 0x02, 0x2a, 0xa8, 0x28, 0x00, 0x0a,
+   0xa8, 0x0a, 0x80, 0xaa, 0x82, 0x02, 0x00, 0x20, 0xa0, 0x00, 0xa0, 0x82,
+   0x8a, 0x0a, 0x00, 0xa0, 0x80, 0x02, 0x00, 0x28, 0x00, 0x00, 0x0a, 0xa0,
+   0x00, 0x00, 0x05, 0x14, 0x50, 0x54, 0x00, 0x15, 0x50, 0x05, 0x40, 0x55,
+   0x01, 0x05, 0x00, 0x10, 0x40, 0x01, 0x40, 0x01, 0x05, 0x15, 0x50, 0x51,
+   0x40, 0x01, 0x00, 0x50, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x0a, 0x2a,
+   0xa8, 0xa8, 0x80, 0x0a, 0xa0, 0x02, 0x80, 0x0a, 0x80, 0x02, 0x00, 0x08,
+   0x80, 0x02, 0xa0, 0x82, 0x0a, 0x2a, 0xa8, 0xa0, 0x80, 0x02, 0x2a, 0xa8,
+   0x80, 0x8a, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x54, 0x55, 0x50, 0x55, 0x05,
+   0x50, 0x01, 0x00, 0x00, 0x44, 0x05, 0x00, 0x04, 0x00, 0x05, 0x40, 0x55,
+   0x05, 0x54, 0x55, 0x50, 0x00, 0x55, 0x15, 0x50, 0x55, 0x05, 0x05, 0x50,
+   0x00, 0x00, 0x00, 0xa8, 0x2a, 0xa0, 0xaa, 0x0a, 0xa0, 0x00, 0x08, 0x00,
+   0x8a, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x80, 0xaa, 0x02, 0xaa, 0x2a, 0x28,
+   0x80, 0xaa, 0x0a, 0xa0, 0xaa, 0x82, 0x02, 0x28, 0x00, 0x00, 0x00, 0x50,
+   0x15, 0x40, 0x55, 0x05, 0x40, 0x01, 0x10, 0x00, 0x55, 0x01, 0x00, 0x05,
+   0x00, 0x00, 0x00, 0x55, 0x01, 0x54, 0x15, 0x50, 0x00, 0x55, 0x05, 0x40,
+   0x55, 0x01, 0x05, 0x50, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x0a,
+   0xa0, 0x00, 0x00, 0xa0, 0xaa, 0x02, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x2a,
+   0x00, 0xa0, 0x0a, 0x28, 0x00, 0xa8, 0x00, 0x80, 0x2a, 0x80, 0x02, 0x28,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+   0x55, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0xa0, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa,
+   0xaa, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x50, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+   0x55, 0x05, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x0a, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0xaa, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x45, 0x05, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x22, 0xa0, 0x22, 0xa8, 0x0a, 0xa8, 0x00,
+   0xa8, 0xa0, 0x28, 0x80, 0xaa, 0x22, 0x28, 0xa0, 0x02, 0x2a, 0x2a, 0xa0,
+   0x02, 0x8a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x40, 0x15, 0x50, 0x15, 0x54, 0x15, 0x54, 0x01, 0x55, 0x41, 0x55, 0x00,
+   0x55, 0x11, 0x54, 0x50, 0x05, 0x54, 0x54, 0x54, 0x05, 0x54, 0x05, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x08, 0x08,
+   0x20, 0x08, 0x02, 0x82, 0x82, 0x82, 0x82, 0x00, 0xaa, 0x08, 0x20, 0x20,
+   0x08, 0x08, 0x08, 0x0a, 0x0a, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x50, 0x10, 0x04, 0x10, 0x10, 0x00, 0x01, 0x04,
+   0x01, 0x01, 0x01, 0x01, 0x54, 0x14, 0x11, 0x00, 0x10, 0x10, 0x04, 0x04,
+   0x04, 0x10, 0x00, 0x14, 0x51, 0x10, 0x44, 0x01, 0x50, 0x44, 0x44, 0x14,
+   0xa0, 0x00, 0x02, 0x08, 0x08, 0x80, 0x00, 0x82, 0x00, 0x82, 0x80, 0x00,
+   0xa8, 0x28, 0x00, 0xa0, 0x0a, 0x20, 0x08, 0x02, 0x08, 0x08, 0x00, 0x00,
+   0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x05, 0x04, 0x00,
+   0x10, 0x00, 0x55, 0x45, 0x55, 0x41, 0x40, 0x00, 0x54, 0x54, 0x00, 0x50,
+   0x05, 0x10, 0x04, 0x55, 0x05, 0x04, 0x00, 0x44, 0x10, 0x14, 0x45, 0x04,
+   0x10, 0x54, 0x54, 0x04, 0x00, 0x0a, 0x02, 0x00, 0x08, 0x80, 0xaa, 0x82,
+   0xaa, 0x82, 0x80, 0x00, 0x2a, 0xaa, 0x00, 0x08, 0x08, 0x20, 0x02, 0xaa,
+   0x0a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+   0x10, 0x14, 0x04, 0x00, 0x04, 0x00, 0x01, 0x40, 0x00, 0x40, 0x40, 0x00,
+   0x15, 0x45, 0x15, 0x04, 0x04, 0x10, 0x01, 0x01, 0x00, 0x04, 0x00, 0x05,
+   0x15, 0x10, 0x44, 0x04, 0x14, 0x14, 0x41, 0x04, 0x08, 0x08, 0x0a, 0x08,
+   0x08, 0x80, 0x02, 0x82, 0x80, 0x20, 0x20, 0x80, 0x8a, 0x8a, 0x22, 0x02,
+   0x02, 0xa0, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x54, 0x05, 0x54, 0x15, 0x55, 0x01, 0x55, 0x01,
+   0x55, 0x51, 0x51, 0x01, 0x45, 0x05, 0x00, 0x54, 0x15, 0x40, 0x00, 0x54,
+   0x45, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xa8, 0x02, 0xa8, 0x82, 0xaa, 0x00, 0xaa, 0x00, 0x2a, 0xa8, 0xa8, 0x80,
+   0x82, 0x22, 0x20, 0xa8, 0x0a, 0x20, 0x00, 0xa8, 0x80, 0xaa, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x55, 0x55, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+   0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xa0, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x08,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+   0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0xa8, 0xaa, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x54, 0x00, 0x54, 0x55, 0x01, 0x00, 0x40, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+   0x00, 0xa8, 0xaa, 0x02, 0x00, 0x80, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x50, 0x55, 0x05,
+   0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x54, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0x0a, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x0a, 0x08,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x20, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+   0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x80, 0xaa, 0x2a,
+   0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xa8, 0x02, 0x08, 0x00, 0x10, 0x50, 0x50, 0x50, 0x40, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x50, 0x00,
+   0x50, 0x00, 0x05, 0x04, 0x01, 0x05, 0x50, 0x40, 0x54, 0x05, 0x04, 0x05,
+   0x8a, 0x20, 0x20, 0x88, 0xa0, 0x28, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+   0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x20, 0x00, 0x82, 0x82, 0x08, 0x8a,
+   0x82, 0x08, 0x88, 0xa0, 0xa8, 0x0a, 0x22, 0x28, 0x00, 0x41, 0x00, 0x04,
+   0x41, 0x44, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x55, 0x55,
+   0x00, 0x00, 0x10, 0x00, 0x01, 0x41, 0x10, 0x44, 0x44, 0x10, 0x04, 0x41,
+   0x50, 0x15, 0x11, 0x10, 0x80, 0x80, 0x00, 0x02, 0x82, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x80, 0x00,
+   0x02, 0x22, 0x20, 0x08, 0x20, 0x20, 0x02, 0x22, 0xa0, 0x2a, 0x22, 0x20,
+   0x00, 0x41, 0x10, 0x01, 0x44, 0x00, 0x00, 0x40, 0x41, 0x51, 0x04, 0x14,
+   0x15, 0x00, 0x11, 0x44, 0x50, 0x54, 0x40, 0x01, 0x05, 0x10, 0x00, 0x04,
+   0x10, 0x40, 0x01, 0x44, 0x10, 0x15, 0x51, 0x00, 0xa8, 0x80, 0x00, 0xaa,
+   0x82, 0x00, 0x00, 0x20, 0x22, 0x8a, 0xa2, 0x22, 0x22, 0x80, 0xa0, 0x88,
+   0x88, 0x88, 0x88, 0x02, 0x2a, 0x20, 0x00, 0x08, 0xa0, 0x2a, 0xaa, 0x22,
+   0x20, 0x8a, 0xa0, 0x02, 0x04, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x40,
+   0x10, 0x10, 0x41, 0x54, 0x11, 0x00, 0x11, 0x40, 0x54, 0x05, 0x04, 0x05,
+   0x50, 0x11, 0x00, 0x04, 0x10, 0x00, 0x01, 0x40, 0x10, 0x45, 0x00, 0x15,
+   0x82, 0x80, 0x08, 0x02, 0x80, 0x00, 0x00, 0x00, 0x22, 0x88, 0x02, 0x02,
+   0x22, 0x00, 0x82, 0x08, 0x02, 0x08, 0x02, 0x0a, 0x80, 0x22, 0x00, 0x08,
+   0x20, 0x00, 0x02, 0x20, 0x20, 0xa2, 0x00, 0x28, 0x01, 0x01, 0x05, 0x01,
+   0x40, 0x00, 0x00, 0x40, 0x14, 0x51, 0x41, 0x44, 0x11, 0x40, 0x04, 0x11,
+   0x04, 0x05, 0x01, 0x14, 0x00, 0x15, 0x00, 0x04, 0x10, 0x00, 0x01, 0x40,
+   0x10, 0x51, 0x01, 0x50, 0x82, 0x00, 0x02, 0x02, 0x80, 0x00, 0x00, 0x80,
+   0xa2, 0x88, 0x2a, 0x28, 0x22, 0x80, 0x02, 0x28, 0x8a, 0x88, 0x00, 0x28,
+   0x00, 0x22, 0x00, 0x08, 0x20, 0x00, 0x02, 0x20, 0xa0, 0xa8, 0x02, 0x20,
+   0x01, 0x05, 0x05, 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
+   0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x01, 0x44, 0x00, 0x04,
+   0x40, 0x40, 0x04, 0x44, 0x10, 0x51, 0x15, 0x40, 0x82, 0x00, 0x02, 0x08,
+   0x82, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa,
+   0x2a, 0x00, 0x00, 0x00, 0x02, 0x82, 0x08, 0x08, 0x80, 0x20, 0x08, 0x22,
+   0xa0, 0xa0, 0x2a, 0x20, 0x14, 0x01, 0x00, 0x50, 0x50, 0x01, 0x00, 0x00,
+   0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00,
+   0x51, 0x00, 0x05, 0x15, 0x00, 0x05, 0x50, 0x50, 0x50, 0x40, 0x15, 0x05,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x2a, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x02, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x54, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+   0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa0, 0x0a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+   0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0a, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x50, 0x55, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+   0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa,
+   0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x2a, 0x00, 0x00, 0x00,
+   0x00, 0xa0, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0xaa, 0x15, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
+   0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55,
+   0xa2, 0x00, 0x80, 0x02, 0x0a, 0xa2, 0x82, 0x02, 0x0a, 0x08, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x0a, 0xa8, 0xa0, 0x80, 0x82, 0xa0, 0x11, 0x01, 0x00, 0x04,
+   0x11, 0x50, 0x41, 0x04, 0x11, 0x10, 0x00, 0x14, 0x44, 0x40, 0x00, 0x41,
+   0x11, 0x00, 0x14, 0x00, 0x44, 0x05, 0x05, 0x04, 0x45, 0x00, 0x10, 0x44,
+   0x11, 0x11, 0x04, 0x44, 0xa2, 0x02, 0x20, 0x80, 0x20, 0x28, 0x20, 0x08,
+   0x02, 0x20, 0x80, 0x22, 0xa8, 0xa8, 0xa0, 0x82, 0x28, 0x00, 0x28, 0x80,
+   0x22, 0x08, 0x82, 0x0a, 0x22, 0x80, 0x00, 0x82, 0x20, 0x00, 0x88, 0x8a,
+   0x51, 0x05, 0x50, 0x00, 0x10, 0x11, 0x11, 0x10, 0x01, 0x50, 0x40, 0x10,
+   0x54, 0x04, 0x11, 0x04, 0x41, 0x00, 0x50, 0x40, 0x10, 0x04, 0x44, 0x10,
+   0x44, 0x40, 0x01, 0x01, 0x10, 0x10, 0x44, 0x14, 0xa2, 0x00, 0xa0, 0x00,
+   0xa8, 0x02, 0xa0, 0x0a, 0x02, 0xa0, 0xa0, 0x00, 0x0a, 0x82, 0x08, 0x82,
+   0x20, 0x00, 0xa0, 0x20, 0x20, 0x08, 0x22, 0x08, 0x02, 0x80, 0x02, 0x02,
+   0x20, 0xa8, 0x8a, 0x82, 0x51, 0x01, 0x40, 0x01, 0x55, 0x01, 0x10, 0x00,
+   0x01, 0x40, 0x41, 0x00, 0x04, 0x54, 0x50, 0x41, 0x40, 0x00, 0x40, 0x10,
+   0x10, 0x04, 0x41, 0x05, 0x01, 0x00, 0x05, 0x01, 0x10, 0x10, 0x40, 0x50,
+   0xa2, 0x08, 0x80, 0x82, 0xa0, 0x8a, 0x20, 0x00, 0x02, 0x80, 0x22, 0x00,
+   0x02, 0x0a, 0x28, 0x80, 0x20, 0x00, 0x80, 0x20, 0x08, 0x88, 0xa0, 0x00,
+   0x02, 0x00, 0x0a, 0x02, 0x20, 0x08, 0x80, 0xa0, 0x51, 0x01, 0x00, 0x44,
+   0x50, 0x11, 0x10, 0x00, 0x01, 0x00, 0x11, 0x00, 0x01, 0x01, 0x04, 0x40,
+   0x10, 0x00, 0x40, 0x11, 0x10, 0x10, 0x11, 0x00, 0x01, 0x00, 0x10, 0x01,
+   0x10, 0x10, 0x40, 0x50, 0xa2, 0x08, 0x00, 0x88, 0x80, 0x08, 0x20, 0x00,
+   0x02, 0x02, 0x22, 0x00, 0x02, 0x02, 0x08, 0x20, 0x20, 0x00, 0x80, 0x08,
+   0x08, 0x88, 0x20, 0x80, 0x00, 0x00, 0x20, 0x02, 0x20, 0x28, 0x80, 0xa0,
+   0x51, 0x11, 0x10, 0x44, 0x40, 0x50, 0x40, 0x10, 0x01, 0x00, 0x11, 0x00,
+   0x01, 0x01, 0x04, 0x40, 0x10, 0x00, 0x01, 0x11, 0x04, 0x50, 0x10, 0x00,
+   0x01, 0x40, 0x10, 0x04, 0x11, 0x50, 0x00, 0x01, 0xa2, 0x28, 0x20, 0x82,
+   0x0a, 0x20, 0xa0, 0x0a, 0x02, 0x02, 0x22, 0x88, 0x00, 0x82, 0x08, 0x22,
+   0x08, 0x80, 0x80, 0x28, 0x08, 0x28, 0x20, 0x88, 0x00, 0x80, 0x08, 0xaa,
+   0x20, 0xa0, 0x82, 0xaa, 0x41, 0x50, 0x50, 0x01, 0x55, 0x00, 0x00, 0x05,
+   0x05, 0x05, 0x51, 0x04, 0x01, 0x45, 0x14, 0x11, 0x50, 0x00, 0x41, 0x50,
+   0x04, 0x10, 0x50, 0x44, 0x00, 0x40, 0x05, 0x50, 0x50, 0x40, 0x01, 0x14,
+   0xaa, 0xaa, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa0, 0x82,
+   0x00, 0x2a, 0xa8, 0x20, 0x28, 0x80, 0x2a, 0x20, 0x08, 0x08, 0xa0, 0x82,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
+   0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x80, 0x0a, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x54, 0x55, 0x01, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0xa0,
+   0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x40, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xa0, 0xaa, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x50,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x28, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x55, 0x55, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x2a, 0x2a,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xaa, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x45,
+   0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x88, 0xa2, 0x22, 0x08, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x88, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x0a, 0x00, 0x0a, 0x08,
+   0x02, 0x22, 0xa0, 0x80, 0x08, 0x00, 0xa0, 0x00, 0x20, 0xa0, 0xa0, 0xa0,
+   0x41, 0x01, 0x51, 0x45, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01,
+   0x00, 0x00, 0x55, 0x55, 0x14, 0x00, 0x11, 0x14, 0x05, 0x45, 0x10, 0x41,
+   0x11, 0x00, 0x40, 0x01, 0x14, 0x41, 0x40, 0x10, 0x82, 0x28, 0xa2, 0xaa,
+   0x80, 0xa2, 0xa2, 0xa0, 0xa8, 0x00, 0x28, 0x28, 0x08, 0xa2, 0x02, 0xaa,
+   0xa8, 0x80, 0x20, 0x88, 0x88, 0x0a, 0x08, 0x82, 0x20, 0x00, 0x80, 0x0a,
+   0x00, 0x82, 0x00, 0x08, 0x04, 0x51, 0x51, 0x55, 0x45, 0x44, 0x11, 0x11,
+   0x11, 0x01, 0x50, 0x44, 0x04, 0x11, 0x05, 0x55, 0x41, 0x41, 0x40, 0x10,
+   0x40, 0x55, 0x04, 0x44, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, 0x01, 0x04,
+   0x88, 0xa8, 0xa8, 0x2a, 0x2a, 0x20, 0x08, 0x0a, 0x0a, 0x02, 0xa0, 0x80,
+   0x88, 0x08, 0xa2, 0xaa, 0x02, 0x22, 0x00, 0x08, 0xa0, 0x8a, 0x02, 0x88,
+   0x20, 0x00, 0x00, 0x20, 0x00, 0x82, 0x20, 0x02, 0x05, 0x55, 0x54, 0x55,
+   0x44, 0x40, 0x50, 0x51, 0x11, 0x01, 0x04, 0x51, 0x10, 0x51, 0x41, 0x55,
+   0x05, 0x44, 0x00, 0x10, 0x00, 0x50, 0x54, 0x45, 0x40, 0x00, 0x00, 0x40,
+   0x50, 0x01, 0x01, 0x54, 0x80, 0x2a, 0xaa, 0x0a, 0x28, 0x28, 0x08, 0x08,
+   0x08, 0x02, 0x88, 0x88, 0x80, 0x08, 0xa8, 0xaa, 0x0a, 0x28, 0x00, 0x08,
+   0xa0, 0x02, 0x02, 0x80, 0x20, 0x00, 0x00, 0x80, 0x08, 0x02, 0x02, 0x02,
+   0x00, 0x15, 0x55, 0x15, 0x44, 0x44, 0x10, 0x11, 0x11, 0x01, 0x04, 0x45,
+   0x50, 0x10, 0x51, 0x55, 0x15, 0x44, 0x00, 0x10, 0x00, 0x01, 0x04, 0x40,
+   0x40, 0x00, 0x00, 0x40, 0x04, 0x01, 0x11, 0x04, 0x80, 0x0a, 0xaa, 0x2a,
+   0x82, 0x22, 0xa0, 0xa0, 0x08, 0x02, 0xa8, 0xa8, 0x20, 0xa0, 0xa8, 0xaa,
+   0x0a, 0x28, 0x00, 0x08, 0x80, 0x00, 0x02, 0x80, 0x20, 0x00, 0x00, 0x80,
+   0x02, 0x02, 0x0a, 0x02, 0x00, 0x04, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x44, 0x00, 0x10,
+   0x10, 0x00, 0x04, 0x40, 0x40, 0x00, 0x00, 0x40, 0x04, 0x01, 0x04, 0x04,
+   0x08, 0x02, 0xa8, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0xaa, 0x28, 0x82, 0x00, 0x08, 0xa8, 0x80, 0x08, 0x88,
+   0x20, 0x00, 0x20, 0x20, 0x02, 0x0a, 0x0a, 0x08, 0x44, 0x00, 0x50, 0x55,
+   0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+   0x51, 0x01, 0x11, 0x10, 0x54, 0x41, 0x10, 0x44, 0x40, 0x00, 0x40, 0x10,
+   0x04, 0x01, 0x04, 0x10, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00,
+   0x00, 0xa0, 0x00, 0x08, 0x00, 0x00, 0x00, 0xaa, 0x08, 0x00, 0x0a, 0x2a,
+   0x2a, 0x0a, 0xa0, 0xa0, 0xa0, 0x00, 0x20, 0x0a, 0x28, 0x02, 0x00, 0xa0,
+   0x50, 0x01, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-- 
cgit v1.2.3


From 3e7c6697ac2631a215691c8d23a32a790db33b85 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:31 +0200
Subject: Imported nxagent-3.1.0-6.tar.gz

Summary: Imported nxagent-3.1.0-6.tar.gz
Keywords:

Imported nxagent-3.1.0-6.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |   6 +
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  31 ++++
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |  16 +++
 nx-X11/programs/Xserver/hw/nxagent/Events.c        |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |   2 +
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |   8 ++
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        | 160 ++++++++++++++++++---
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |  84 +++++++++++
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |  84 +++++++++++
 10 files changed, 379 insertions(+), 23 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 07526de56..5b336279e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -1215,6 +1215,12 @@ static void nxagentParseOptions(char *name, char *value)
 
     return;
   }
+  else if  (strcmp(name, "copysize") == 0)
+  {
+    nxagentChangeOption(CopyBufferSize, atoi(value));
+
+    return;
+  }
   else
   {
     #ifdef DEBUG
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 1a63ce5b6..e9138747a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,36 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index b581540cb..4d8f3f631 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -59,7 +59,7 @@ static int agentClipboardStatus;
 static int clientAccum;
 
 Atom serverCutProperty;
-static Atom clientCutProperty;
+Atom clientCutProperty;
 static Window serverWindow;
 
 static const int nxagentPrimarySelection = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 89cc1a846..1644d51a4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -650,6 +650,22 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
       {
         w = MIN(box.x2 - x, tileWidth);
 
+        /*
+         * FIXME: This should not occur.
+         */
+
+        if (nxagentDrawableStatus(pDrawable) == Synchronized)
+        {
+          #ifdef WARNING
+          if (pDrawable -> type == DRAWABLE_WINDOW && pSrcDrawable != pDrawable)
+            fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Trying to synchronize "
+                        "the clean drawable type [%d] at [%p] with source at [%p].\n",
+                            pDrawable -> type, (void *) pDrawable, (void *) pSrcDrawable);
+          #endif
+
+          goto nxagentSynchronizeRegionStop;
+        }
+
         if (canBreakOnTimeout(breakMask))
         {
           /*
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index e1eab6fd2..d2d9f87ea 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -55,6 +55,7 @@
 #include "Drawable.h"
 #include "Handlers.h"
 #include "Utils.h"
+#include "Error.h"
 
 #include "NX.h"
 #include "NXvars.h"
@@ -1478,7 +1479,10 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           if (nxagentExposeQueue.exposures[nxagentExposeQueue.start].serial != X.xconfigure.x)
           {
             #ifdef WARNING
-            fprintf(stderr, "nxagentDispatchEvents: Requested ConfigureNotify changes didn't take place.\n");
+            if (nxagentVerbose == 1)
+            {
+              fprintf(stderr, "nxagentDispatchEvents: Requested ConfigureNotify changes didn't take place.\n");
+            }
             #endif
           }
 
@@ -3358,7 +3362,8 @@ void nxagentSynchronizeExpose(void)
                           (nxagentExposeQueueHead.remoteRegion),
                               (nxagentExposeQueueHead.localRegion));
 
-      if (REGION_NIL(nxagentExposeQueueHead.remoteRegion) == 0)
+      if (REGION_NIL(nxagentExposeQueueHead.remoteRegion) == 0 &&
+             ((pWin -> eventMask|wOtherEventMasks(pWin)) & ExposureMask))
       {
         #ifdef TEST
         fprintf(stderr, "nxagentSynchronizeExpose: Going to call miWindowExposures"
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index 3a27e0da0..64dbe3b42 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -139,6 +139,8 @@ void nxagentInitOptions()
   nxagentOptions.ClientOs = UNDEFINED;
 
   nxagentOptions.InhibitXkb = 1;
+
+  nxagentOptions.CopyBufferSize = COPY_UNLIMITED;
 }
 
 /*
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index 493ba6f61..aa78489b1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -27,6 +27,7 @@
 #endif
 
 #define UNDEFINED -1
+#define COPY_UNLIMITED -1
 
 typedef enum _BackingStoreMode
 {
@@ -349,6 +350,13 @@ typedef struct _AgentOptions
 
   int InhibitXkb;
 
+  /*
+   * Maximum number of bytes that can be pasted from
+   * an NX session into an external application.
+   */
+
+  int CopyBufferSize;
+
 } AgentOptionsRec;
 
 typedef AgentOptionsRec *AgentOptionsPtr;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 255da3362..4cc1075af 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -46,6 +46,7 @@ is" without express or implied warranty.
 #include "../../fb/fb.h"
 #include "../../randr/randrstr.h"
 #include "inputstr.h"
+#include "mivalidate.h"
 
 #include "Agent.h"
 #include "Display.h"
@@ -1989,6 +1990,144 @@ Bool nxagentCloseScreen(int index, ScreenPtr pScreen)
   return True;
 }
 
+/*
+ * This function comes from the xfree86 Xserver.
+ */
+
+static void nxagentSetRootClip (ScreenPtr pScreen, Bool enable)
+{
+    WindowPtr   pWin = WindowTable[pScreen->myNum];
+    WindowPtr   pChild;
+    Bool        WasViewable = (Bool)(pWin->viewable);
+    Bool        anyMarked = FALSE;
+    RegionPtr   pOldClip = NULL, bsExposed;
+#ifdef DO_SAVE_UNDERS
+    Bool        dosave = FALSE;
+#endif
+    WindowPtr   pLayerWin;
+    BoxRec      box;
+
+    if (WasViewable)
+    {
+        for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+        {
+            (void) (*pScreen->MarkOverlappedWindows)(pChild,
+                                                     pChild,
+                                                     &pLayerWin);
+        }
+        (*pScreen->MarkWindow) (pWin);
+        anyMarked = TRUE;
+        if (pWin->valdata)
+        {
+            if (HasBorder (pWin))
+            {
+                RegionPtr       borderVisible;
+
+                borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+                REGION_SUBTRACT(pScreen, borderVisible,
+                                &pWin->borderClip, &pWin->winSize);
+                pWin->valdata->before.borderVisible = borderVisible;
+            }
+            pWin->valdata->before.resized = TRUE;
+        }
+    }
+
+    /*
+     * Use REGION_BREAK to avoid optimizations in ValidateTree
+     * that assume the root borderClip can't change well, normally
+     * it doesn't...)
+     */
+    if (enable)
+    {
+        box.x1 = 0;
+        box.y1 = 0;
+        box.x2 = pScreen->width;
+        box.y2 = pScreen->height;
+        REGION_INIT (pScreen, &pWin->winSize, &box, 1);
+        REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
+        if (WasViewable)
+            REGION_RESET(pScreen, &pWin->borderClip, &box);
+        pWin->drawable.width = pScreen->width;
+        pWin->drawable.height = pScreen->height;
+        REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+    }
+    else
+    {
+        REGION_EMPTY(pScreen, &pWin->borderClip);
+        REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+    }
+
+    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+    if (WasViewable)
+    {
+        if (pWin->backStorage)
+        {
+            pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+            REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+        }
+
+        if (pWin->firstChild)
+        {
+            anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+                                                           pWin->firstChild,
+                                                           (WindowPtr *)NULL);
+        }
+        else
+        {
+            (*pScreen->MarkWindow) (pWin);
+            anyMarked = TRUE;
+        }
+
+#ifdef DO_SAVE_UNDERS
+        if (DO_SAVE_UNDERS(pWin))
+        {
+            dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+        }
+#endif /* DO_SAVE_UNDERS */
+
+        if (anyMarked)
+            (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+    }
+    
+    if (pWin->backStorage &&
+        ((pWin->backingStore == Always) || WasViewable))
+    {
+        if (!WasViewable)
+            pOldClip = &pWin->clipList; /* a convenient empty region */
+        bsExposed = (*pScreen->TranslateBackingStore)
+                             (pWin, 0, 0, pOldClip,
+                              pWin->drawable.x, pWin->drawable.y);
+        if (WasViewable)
+            REGION_DESTROY(pScreen, pOldClip);
+        if (bsExposed)
+        {
+            RegionPtr   valExposed = NullRegion;
+
+            if (pWin->valdata)
+                valExposed = &pWin->valdata->after.exposed;
+            (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+            if (valExposed)
+                REGION_EMPTY(pScreen, valExposed);
+            REGION_DESTROY(pScreen, bsExposed);
+        }
+    }
+    if (WasViewable)
+    {
+        if (anyMarked)
+            (*pScreen->HandleExposures)(pWin);
+#ifdef DO_SAVE_UNDERS
+        if (dosave)
+            (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+        if (anyMarked && pScreen->PostValidateTree)
+            (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+    }
+    if (pWin->realized)
+        WindowsRestructured ();
+    FlushAllOutput ();
+}   
+
 Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
                              int mmWidth, int mmHeight)
 {
@@ -2002,7 +2141,6 @@ Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
   int oldMmWidth;
   int oldMmHeight;
 
-  WindowPtr pWin;
   RegionPtr pRootWinSize;
 
   #ifdef TEST
@@ -2180,25 +2318,7 @@ FIXME: We should try to restore the previously
 
   pRootWinSize = &WindowTable[pScreen -> myNum] -> winSize;
 
-  /*
-   * Force a fictitious resize of all the top
-   * level windows, in order to trigger the
-   * window tree validation.
-   */
-
-  if (nxagentOption(Rootless) == 0)
-  {
-    for (pWin = WindowTable[pScreen -> myNum] -> firstChild; pWin != NULL; pWin = pWin -> nextSib)
-    {
-
-      (*pWin -> drawable.pScreen -> ResizeWindow)(pWin, pWin -> drawable.x,
-                                                      pWin -> drawable.y,
-                                                          pWin -> drawable.width,
-                                                              pWin -> drawable.height,
-                                                                  pWin -> nextSib);
-
-    }
-  }
+  nxagentSetRootClip(pScreen, 1);
 
   XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[0]),
                   nxagentOption(RootX), nxagentOption(RootY));
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
index 3d08a3228..f58163488 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -89,6 +89,7 @@ SOFTWARE.
 #include "Options.h"
 #include "Rootless.h"
 #include "Client.h"
+#include "Windows.h"
 
 #if defined(LBX) || defined(LBX_COMPAT)
 #if 0 /* no header in X11 environment, not used in X11 environment */
@@ -99,6 +100,17 @@ int fWriteToClient(ClientPtr client, int len, char *buf)
 #endif
 #endif
 
+extern Atom clientCutProperty;
+
+#ifdef NXAGENT_SERVER
+typedef struct
+{
+  CARD32 state;
+  Window icon;
+}
+nxagentWMStateRec;
+#endif
+
 /*****************************************************************
  * Property Stuff
  *
@@ -343,10 +355,23 @@ ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
     int sizeInBytes;
     int totalSize;
     pointer data;
+    int copySize;
 
     sizeInBytes = format>>3;
     totalSize = len * sizeInBytes;
 
+    copySize = nxagentOption(CopyBufferSize);
+
+    if (copySize != COPY_UNLIMITED && property == clientCutProperty)
+    {
+      if (totalSize > copySize)
+      {
+        totalSize = copySize;
+        totalSize = totalSize - (totalSize % sizeInBytes);
+        len = totalSize / sizeInBytes;
+      }
+    }
+
     /* first see if property already exists */
 
     pProp = wUserProps (pWin);
@@ -545,6 +570,11 @@ NullPropertyReply(
 int
 ProcGetProperty(ClientPtr client)
 {
+    #ifdef NXAGENT_SERVER
+    nxagentWMStateRec wmState;
+    nxagentWMStateRec *wmsP = &wmState;
+    #endif
+
     PropertyPtr pProp, prevProp;
     unsigned long n, len, ind;
     WindowPtr pWin;
@@ -552,6 +582,7 @@ ProcGetProperty(ClientPtr client)
     REQUEST(xGetPropertyReq);
 
     REQUEST_SIZE_MATCH(xGetPropertyReq);
+
     if (stuff->delete)
 	UpdateCurrentTime();
     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
@@ -587,6 +618,59 @@ ProcGetProperty(ClientPtr client)
 
     reply.type = X_Reply;
     reply.sequenceNumber = client->sequence;
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * Creating a reply for WM_STATE property if it doesn't exist.
+     * This is intended to allow drag & drop work in JAva 1.6 when
+     * the agent is connected to NXWin in multiwindow mode.
+     */
+
+    if (nxagentOption(Rootless) &&
+            nxagentWindowTopLevel(pWin) &&
+                (!pProp) &&
+                    strcmp(NameForAtom(stuff->property), "WM_STATE") == 0)
+    {
+      wmState.state = 1;
+      wmState.icon = None;
+
+      if (ChangeWindowProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState, 1) == Success)
+      {
+        nxagentExportProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState);
+      }
+
+      n = 8;
+      ind = stuff->longOffset << 2;        
+
+      if (n < ind)
+      {
+        client->errorValue = stuff->longOffset;
+        return BadValue;
+      }
+
+      len = min(n - ind, 4 * stuff->longLength);
+
+      reply.bytesAfter = n - (ind + len);
+      reply.length = (len + 3) >> 2;
+
+      reply.format = 32;
+      reply.nItems = len / 4;
+      reply.propertyType = stuff->property;
+
+      WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+
+      if (len)
+      {
+        client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write;
+
+        WriteSwappedDataToClient(client, len, (char *)wmsP + ind);
+      }
+
+      return(client->noClientException);
+    }
+    #endif
+
     if (!pProp) 
 	return NullPropertyReply(client, None, 0, &reply);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
index 3d08a3228..f58163488 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -89,6 +89,7 @@ SOFTWARE.
 #include "Options.h"
 #include "Rootless.h"
 #include "Client.h"
+#include "Windows.h"
 
 #if defined(LBX) || defined(LBX_COMPAT)
 #if 0 /* no header in X11 environment, not used in X11 environment */
@@ -99,6 +100,17 @@ int fWriteToClient(ClientPtr client, int len, char *buf)
 #endif
 #endif
 
+extern Atom clientCutProperty;
+
+#ifdef NXAGENT_SERVER
+typedef struct
+{
+  CARD32 state;
+  Window icon;
+}
+nxagentWMStateRec;
+#endif
+
 /*****************************************************************
  * Property Stuff
  *
@@ -343,10 +355,23 @@ ChangeWindowProperty(WindowPtr pWin, Atom property, Atom type, int format,
     int sizeInBytes;
     int totalSize;
     pointer data;
+    int copySize;
 
     sizeInBytes = format>>3;
     totalSize = len * sizeInBytes;
 
+    copySize = nxagentOption(CopyBufferSize);
+
+    if (copySize != COPY_UNLIMITED && property == clientCutProperty)
+    {
+      if (totalSize > copySize)
+      {
+        totalSize = copySize;
+        totalSize = totalSize - (totalSize % sizeInBytes);
+        len = totalSize / sizeInBytes;
+      }
+    }
+
     /* first see if property already exists */
 
     pProp = wUserProps (pWin);
@@ -545,6 +570,11 @@ NullPropertyReply(
 int
 ProcGetProperty(ClientPtr client)
 {
+    #ifdef NXAGENT_SERVER
+    nxagentWMStateRec wmState;
+    nxagentWMStateRec *wmsP = &wmState;
+    #endif
+
     PropertyPtr pProp, prevProp;
     unsigned long n, len, ind;
     WindowPtr pWin;
@@ -552,6 +582,7 @@ ProcGetProperty(ClientPtr client)
     REQUEST(xGetPropertyReq);
 
     REQUEST_SIZE_MATCH(xGetPropertyReq);
+
     if (stuff->delete)
 	UpdateCurrentTime();
     pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
@@ -587,6 +618,59 @@ ProcGetProperty(ClientPtr client)
 
     reply.type = X_Reply;
     reply.sequenceNumber = client->sequence;
+
+    #ifdef NXAGENT_SERVER
+
+    /*
+     * Creating a reply for WM_STATE property if it doesn't exist.
+     * This is intended to allow drag & drop work in JAva 1.6 when
+     * the agent is connected to NXWin in multiwindow mode.
+     */
+
+    if (nxagentOption(Rootless) &&
+            nxagentWindowTopLevel(pWin) &&
+                (!pProp) &&
+                    strcmp(NameForAtom(stuff->property), "WM_STATE") == 0)
+    {
+      wmState.state = 1;
+      wmState.icon = None;
+
+      if (ChangeWindowProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState, 1) == Success)
+      {
+        nxagentExportProperty(pWin, stuff->property, stuff->property, 32, 0, 2, &wmState);
+      }
+
+      n = 8;
+      ind = stuff->longOffset << 2;        
+
+      if (n < ind)
+      {
+        client->errorValue = stuff->longOffset;
+        return BadValue;
+      }
+
+      len = min(n - ind, 4 * stuff->longLength);
+
+      reply.bytesAfter = n - (ind + len);
+      reply.length = (len + 3) >> 2;
+
+      reply.format = 32;
+      reply.nItems = len / 4;
+      reply.propertyType = stuff->property;
+
+      WriteReplyToClient(client, sizeof(xGenericReply), &reply);
+
+      if (len)
+      {
+        client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write;
+
+        WriteSwappedDataToClient(client, len, (char *)wmsP + ind);
+      }
+
+      return(client->noClientException);
+    }
+    #endif
+
     if (!pProp) 
 	return NullPropertyReply(client, None, 0, &reply);
 
-- 
cgit v1.2.3


From 266b5554943baffafbf1d574f567283cc9792278 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:31 +0200
Subject: Imported nxagent-3.1.0-7.tar.gz

Summary: Imported nxagent-3.1.0-7.tar.gz
Keywords:

Imported nxagent-3.1.0-7.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       | 10 +++++
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      | 16 +++++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  |  7 +++
 .../Xserver/hw/nxagent/X/NXdixfonts.c.NX.original  |  7 +++
 .../Xserver/hw/nxagent/X/NXdixfonts.c.X.original   |  7 +++
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       | 50 ++++++++++++++++++----
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       | 50 ++++++++++++++++++----
 .../Xserver/hw/nxagent/X/NXshm.c.X.original        | 50 ++++++++++++++++++----
 8 files changed, 173 insertions(+), 24 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index e9138747a..285ecb637 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,15 @@
 ChangeLog:
 
+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.
+
+- 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.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 1644d51a4..abc228e9c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -2609,8 +2609,24 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
     goto nxagentCreateDrawableBitmapEnd;
   }
 
+  /*
+   * FIXME: A better way it would be create the bitmap
+   * with the same extents of the clipRegion. This
+   * requires to save the offset with respect to the
+   * drawable origin like in the backing store.
+   */
+
   pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth);
 
+  if (pBitmap == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreateDrawableBitmap: Cannot create pixmap for the bitmap data.\n");
+    #endif
+
+    goto nxagentCreateDrawableBitmapEnd;
+  }
+
   pGC = GetScratchGC(pBitmap -> drawable.depth, pBitmap -> drawable.pScreen);
 
   ValidateGC((DrawablePtr) pBitmap, pGC);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
index 6dfff3776..b431796be 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -437,6 +437,13 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
 	err = BadFontName;
 	goto bail;
     }
+    /* check values for firstCol, lastCol, firstRow, and lastRow */
+    if (pfont->info.firstCol > pfont->info.lastCol ||
+       pfont->info.firstRow > pfont->info.lastRow ||
+       pfont->info.lastCol - pfont->info.firstCol > 255) {
+       err = AllocError;
+       goto bail;
+    }
     if (!pfont->fpe)
 	pfont->fpe = fpe;
     pfont->refcnt++;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
index 6dfff3776..b431796be 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -437,6 +437,13 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
 	err = BadFontName;
 	goto bail;
     }
+    /* check values for firstCol, lastCol, firstRow, and lastRow */
+    if (pfont->info.firstCol > pfont->info.lastCol ||
+       pfont->info.firstRow > pfont->info.lastRow ||
+       pfont->info.lastCol - pfont->info.firstCol > 255) {
+       err = AllocError;
+       goto bail;
+    }
     if (!pfont->fpe)
 	pfont->fpe = fpe;
     pfont->refcnt++;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
index 9de998417..2c5874e8d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.X.original
@@ -336,6 +336,13 @@ doOpenFont(ClientPtr client, OFclosurePtr c)
 	err = BadFontName;
 	goto bail;
     }
+    /* check values for firstCol, lastCol, firstRow, and lastRow */
+    if (pfont->info.firstCol > pfont->info.lastCol ||
+       pfont->info.firstRow > pfont->info.lastRow ||
+       pfont->info.lastCol - pfont->info.firstCol > 255) {
+       err = AllocError;
+       goto bail;
+    }
     if (!pfont->fpe)
 	pfont->fpe = fpe;
     pfont->refcnt++;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index 3aecaf229..e3e4f4b83 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -832,6 +832,8 @@ ProcPanoramiXShmCreatePixmap(
     int i, j, result;
     ShmDescPtr shmdesc;
     REQUEST(xShmCreatePixmapReq);
+    unsigned int width, height, depth;
+    unsigned long size;
     PanoramiXRes *newPix;
 
     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
@@ -841,11 +843,18 @@ ProcPanoramiXShmCreatePixmap(
     LEGAL_NEW_RESOURCE(stuff->pid, client);
     VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-    if (!stuff->width || !stuff->height)
+
+    width = stuff->width;
+    height = stuff->height;
+    depth = stuff->depth;
+    if (!width || !height || !depth)
     {
 	client->errorValue = 0;
         return BadValue;
     }
+    if (width > 32767 || height > 32767)
+        return BadAlloc;
+
     if (stuff->depth != 1)
     {
         pDepth = pDraw->pScreen->allowedDepths;
@@ -855,10 +864,18 @@ ProcPanoramiXShmCreatePixmap(
 	client->errorValue = stuff->depth;
         return BadValue;
     }
+
 CreatePmap:
-    VERIFY_SHMSIZE(shmdesc, stuff->offset,
-		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
-		   client);
+    size = PixmapBytePad(width, depth) * height;
+    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+        if (size < width * height)
+            return BadAlloc;
+        /* thankfully, offset is unsigned */
+        if (stuff->offset + size < size)
+            return BadAlloc;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
 
     if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
 	return BadAlloc;
@@ -1174,6 +1191,8 @@ ProcShmCreatePixmap(client)
     register int i;
     ShmDescPtr shmdesc;
     REQUEST(xShmCreatePixmapReq);
+    unsigned int width, height, depth;
+    unsigned long size;
 
     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
     client->errorValue = stuff->pid;
@@ -1182,11 +1201,18 @@ ProcShmCreatePixmap(client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
     VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-    if (!stuff->width || !stuff->height)
+    
+    width = stuff->width;
+    height = stuff->height;
+    depth = stuff->depth;
+    if (!width || !height || !depth)
     {
 	client->errorValue = 0;
         return BadValue;
     }
+    if (width > 32767 || height > 32767)
+	return BadAlloc;
+
     if (stuff->depth != 1)
     {
         pDepth = pDraw->pScreen->allowedDepths;
@@ -1196,10 +1222,18 @@ ProcShmCreatePixmap(client)
 	client->errorValue = stuff->depth;
         return BadValue;
     }
+
 CreatePmap:
-    VERIFY_SHMSIZE(shmdesc, stuff->offset,
-		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
-		   client);
+    size = PixmapBytePad(width, depth) * height;
+    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+	if (size < width * height)
+	    return BadAlloc;
+	/* thankfully, offset is unsigned */
+	if (stuff->offset + size < size)
+	    return BadAlloc;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
     pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
 			    pDraw->pScreen, stuff->width,
 			    stuff->height, stuff->depth,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index 3aecaf229..e3e4f4b83 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -832,6 +832,8 @@ ProcPanoramiXShmCreatePixmap(
     int i, j, result;
     ShmDescPtr shmdesc;
     REQUEST(xShmCreatePixmapReq);
+    unsigned int width, height, depth;
+    unsigned long size;
     PanoramiXRes *newPix;
 
     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
@@ -841,11 +843,18 @@ ProcPanoramiXShmCreatePixmap(
     LEGAL_NEW_RESOURCE(stuff->pid, client);
     VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-    if (!stuff->width || !stuff->height)
+
+    width = stuff->width;
+    height = stuff->height;
+    depth = stuff->depth;
+    if (!width || !height || !depth)
     {
 	client->errorValue = 0;
         return BadValue;
     }
+    if (width > 32767 || height > 32767)
+        return BadAlloc;
+
     if (stuff->depth != 1)
     {
         pDepth = pDraw->pScreen->allowedDepths;
@@ -855,10 +864,18 @@ ProcPanoramiXShmCreatePixmap(
 	client->errorValue = stuff->depth;
         return BadValue;
     }
+
 CreatePmap:
-    VERIFY_SHMSIZE(shmdesc, stuff->offset,
-		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
-		   client);
+    size = PixmapBytePad(width, depth) * height;
+    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+        if (size < width * height)
+            return BadAlloc;
+        /* thankfully, offset is unsigned */
+        if (stuff->offset + size < size)
+            return BadAlloc;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
 
     if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
 	return BadAlloc;
@@ -1174,6 +1191,8 @@ ProcShmCreatePixmap(client)
     register int i;
     ShmDescPtr shmdesc;
     REQUEST(xShmCreatePixmapReq);
+    unsigned int width, height, depth;
+    unsigned long size;
 
     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
     client->errorValue = stuff->pid;
@@ -1182,11 +1201,18 @@ ProcShmCreatePixmap(client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
     VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-    if (!stuff->width || !stuff->height)
+    
+    width = stuff->width;
+    height = stuff->height;
+    depth = stuff->depth;
+    if (!width || !height || !depth)
     {
 	client->errorValue = 0;
         return BadValue;
     }
+    if (width > 32767 || height > 32767)
+	return BadAlloc;
+
     if (stuff->depth != 1)
     {
         pDepth = pDraw->pScreen->allowedDepths;
@@ -1196,10 +1222,18 @@ ProcShmCreatePixmap(client)
 	client->errorValue = stuff->depth;
         return BadValue;
     }
+
 CreatePmap:
-    VERIFY_SHMSIZE(shmdesc, stuff->offset,
-		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
-		   client);
+    size = PixmapBytePad(width, depth) * height;
+    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+	if (size < width * height)
+	    return BadAlloc;
+	/* thankfully, offset is unsigned */
+	if (stuff->offset + size < size)
+	    return BadAlloc;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
     pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
 			    pDraw->pScreen, stuff->width,
 			    stuff->height, stuff->depth,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
index 806008c60..e2cf8cd24 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
@@ -728,6 +728,8 @@ ProcPanoramiXShmCreatePixmap(
     int i, j, result;
     ShmDescPtr shmdesc;
     REQUEST(xShmCreatePixmapReq);
+    unsigned int width, height, depth;
+    unsigned long size;
     PanoramiXRes *newPix;
 
     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
@@ -737,11 +739,18 @@ ProcPanoramiXShmCreatePixmap(
     LEGAL_NEW_RESOURCE(stuff->pid, client);
     VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-    if (!stuff->width || !stuff->height)
+
+    width = stuff->width;
+    height = stuff->height;
+    depth = stuff->depth;
+    if (!width || !height || !depth)
     {
 	client->errorValue = 0;
         return BadValue;
     }
+    if (width > 32767 || height > 32767)
+        return BadAlloc;
+
     if (stuff->depth != 1)
     {
         pDepth = pDraw->pScreen->allowedDepths;
@@ -751,10 +760,18 @@ ProcPanoramiXShmCreatePixmap(
 	client->errorValue = stuff->depth;
         return BadValue;
     }
+
 CreatePmap:
-    VERIFY_SHMSIZE(shmdesc, stuff->offset,
-		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
-		   client);
+    size = PixmapBytePad(width, depth) * height;
+    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+        if (size < width * height)
+            return BadAlloc;
+        /* thankfully, offset is unsigned */
+        if (stuff->offset + size < size)
+            return BadAlloc;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
 
     if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
 	return BadAlloc;
@@ -1052,6 +1069,8 @@ ProcShmCreatePixmap(client)
     register int i;
     ShmDescPtr shmdesc;
     REQUEST(xShmCreatePixmapReq);
+    unsigned int width, height, depth;
+    unsigned long size;
 
     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
     client->errorValue = stuff->pid;
@@ -1060,11 +1079,18 @@ ProcShmCreatePixmap(client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
     VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
-    if (!stuff->width || !stuff->height)
+    
+    width = stuff->width;
+    height = stuff->height;
+    depth = stuff->depth;
+    if (!width || !height || !depth)
     {
 	client->errorValue = 0;
         return BadValue;
     }
+    if (width > 32767 || height > 32767)
+	return BadAlloc;
+
     if (stuff->depth != 1)
     {
         pDepth = pDraw->pScreen->allowedDepths;
@@ -1074,10 +1100,18 @@ ProcShmCreatePixmap(client)
 	client->errorValue = stuff->depth;
         return BadValue;
     }
+
 CreatePmap:
-    VERIFY_SHMSIZE(shmdesc, stuff->offset,
-		   PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
-		   client);
+    size = PixmapBytePad(width, depth) * height;
+    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+	if (size < width * height)
+	    return BadAlloc;
+	/* thankfully, offset is unsigned */
+	if (stuff->offset + size < size)
+	    return BadAlloc;
+    }
+
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
     pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
 			    pDraw->pScreen, stuff->width,
 			    stuff->height, stuff->depth,
-- 
cgit v1.2.3


From 1c25e92b9ea5811d8ab9c2bfdc0dcb2e4d21bd0a Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:31 +0200
Subject: Imported nxagent-3.2.0-10.tar.gz

Summary: Imported nxagent-3.2.0-10.tar.gz
Keywords:

Imported nxagent-3.2.0-10.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |   12 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |    1 +
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |    2 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  117 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig  | 5959 ++++++++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |   64 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h     |   15 +
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |   27 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |   22 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.c        |  204 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |    1 +
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |  155 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         |   18 +
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |   15 +
 nx-X11/programs/Xserver/hw/nxagent/Image.c         |    9 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |    9 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      |    4 +-
 nx-X11/programs/Xserver/hw/nxagent/Literals.h      |    7 +
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |   22 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        |   56 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.c          |   15 +
 nx-X11/programs/Xserver/hw/nxagent/Trap.h          |   16 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |    3 +-
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |    3 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   19 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   19 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.X.original      |   14 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |   18 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |   18 +-
 .../Xserver/hw/nxagent/X/NXrender.c.X.original     |   18 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c  |   77 +
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |   77 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   13 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   13 +-
 .../Xserver/hw/nxagent/X/NXshm.c.X.original        |   13 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c    |   21 +-
 .../Xserver/hw/nxagent/X/NXwindow.c.NX.original    |   21 +-
 37 files changed, 6943 insertions(+), 154 deletions(-)
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 5b336279e..c74bc3f56 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -2080,8 +2080,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 65536;
-      tileHeight = 65536;
+      tileWidth  = 4096;
+      tileHeight = 4096;
 
       break;
     }
@@ -2091,8 +2091,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 65536;
-      tileHeight = 65536;
+      tileWidth  = 4096;
+      tileHeight = 4096;
 
       break;
     }
@@ -2103,8 +2103,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 65536;
-      tileHeight = 65536;
+      tileWidth  = 4096;
+      tileHeight = 4096;
 
       break;
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
index 1f412fd27..ac26646ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -78,6 +78,7 @@ static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
   "NXDARWIN",             /* 9  */
   "CLIPBOARD",            /* 10 */
   "TIMESTAMP",            /* 11 */
+  "UTF8_STRING",          /* 12 */
   NULL,
   NULL
 };
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
index 0dd75de43..17b2d8f57 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -22,7 +22,7 @@
 #include "../../include/window.h"
 #include "screenint.h"
 
-#define NXAGENT_NUMBER_OF_ATOMS  13
+#define NXAGENT_NUMBER_OF_ATOMS  14
 
 extern Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 285ecb637..1c10208ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,116 @@
 ChangeLog:
 
+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
@@ -7,8 +118,8 @@ nxagent-3.1.0-7
   CVE-2007-5760    CVE-2007-5958    CVE-2007-6427   CVE-2007-6428
   CVE-2007-6429    CVE-2008-0006.
 
-- Handled the case if nxagentCreateDrawableBitmap() fails to create
-  the pixmap intended to store the bitmap data.
+- Fixed TR02F02007. Handled the case if nxagentCreateDrawableBitmap()
+  fails to create the pixmap intended to store the bitmap data.
 
 nxagent-3.1.0-6
 
@@ -81,7 +192,7 @@ nxagent-3.0.0-90
 - 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 string comparison in the font replacement routine.
+- Fixed TR07E01762. Problem in comparison of font names.
 
 - Printed the new geometry in the session log when the agent screen is
   resized.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig
new file mode 100644
index 000000000..539a7b829
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig
@@ -0,0 +1,5959 @@
+ChangeLog:
+
+nxagent-3.2.0-8-MAR1
+
+- Fixed TR07F02091. Scalable fonts were not correctly listed among
+  available fonts.
+
+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/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 4d8f3f631..a575cabe5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -31,6 +31,10 @@
 #include "Rootless.h"
 #include "Clipboard.h"
 
+#include "gcstruct.h"
+#include "xfixeswire.h"
+#include <X11/extensions/Xfixes.h>
+
 /*
  * Use asyncronous get property replies.
  */
@@ -115,15 +119,24 @@ static Time   lastServerTime;
 
 static Atom serverTARGETS;
 static Atom serverTEXT;
+static Atom serverUTF8_STRING;
 static Atom clientTARGETS;
 static Atom clientTEXT;
 static Atom clientCOMPOUND_TEXT;
+static Atom clientUTF8_STRING;
 
 static char szAgentTARGETS[] = "TARGETS";
 static char szAgentTEXT[] = "TEXT";
 static char szAgentCOMPOUND_TEXT[] = "COMPOUND_TEXT";
+static char szAgentUTF8_STRING[] = "UTF8_STRING";
 static char szAgentNX_CUT_BUFFER_CLIENT[] = "NX_CUT_BUFFER_CLIENT";
 
+/*
+ * Save the values queried from X server.
+ */
+
+XFixesAgentInfoRec nxagentXFixesInfo = { -1, -1, -1, 0 };
+
 extern Display *nxagentDisplay;
 
 Bool nxagentValidServerTargets(Atom target);
@@ -299,7 +312,7 @@ FIXME: Do we need this?
       result = XChangeProperty (nxagentDisplay,
                                 X->xselectionrequest.requestor,
                                 X->xselectionrequest.property,
-                                X->xselectionrequest.target,
+                                XInternAtom(nxagentDisplay, "ATOM", 0),
                                 sizeof(Atom)*8,
                                 PropModeReplace,
                                 (unsigned char*)&xa_STRING,
@@ -1178,19 +1191,20 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
 
   if (target == clientTARGETS)
   {
-    Atom xa_STRING[3];
+    Atom xa_STRING[4];
     xEvent x;
 
     xa_STRING[0] = XA_STRING;
     xa_STRING[1] = clientTEXT;
     xa_STRING[2] = clientCOMPOUND_TEXT;
+    xa_STRING[3] = clientUTF8_STRING;
 
     ChangeWindowProperty(pWin,
                          property,
-                         target,
+                         MakeAtom("ATOM", 4, 1),
                          sizeof(Atom)*8,
                          PropModeReplace,
-                         3,
+                         4,
                          &xa_STRING, 1);
 
     x.u.u.type = SelectionNotify;
@@ -1264,7 +1278,10 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
     }
   }
 
-  if ((target == clientTEXT) || (target == XA_STRING) || (target == clientCOMPOUND_TEXT))
+  if ((target == clientTEXT) ||
+          (target == XA_STRING) ||
+              (target == clientCOMPOUND_TEXT) ||
+                  (target == clientUTF8_STRING))
   {
     lastClientWindowPtr = pWin;
     lastClientStage = SelectionStageNone;
@@ -1283,8 +1300,16 @@ int nxagentConvertSelection(ClientPtr client, WindowPtr pWin, Atom selection,
       selection = lastSelectionOwner[nxagentClipboardSelection].selection;
     }
 
-    XConvertSelection(nxagentDisplay, selection, XA_STRING, serverCutProperty,
-                         serverWindow, CurrentTime);
+    if (target == clientUTF8_STRING)
+    {
+      XConvertSelection(nxagentDisplay, selection, serverUTF8_STRING, serverCutProperty,
+                           serverWindow, CurrentTime);
+    }
+    else
+    {
+      XConvertSelection(nxagentDisplay, selection, XA_STRING, serverCutProperty,
+                           serverWindow, CurrentTime);
+    }
 
     #ifdef DEBUG
     fprintf(stderr, "nxagentConvertSelection: Sent XConvertSelection with target=[%s], property [%s]\n",
@@ -1465,6 +1490,7 @@ int nxagentInitClipboard(WindowPtr pWin)
   serverCutProperty = nxagentAtoms[5];  /* NX_CUT_BUFFER_SERVER */
   serverTARGETS = nxagentAtoms[6];  /* TARGETS */
   serverTEXT = nxagentAtoms[7];  /* TEXT */
+  serverUTF8_STRING = nxagentAtoms[12]; /* UTF8_STRING */
 
   if (serverCutProperty == None)
   {
@@ -1482,6 +1508,29 @@ int nxagentInitClipboard(WindowPtr pWin)
 
   XSetSelectionOwner(nxagentDisplay, serverCutProperty, iWindow, CurrentTime);
 
+  if (XQueryExtension(nxagentDisplay,
+                      "XFIXES",
+                      &nxagentXFixesInfo.Opcode,
+                      &nxagentXFixesInfo.EventBase,
+                      &nxagentXFixesInfo.ErrorBase) == 0)
+  {
+    ErrorF("Unable to initialize XFixes extension.\n");
+  }
+
+  else
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentInitClipboard: Registering for XFixesSelectionNotify events.\n");
+    #endif
+
+    XFixesSelectSelectionInput(nxagentDisplay, iWindow, nxagentClipboardAtom,
+                               XFixesSetSelectionOwnerNotifyMask |
+                               XFixesSelectionWindowDestroyNotifyMask |
+                               XFixesSelectionClientCloseNotifyMask);
+
+    nxagentXFixesInfo.Initialized = 1;
+  }
+
   if (nxagentSessionId[0])
   {
     #ifdef TEST
@@ -1525,6 +1574,7 @@ int nxagentInitClipboard(WindowPtr pWin)
     clientTARGETS = MakeAtom(szAgentTARGETS, strlen(szAgentTARGETS), True);
     clientTEXT = MakeAtom(szAgentTEXT, strlen(szAgentTEXT), True);
     clientCOMPOUND_TEXT = MakeAtom(szAgentCOMPOUND_TEXT, strlen(szAgentCOMPOUND_TEXT), True);
+    clientUTF8_STRING = MakeAtom(szAgentUTF8_STRING, strlen(szAgentUTF8_STRING), True);
 
     if (clientCutProperty == None)
     {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
index e4bcbf65e..912260b8b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -18,6 +18,21 @@
 #ifndef __Clipboard_H__
 #define __Clipboard_H__
 
+/*
+ * Queried at clipboard initialization.
+ */
+
+typedef struct _XFixesAgentInfo
+{
+  int Opcode;
+  int EventBase;
+  int ErrorBase;
+  int Initialized;
+
+} XFixesAgentInfoRec;
+
+extern XFixesAgentInfoRec nxagentXFixesInfo;
+
 /*
  * Create the NX_CUT_BUFFER_CLIENT atom and
  * initialize the required property to exchange
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index c2e131954..9f257e508 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -123,12 +123,12 @@ static enum
 } reconnectDisplayState;
 
 int nxagentDefaultVisualIndex;
-Colormap *nxagentDefaultColormaps;
+Colormap *nxagentDefaultColormaps = NULL;
 int nxagentNumDefaultColormaps;
-int *nxagentDepths;
+int *nxagentDepths = NULL;
 int nxagentNumDepths;
-XPixmapFormatValues *nxagentPixmapFormats;
-XPixmapFormatValues *nxagentRemotePixmapFormats;
+XPixmapFormatValues *nxagentPixmapFormats = NULL;
+XPixmapFormatValues *nxagentRemotePixmapFormats = NULL;
 int nxagentNumPixmapFormats;
 int nxagentRemoteNumPixmapFormats;
 Pixel nxagentBlackPixel;
@@ -2499,6 +2499,25 @@ Bool nxagentReconnectDisplay(void *p0)
     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.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index abc228e9c..2c1b07fa5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -371,6 +371,7 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   int nBox;
   int x, y;
   int w, h;
+  int extentWidth, extentHeight;
   int tileWidth, tileHeight;
   int length, format, leftPad;
   int i;
@@ -590,8 +591,20 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
               pDrawable -> x, pDrawable -> y, pDrawable -> width, pDrawable -> height);
   #endif
 
-  w = tileWidth  = (nxagentOption(TileWidth)  > pDrawable -> width  ? pDrawable -> width  : nxagentOption(TileWidth));
-  h = tileHeight = (nxagentOption(TileHeight) > pDrawable -> height ? pDrawable -> height : nxagentOption(TileHeight));
+  /*
+   * We are going to synchronize the corrupted
+   * area, so we use the corrupted extents as
+   * maximum size of the image data. It's im-
+   * portant to avoid using the drawable size,
+   * because in case of a huge window it had to
+   * result in a failed data memory allocation.
+   */
+
+  extentWidth  = clipRegion -> extents.x2 - clipRegion -> extents.x1;
+  extentHeight = clipRegion -> extents.y2 - clipRegion -> extents.y1;
+
+  w = tileWidth  = (nxagentOption(TileWidth)  > extentWidth  ? extentWidth  : nxagentOption(TileWidth));
+  h = tileHeight = (nxagentOption(TileHeight) > extentHeight ? extentHeight : nxagentOption(TileHeight));
 
   #ifdef DEBUG
   fprintf(stderr, "nxagentSynchronizeRegion: Using tiles of size [%dx%d].\n", tileWidth, tileHeight);
@@ -2613,7 +2626,10 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
    * FIXME: A better way it would be create the bitmap
    * with the same extents of the clipRegion. This
    * requires to save the offset with respect to the
-   * drawable origin like in the backing store.
+   * drawable origin like in the backing store. This
+   * becomes particularly important when the drawable
+   * is a huge window, because the pixmap creation
+   * would fail.
    */
 
   pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index d2d9f87ea..b37d81adf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -22,6 +22,7 @@
 #include "Xproto.h"
 #include "screenint.h"
 #include "input.h"
+#include "dix.h"
 #include "misc.h"
 #include "scrnintstr.h"
 #include "windowstr.h"
@@ -61,6 +62,9 @@
 #include "NXvars.h"
 #include "NXproto.h"
 
+#include "xfixesproto.h"
+#include <X11/extensions/Xfixes.h>
+
 #ifdef NXAGENT_FIXKEYS
 #include "inputstr.h"
 #include "input.h"
@@ -113,6 +117,15 @@ extern int nxagentLastClipboardClient;
 extern Bool nxagentRootlessTreesMatch(void);
 #endif
 
+extern Selection *CurrentSelections;
+extern int NumCurrentSelections;
+
+typedef union _XFixesSelectionEvent {
+        int                          type;
+        XFixesSelectionNotifyEvent   xfixesselection;
+        XEvent                       core;
+} XFixesSelectionEvent;
+
 Bool   xkbdRunning = False;
 pid_t  pidkbd;
 
@@ -742,7 +755,19 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         if (nxagentXkbState.Initialized == 0)
         {
+          if (X.xkey.keycode == 66)
+          {
+            nxagentXkbCapsTrap = 1;
+          }
+          else if (X.xkey.keycode == 77)
+          {
+            nxagentXkbNumTrap = 1;
+          }
+
           nxagentInitKeyboardState();
+
+          nxagentXkbCapsTrap = 0;
+          nxagentXkbNumTrap = 0;
         }
 
         x.u.u.type = KeyRelease;
@@ -1283,10 +1308,6 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
                       X.xcrossing.mode == NotifyNormal)
           {
             nxagentUngrabPointerAndKeyboard(&X);
-
-            pScreen = nxagentScreen(X.xcrossing.window);
-
-            minimize = True;
           }
         }
 
@@ -1610,7 +1631,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
          * state modification event.
          */
 
-        if (nxagentHandleKeyboardEvent(&X) == 0)
+        if (nxagentHandleKeyboardEvent(&X) == 0 && nxagentHandleXFixesSelectionNotify(&X) == 0)
         {
           #ifdef TEST
           fprintf(stderr, "nxagentDispatchEvents: WARNING! Unhandled event code [%d].\n",
@@ -1805,7 +1826,19 @@ int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
 
   if (nxagentXkbState.Initialized == 0)
   {
+    if (X -> xkey.keycode == 66)
+    {
+      nxagentXkbCapsTrap = 1;
+    }
+    else if (X -> xkey.keycode == 77)
+    {
+      nxagentXkbNumTrap = 1;
+    }
+
     nxagentInitKeyboardState();
+
+    nxagentXkbCapsTrap = 0;
+    nxagentXkbNumTrap = 0;
   }
 
   if (nxagentCheckSpecialKeystroke(&X -> xkey, result))
@@ -2228,7 +2261,11 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         {
           pScreen = nxagentScreen(X -> xmap.window);
 
-          nxagentMaximizeToFullScreen(pScreen);
+          XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+          XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                             DefaultScreen(nxagentDisplay));
+
         }
 
         if (X -> xclient.window == (nxagentOption(Fullscreen) ?
@@ -2273,7 +2310,10 @@ int nxagentHandleKeyboardEvent(XEvent *X)
       fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [66] to engage capslock.\n");
       #endif
 
-      nxagentSendFakeKey(66);
+      if (!nxagentXkbCapsTrap)
+      {
+        nxagentSendFakeKey(66);
+      }
     }
 
     if (nxagentXkbState.Caps == 1 &&
@@ -2288,6 +2328,18 @@ int nxagentHandleKeyboardEvent(XEvent *X)
       nxagentSendFakeKey(66);
     }
 
+    if (nxagentXkbState.Caps == 0 &&
+          !(nxagentXkbState.Locked & CAPSFLAG_IN_EVENT) &&
+              nxagentXkbCapsTrap)
+    {
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [66] to release capslock.\n");
+      #endif
+
+      nxagentSendFakeKey(66);
+    }
+
     if (nxagentXkbState.Num == 0 &&
             (nxagentXkbState.Locked & NUMFLAG_IN_EVENT))
     {
@@ -2297,7 +2349,10 @@ int nxagentHandleKeyboardEvent(XEvent *X)
       fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [77] to engage numlock.\n");
       #endif
 
-      nxagentSendFakeKey(77);
+      if (!nxagentXkbNumTrap)
+      {
+        nxagentSendFakeKey(77);
+      }
     }
 
     if (nxagentXkbState.Num == 1 &&
@@ -2312,12 +2367,95 @@ int nxagentHandleKeyboardEvent(XEvent *X)
       nxagentSendFakeKey(77);
     }
 
+    if (nxagentXkbState.Num == 0 &&
+          !(nxagentXkbState.Locked & NUMFLAG_IN_EVENT) &&
+              nxagentXkbNumTrap)
+    {
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleKeyboardEvent: Sending fake key [77] to release numlock.\n");
+      #endif
+
+      nxagentSendFakeKey(77);
+    }
+
     return 1;
   }
 
   return 0;
 }
 
+int nxagentHandleXFixesSelectionNotify(XEvent *X)
+{
+  int i;
+  Atom local;
+
+  XFixesSelectionEvent *xfixesEvent = (XFixesSelectionEvent *) X;
+
+  if (nxagentXFixesInfo.Initialized == 0 ||
+          xfixesEvent -> type != (nxagentXFixesInfo.EventBase + XFixesSelectionNotify))
+    return 0;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Handling event.\n");
+  #endif
+
+  local = nxagentRemoteToLocalAtom(xfixesEvent -> xfixesselection.selection);
+
+  if (SelectionCallback)
+  {
+    i = 0;
+
+    while ((i < NumCurrentSelections) &&
+            CurrentSelections[i].selection != local)
+      i++;
+
+    if (i < NumCurrentSelections)
+    {
+      SelectionInfoRec    info;
+
+      if (CurrentSelections[i].client != 0)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Do nothing.\n");
+        #endif
+
+        return 1;
+      }
+
+      #ifdef TEST
+      fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Calling callbacks for %d [%s] selection.\n",
+                       CurrentSelections[i].selection, NameForAtom(CurrentSelections[i].selection));
+      #endif
+
+      #ifdef DEBUG
+      fprintf(stderr, "nxagentHandleXFixesSelectionNotify: Subtype ");
+
+      switch (xfixesEvent -> xfixesselection.subtype)
+      {
+        case SelectionSetOwner:
+          fprintf(stderr, "SelectionSetOwner.\n");
+          break;
+        case SelectionWindowDestroy:
+          fprintf(stderr, "SelectionWindowDestroy.\n");
+          break;
+        case SelectionClientClose:
+          fprintf(stderr, "SelectionClientClose.\n");
+          break;
+        default:
+          fprintf(stderr, ".\n");
+          break;
+      }
+      #endif
+
+      info.selection = &CurrentSelections[i];
+      info.kind = xfixesEvent->xfixesselection.subtype;
+      CallCallbacks(&SelectionCallback, &info);
+    }
+  }
+  return 1;
+}
+
 int nxagentHandleProxyEvent(XEvent *X)
 {
   switch (X -> xclient.data.l[0])
@@ -2924,56 +3062,6 @@ int nxagentHandleReparentNotify(XEvent* X)
 
     return 1;
   }
-  else
-  {
-    /*
-     * This code is supposed to detect if a window manager
-     * is running but in some cases it may be unreliable.
-     * Each window manager behaves differently so the check
-     * can fail for some less common WMs.
-     */
-
-    if (!nxagentWMIsRunning && nxagentOption(Fullscreen) &&
-            X -> xreparent.window == nxagentDefaultWindows[pScreen -> myNum])
-    {
-      #ifdef WARNING
-      fprintf(stderr, "Warning: The agent window was reparented. Is a "
-                  "window manager running?\n");
-      #endif
-
-      /*
-       * If no window manager is running and we are supposed to
-       * be in fullscreen mode then don't wait for the reparent
-       * event. We can assume that there is an undetected window
-       * manager and, as switching to fullscreen could have fail-
-       * ed, we try it again.
-       */
-
-      nxagentSwitchFullscreen(pScreen, True);
-
-      nxagentWMIsRunning = True;
-    }
-    else if (nxagentWMIsRunning && X -> xreparent.window ==
-                 nxagentDefaultWindows[pScreen -> myNum] && X -> xreparent.parent ==
-                     RootWindow(nxagentDisplay, (pScreen -> myNum)))
-    {
-      #ifdef WARNING
-
-      fprintf(stderr, "Warning: The agent window has been reparented to the root.\n");
-
-      fprintf(stderr, "Warning: No window manager seems to be running.\n");
-
-      #endif
-
-      /*
-       * The agent window was unexpectedly reparented
-       * to the root window. We assume that the window
-       * manager was terminated.
-       */
-
-      nxagentWMIsRunning = False;
-    }
-  }
 
   return 1;
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index 4870f83e0..ab0d25764 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -115,6 +115,7 @@ extern int nxagentHandlePropertyNotify(XEvent *X);
 extern int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult*);
 extern int nxagentHandleReparentNotify(XEvent *X);
 extern int nxagentHandleConfigureNotify(XEvent *X);
+extern int nxagentHandleXFixesSelectionNotify(XEvent *X);
 
 /*
  * Send a fake keystroke to the remote
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index ff968bcc5..e552f826b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -101,6 +101,8 @@ static XFontStruct *nxagentLoadQueryFont(register Display *dpy , char *fontName
 int nxagentFreeFont(XFontStruct *fs);
 static Bool nxagentGetFontServerPath(char * fontServerPath);
 
+static char * nxagentMakeScalableFontName(const char *fontName, int scalableResolution);
+
 RESTYPE RT_NX_FONT;
 
 #ifdef NXAGENT_RECONNECT_FONT_DEBUG
@@ -419,13 +421,59 @@ Bool nxagentFontFind(const char *name, int *pos)
 Bool nxagentFontLookUp(const char *name)
 {
   int i;
-  if (name)
-    if (!strlen(name))
-       return 0;
-  if (nxagentFontFind(name, &i))
-    return (nxagentRemoteFontList.list[i]->status > 0);
-  else
+  int result;
+
+  char *scalable;
+
+  if (name != NULL && strlen(name) == 0)
+  {
+    return 0;
+  }
+
+  result = nxagentFontFind(name, &i);
+
+  scalable = NULL;
+
+  /*
+   * Let's try with the scalable font description.
+   */
+
+  if (result == 0)
+  {
+    scalable = nxagentMakeScalableFontName(name, 0); 
+
+    if (scalable != NULL)
+    {
+      result = nxagentFontFind(scalable, &i);
+
+      free(scalable);
+    }
+  }
+
+  /*
+   * Let's try again after replacing zero to xdpi and ydpi in the pattern.
+   */
+
+  if (result == 0)
+  {
+    scalable = nxagentMakeScalableFontName(name, 1); 
+
+    if (scalable != NULL)
+    {
+      result = nxagentFontFind(scalable, &i);
+
+      free(scalable);
+    }
+  }
+
+  if (result == 0)
+  {
     return 0;
+  }
+  else
+  {
+    return (nxagentRemoteFontList.list[i]->status > 0);
+  }
 }
 
 Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont)
@@ -768,6 +816,11 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
         fprintf(stderr, "nxagentLoadBestQueryFont: Weight '%d' of more accurate font '%s' .\n", weight, substFontBuf);
         #endif
       }
+
+      for (j = 0; j < numSearchFields; j++)
+      {
+        free (searchFields[j]);
+      }
     }
   }
 
@@ -783,6 +836,11 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
 
   free (substFontBuf);
 
+  for (j = 0; j < numFontFields; j++)
+  {
+    free (fontNameFields[j]);
+  }
+
   return fontStruct;
 }
 
@@ -1688,3 +1746,88 @@ int nxagentSplitString(char *string, char *fields[], int nfields, char *sep)
   return i;
 }
 
+char *nxagentMakeScalableFontName(const char *fontName, int scalableResolution)
+{
+  char *scalableFontName;
+  const char *s;
+  int len;
+  int field;
+
+  len = strlen(fontName) + 1;
+
+  scalableFontName = malloc(len);
+
+  if (scalableFontName == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentMakeScalableFontName: PANIC! malloc() failed.\n");
+    #endif
+
+    return NULL;
+  }
+
+  scalableFontName[0] = 0;
+
+  if (*fontName != '-')
+  {
+    goto MakeScalableFontNameError;
+  }
+
+  s = fontName;
+
+  field = 0;
+
+  while (s != NULL)
+  {
+    s = strchr(s + 1, '-');
+
+    if (s != NULL)
+    {
+      if (field == 6 || field == 7 || field == 11)
+      {
+        /*
+         * PIXEL_SIZE || POINT_SIZE || AVERAGE_WIDTH
+         */
+
+        strcat(scalableFontName, "-0");
+      }
+      else if (scalableResolution == 1 && (field == 8 || field == 9))
+      {
+        /*
+         * RESOLUTION_X || RESOLUTION_Y
+         */
+
+        strcat(scalableFontName, "-0");
+      }
+      else
+      {
+        strncat(scalableFontName, fontName, s - fontName);
+      }
+
+      fontName = s;
+    }
+    else
+    {
+      strcat(scalableFontName, fontName);
+    }
+
+    field++;
+  }
+
+  if (field != 14)
+  {
+    goto MakeScalableFontNameError;
+  }
+
+  return scalableFontName;
+
+MakeScalableFontNameError:
+
+  free(scalableFontName);
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentMakeScalableFontName: Invalid font name.\n");
+  #endif
+
+  return NULL;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index 7a6432a8e..83aa04f11 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -451,6 +451,8 @@ FIXME: The popup could be synchronized with one
 
       CARD32 targetAttributes[2];
 
+      Bool pClipRegionFree = True;
+
       /*
        * As we want to copy only the synchronized
        * areas of the source drawable, we create
@@ -503,6 +505,13 @@ FIXME: The popup could be synchronized with one
 
         nxagentChangeClip(targetGC, CT_REGION, pClipRegion, 0);
 
+        /*
+         * Next call to nxagentChangeClip() will destroy
+         * pClipRegion, so it has not to be freed.
+         */
+
+        pClipRegionFree = False;
+
         #ifdef DEBUG
         fprintf(stderr, "nxagentDeferCopyArea: Going to execute a copy area with clip mask "
                     "[%d,%d,%d,%d] and origin [%d,%d].\n", ((RegionPtr) targetGC -> clientClip) -> extents.x1,
@@ -518,6 +527,11 @@ FIXME: The popup could be synchronized with one
 
       nxagentChangeClip(targetGC, CT_NONE, NullRegion, 0);
 
+      if (pClipRegionFree == True)
+      {
+        nxagentFreeRegion(pSrcDrawable, pClipRegion);
+      }
+
       FreeScratchGC(targetGC);
     }
     else
@@ -1184,7 +1198,9 @@ void nxagentPolySegment(DrawablePtr pDrawable, GCPtr pGC,
                     (XSegment *) pSegments, nSegments);
     }
 
+    SET_GC_TRAP();
     fbPolySegment(nxagentVirtualDrawable(pDrawable), pGC, nSegments, pSegments);
+    RESET_GC_TRAP();
 
     return;
   }
@@ -1193,7 +1209,9 @@ void nxagentPolySegment(DrawablePtr pDrawable, GCPtr pGC,
     XDrawSegments(nxagentDisplay, nxagentDrawable(pDrawable), nxagentGC(pGC),
                  (XSegment *) pSegments, nSegments);
 
+    SET_GC_TRAP();
     fbPolySegment(pDrawable, pGC, nSegments, pSegments);
+    RESET_GC_TRAP();
   }
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index dc9770c75..3abc3575f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -33,6 +33,7 @@
 #include "Millis.h"
 
 #include "NXlib.h"
+#include "Shadow.h"
 
 /*
  * Set here the required log level.
@@ -705,6 +706,7 @@ void nxagentShadowBlockHandler(pointer data, struct timeval **timeout, pointer m
   int changed;
   int suspended = 0;
   int result;
+  int width_, height_;
 
   #ifdef BLOCKS
   fprintf(stderr, "[Begin block]\n");
@@ -754,6 +756,19 @@ void nxagentShadowBlockHandler(pointer data, struct timeval **timeout, pointer m
 
   changed = 0;
 
+  NXShadowGetScreenSize(&width_, &height_);
+
+  if (width_ != nxagentShadowWidth || height_ != nxagentShadowHeight)
+  {
+    /*
+     * The master session has been resized.
+     */
+
+    NXShadowSetScreenSize(&nxagentShadowWidth, &nxagentShadowHeight);
+
+    nxagentShadowAdaptToRatio();
+  }
+
   nxagentShadowPoll(nxagentShadowPixmapPtr, nxagentShadowGCPtr, nxagentShadowDepth, nxagentShadowWidth,
                         nxagentShadowHeight, nxagentShadowBuffer, &changed, &suspended);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index 5108046b8..4e08f6bf1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -922,7 +922,12 @@ void nxagentRealizeImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
   int numSubImages;
   int totalHeight;
 
-  const int subSize = (MAX_REQUEST_SIZE << 2) - sizeof(xPutImageReq);
+  /*
+   * NXPutPackedImage is longer than PutPackedImage
+   * so that we subtract the bigger one to be sure.
+   */
+
+  const int subSize = (MAX_REQUEST_SIZE << 2) - sizeof(xNXPutPackedImageReq);
 
   Visual *pVisual = NULL;
 
@@ -1171,7 +1176,7 @@ FIXME: Should use an unpack resource here.
    */
 
   pack = (nxagentOption(LinkType) != LINK_TYPE_NONE &&
-              packMethod != PACK_NONE && depth > 8);
+              packMethod != PACK_NONE && depth > 8 && format == ZPixmap);
 
   lossless = (packMethod == nxagentPackLossless);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 197bd8c14..4e47f8f81 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -74,7 +74,7 @@ is" without express or implied warranty.
 #undef  DEBUG
 #undef  DUMP
 
-#define NXAGENT_VERSION  "3.1.0"
+#define NXAGENT_VERSION  "3.2.0"
 
 /*
  * ProcVector array defined in tables.c.
@@ -332,6 +332,13 @@ FIXME: These variables, if not removed at all because have probably
   nxagentAllocateGraphicContexts();
 
   nxagentDoFullGeneration = nxagentFullGeneration;
+
+  /*
+   * Use a solid black root window
+   * background.
+   */
+
+  blackRoot = TRUE;
 }
 
 void InitInput(argc, argv)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index dbdfc5b19..88e99a1a0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -444,7 +444,7 @@ N/A
                                      max_keycode - min_keycode + 1,
                                      &mapWidth);
 
-        if (keymap == NULL)
+        if (keymap64 == NULL)
         {
           XFreeModifiermap(modifier_keymap);
 
@@ -756,6 +756,8 @@ XkbError:
           XkbInitKeyboardDeviceStruct((pointer)pDev, &names, &keySyms, modmap,
                                           nxagentBell, nxagentChangeKeyboardControl);
 
+          free(nxagentXkbConfigFilePath);
+
           if (!nxagentKeyboard ||
                  (nxagentKeyboard && (strcmp(nxagentKeyboard, "query") == 0)))
           {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
index e80f62230..f6aab84e4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Literals.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -142,6 +142,13 @@ static char *nxagentRequestLiteral[] =
   "GetPointerMapping",
   "SetModifierMapping",
   "GetModifierMapping",
+  "",
+  "",
+  "",
+  "",
+  "",
+  "",
+  "",
   "NoOperation"
 };
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index de5f78fad..ce3e6ee05 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -553,12 +553,6 @@ Bool nxagentReconnectSession(void)
            strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
                strcmp(nxagentKeyboard, "query") == 0)
     {
-      if (nxagentOldKeyboard != NULL)
-      {
-        xfree(nxagentOldKeyboard);
-
-        nxagentOldKeyboard = NULL;
-      }
 
       if (nxagentResetKeyboard() == 0)
       {
@@ -576,6 +570,15 @@ Bool nxagentReconnectSession(void)
     }
   }
 
+  nxagentXkbState.Initialized = 0;
+
+  if (nxagentOldKeyboard != NULL)
+  {
+    xfree(nxagentOldKeyboard);
+
+    nxagentOldKeyboard = NULL;
+  }
+
   nxagentDeactivatePointerGrab();
 
   nxagentWakeupByReconnect();
@@ -686,6 +689,13 @@ nxagentReconnectError:
     nxagentDisconnectDisplay();
   }
 
+  if (nxagentOldKeyboard != NULL)
+  {
+    xfree(nxagentOldKeyboard);
+
+    nxagentOldKeyboard = NULL;
+  }
+
   return 0;
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 4cc1075af..34d498fb0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -78,7 +78,16 @@ is" without express or implied warranty.
 #include "Utils.h"
 
 #include "Xrandr.h"
+
+#define GC     XlibGC
+#define Font   XlibFont
+#define KeySym XlibKeySym
+#define XID    XlibXID
 #include <X11/Xlibint.h>
+#undef  GC
+#undef  Font
+#undef  KeySym
+#undef  XID
 
 #include "Xatom.h"
 #include "Xproto.h"
@@ -309,10 +318,44 @@ void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
 /*
     XUnmapWindow(nxagentDisplay, nxagentIconWindow);
 */
+/*
+FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWindow()
+       in order to avoid the session window is iconified.
+       We could avoid the sesssion window is iconified when a LeaveNotify event is received,
+       so this check would be unnecessary.
+*/
+    struct timeval timeout;
+    int i;
+    XEvent e;
+
+    XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
+                        RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
+
+    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
+      #endif
+
+      if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
+      {
+        break;
+      }
+
+      XSync(nxagentDisplay, 0);
+
+      timeout.tv_sec = 0;
+      timeout.tv_usec = 50 * 1000;
+
+      nxagentWaitEvents(nxagentDisplay, &timeout);
+    }
+
     XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
 
     XIconifyWindow(nxagentDisplay, nxagentIconWindow,
                        DefaultScreen(nxagentDisplay));
+
+    while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
 /*
     XMapWindow(nxagentDisplay, nxagentIconWindow);
 */
@@ -2872,6 +2915,15 @@ int nxagentShadowPoll(PixmapPtr nxagentShadowPixmapPtr, GCPtr nxagentShadowGCPtr
       width = pBox[n].y1 - pBox[n].x1;/* y1 = x2 */
       height = y2 - pBox[n].x2;   /* x2 = y1 */
 
+      if((x + width) > nxagentShadowWidth || (y + height) > nxagentShadowHeight)
+      {
+        /*
+         * Out of bounds. Maybe a resize of the master session is going on.
+         */
+
+        continue;
+      }
+
       line = PixmapBytePad(width, nxagentMasterDepth);
 
       #ifdef DEBUG
@@ -3826,8 +3878,8 @@ void nxagentShadowAdaptToRatio(void)
 
   pScreen = screenInfo.screens[0];
 
-  nxagentShadowSetRatio(nxagentOption(Width) * 1.0 / WindowTable[0] -> drawable.width, 
-                            nxagentOption(Height) * 1.0 / WindowTable[0] -> drawable.height);
+  nxagentShadowSetRatio(nxagentOption(Width) * 1.0 / nxagentShadowWidth,
+                            nxagentOption(Height) * 1.0 / nxagentShadowHeight);
 
   nxagentShadowCreateMainWindow(pScreen, WindowTable[0], nxagentShadowWidth, nxagentShadowHeight);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
index 3b801d803..2796b2f14 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -96,4 +96,19 @@ int nxagentLosslessTrap = 0;
 
 int nxagentSplitTrap = 0;
 
+/*
+ * Set to avoid CapsLock synchronization
+ * problems when CapsLock is the first
+ * key to be pressed in the session.
+ */
+
+int nxagentXkbCapsTrap = 0;
+
+/*
+ * Set to avoid NumLock synchronization
+ * problems when NumLock is the first
+ * key to be pressed in the session.
+ */
+
+int nxagentXkbNumTrap = 0;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
index f699306ab..493a18a1b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -97,4 +97,20 @@ extern int nxagentLosslessTrap;
 
 extern int nxagentSplitTrap;
 
+/*
+ * Set to avoid CapsLock synchronization
+ * problems when CapsLock is the first
+ * key to be pressed in the session.
+ */
+
+extern int nxagentXkbCapsTrap;
+
+/*
+ * Set to avoid NumLock synchronization
+ * problems when NumLock is the first
+ * key to be pressed in the session.
+ */
+
+extern int nxagentXkbNumTrap;
+
 #endif /* __Trap_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index 845c6cfb9..f84ca0e03 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -3835,6 +3835,8 @@ ProcSetScreenSaver (register ClientPtr client)
       {
         ScreenSaverInterval = defaultScreenSaverInterval;
       }
+
+      SetScreenSaverTimer();
     }
     #ifdef TEST
 
@@ -3846,7 +3848,6 @@ ProcSetScreenSaver (register ClientPtr client)
 
     #endif
 
-    SetScreenSaverTimer();
     return (client->noClientException);
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index 845c6cfb9..f84ca0e03 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -3835,6 +3835,8 @@ ProcSetScreenSaver (register ClientPtr client)
       {
         ScreenSaverInterval = defaultScreenSaverInterval;
       }
+
+      SetScreenSaverTimer();
     }
     #ifdef TEST
 
@@ -3846,7 +3848,6 @@ ProcSetScreenSaver (register ClientPtr client)
 
     #endif
 
-    SetScreenSaverTimer();
     return (client->noClientException);
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index 06dabddaa..f51a8bce9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -69,6 +69,17 @@
 #undef  DEBUG
 #undef  TEST
 
+#else
+
+#include "picturestr.h"
+#include "glyphstr.h"
+
+#endif
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
 #endif
 
 /*
@@ -401,8 +412,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-
-    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    size_t	     padded_width;
+    
+    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
+	return 0;
+    size = gi->height * padded_width;
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index 06dabddaa..f51a8bce9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -69,6 +69,17 @@
 #undef  DEBUG
 #undef  TEST
 
+#else
+
+#include "picturestr.h"
+#include "glyphstr.h"
+
+#endif
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
 #endif
 
 /*
@@ -401,8 +412,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-
-    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    size_t	     padded_width;
+    
+    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
+	return 0;
+    size = gi->height * padded_width;
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
index 45c5dd975..9f4d1c87b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
@@ -43,6 +43,12 @@
 #include "picturestr.h"
 #include "glyphstr.h"
 
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
 /*
  * From Knuth -- a good choice for hash/rehash values is p, p-2 where
  * p and p-2 are both prime.  These tables are sized to have an extra 10%
@@ -334,8 +340,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-
-    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    size_t	     padded_width;
+    
+    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
+	return 0;
+    size = gi->height * padded_width;
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index 00c55cde7..de2df855f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -1893,6 +1893,8 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
+    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -2353,6 +2355,8 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2955,18 +2959,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int n)
+static void swapStops(void *stuff, int num)
 {
-    int i;
+    int i, n;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < n; ++i) {
+    for (i = 0; i < num; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*n; ++i) {
+    for (i = 0; i < 4*num; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2989,6 +2993,8 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3016,6 +3022,8 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3040,6 +3048,8 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index 00c55cde7..de2df855f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -1893,6 +1893,8 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
+    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -2353,6 +2355,8 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2955,18 +2959,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int n)
+static void swapStops(void *stuff, int num)
 {
-    int i;
+    int i, n;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < n; ++i) {
+    for (i = 0; i < num; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*n; ++i) {
+    for (i = 0; i < 4*num; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2989,6 +2993,8 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3016,6 +3022,8 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3040,6 +3048,8 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
index d2759ab10..d25d49756 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
@@ -1505,6 +1505,8 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
+    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -1918,6 +1920,8 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2489,18 +2493,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int n)
+static void swapStops(void *stuff, int num)
 {
-    int i;
+    int i, n;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < n; ++i) {
+    for (i = 0; i < num; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*n; ++i) {
+    for (i = 0; i < 4*num; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2523,6 +2527,8 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2550,6 +2556,8 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2574,6 +2582,8 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
index 9af5c4187..91e03cb0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -201,6 +201,10 @@ void RegisterResourceName (RESTYPE type, char *name)
 
 #endif
 
+#ifdef NXAGENT_SERVER
+static int nxagentResChangedFlag = 0;
+#endif
+
 RESTYPE
 CreateNewResourceType(DeleteType deleteFunc)
 {
@@ -590,6 +594,9 @@ AddResource(XID id, RESTYPE type, pointer value)
     res->value = value;
     *head = res;
     rrec->elements++;
+    #ifdef NXAGENT_SERVER
+    nxagentResChangedFlag = 1;
+    #endif
     if (!(id & SERVER_BIT) && (id >= rrec->expectID))
 	rrec->expectID = id + 1;
     return TRUE;
@@ -675,6 +682,9 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
 		RESTYPE rtype = res->type;
 		*prev = res->next;
 		elements = --*eltptr;
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 1;
+                #endif
 		if (rtype & RC_CACHED)
 		    FlushClientCaches(res->id);
 		if (rtype != skipDeleteFuncType)
@@ -715,6 +725,9 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
 	    if (res->id == id && res->type == type)
 	    {
 		*prev = res->next;
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 1;
+                #endif
 		if (type & RC_CACHED)
 		    FlushClientCaches(res->id);
 		if (!skipFree)
@@ -809,12 +822,44 @@ RestartLoop:
 	    next = this->next;
 	    if (!type || this->type == type) {
 		elements = *eltptr;
+
+                /*
+                 * FIXME:
+                 * It is not safe to let a function change the resource
+                 * table we are reading!
+                 */
+
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 0;
+                #endif
 		(*func)(this->value, this->id, cdata);
+
+                /*
+                 * Avoid that a call to RebuildTable() could invalidate the
+                 * pointer. This is safe enough, because in RebuildTable()
+                 * the new pointer is allocated just before the old one is
+                 * freed, so it can't point to the same address.
+                 */
+
                 #ifdef NXAGENT_SERVER
                 if (*resptr != resources)
                    goto RestartLoop;
                 #endif
+
+                /*
+                 * It's not enough to check if the number of elements has
+                 * changed, beacause it could happen that the number of
+                 * resources that have been added matches the number of
+                 * the freed ones.
+                 * 'nxagentResChangedFlag' is set if a resource has been
+                 * added or freed.
+                 */
+
+                #ifdef NXAGENT_SERVER
+                if (*eltptr != elements || nxagentResChangedFlag)
+                #else
 		if (*eltptr != elements)
+                #endif
 		    next = resources[i]; /* start over */
 	    }
 	}
@@ -861,12 +906,44 @@ RestartLoop:
         {
             next = this->next;
             elements = *eltptr;
+
+            /*
+             * FIXME:
+             * It is not safe to let a function change the resource
+             * table we are reading!
+             */
+
+            #ifdef NXAGENT_SERVER
+            nxagentResChangedFlag = 0;
+            #endif
             (*func)(this->value, this->id, this->type, cdata);
+
+            /*
+             * Avoid that a call to RebuildTable() could invalidate the
+             * pointer. This is safe enough, because in RebuildTable()
+             * the new pointer is allocated just before the old one is
+             * freed, so it can't point to the same address.
+             */
+
             #ifdef NXAGENT_SERVER
             if (*resptr != resources)
                 goto RestartLoop;
             #endif
+
+            /*
+             * It's not enough to check if the number of elements has
+             * changed, beacause it could happen that the number of
+             * resources that have been added matches the number of
+             * the freed ones.
+             * 'nxagentResChangedFlag' is set if a resource has been
+             * added or freed.
+             */
+
+            #ifdef NXAGENT_SERVER
+            if (*eltptr != elements || nxagentResChangedFlag)
+            #else
             if (*eltptr != elements)
+            #endif
                 next = resources[i]; /* start over */
         }
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index 9af5c4187..91e03cb0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -201,6 +201,10 @@ void RegisterResourceName (RESTYPE type, char *name)
 
 #endif
 
+#ifdef NXAGENT_SERVER
+static int nxagentResChangedFlag = 0;
+#endif
+
 RESTYPE
 CreateNewResourceType(DeleteType deleteFunc)
 {
@@ -590,6 +594,9 @@ AddResource(XID id, RESTYPE type, pointer value)
     res->value = value;
     *head = res;
     rrec->elements++;
+    #ifdef NXAGENT_SERVER
+    nxagentResChangedFlag = 1;
+    #endif
     if (!(id & SERVER_BIT) && (id >= rrec->expectID))
 	rrec->expectID = id + 1;
     return TRUE;
@@ -675,6 +682,9 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType)
 		RESTYPE rtype = res->type;
 		*prev = res->next;
 		elements = --*eltptr;
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 1;
+                #endif
 		if (rtype & RC_CACHED)
 		    FlushClientCaches(res->id);
 		if (rtype != skipDeleteFuncType)
@@ -715,6 +725,9 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
 	    if (res->id == id && res->type == type)
 	    {
 		*prev = res->next;
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 1;
+                #endif
 		if (type & RC_CACHED)
 		    FlushClientCaches(res->id);
 		if (!skipFree)
@@ -809,12 +822,44 @@ RestartLoop:
 	    next = this->next;
 	    if (!type || this->type == type) {
 		elements = *eltptr;
+
+                /*
+                 * FIXME:
+                 * It is not safe to let a function change the resource
+                 * table we are reading!
+                 */
+
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 0;
+                #endif
 		(*func)(this->value, this->id, cdata);
+
+                /*
+                 * Avoid that a call to RebuildTable() could invalidate the
+                 * pointer. This is safe enough, because in RebuildTable()
+                 * the new pointer is allocated just before the old one is
+                 * freed, so it can't point to the same address.
+                 */
+
                 #ifdef NXAGENT_SERVER
                 if (*resptr != resources)
                    goto RestartLoop;
                 #endif
+
+                /*
+                 * It's not enough to check if the number of elements has
+                 * changed, beacause it could happen that the number of
+                 * resources that have been added matches the number of
+                 * the freed ones.
+                 * 'nxagentResChangedFlag' is set if a resource has been
+                 * added or freed.
+                 */
+
+                #ifdef NXAGENT_SERVER
+                if (*eltptr != elements || nxagentResChangedFlag)
+                #else
 		if (*eltptr != elements)
+                #endif
 		    next = resources[i]; /* start over */
 	    }
 	}
@@ -861,12 +906,44 @@ RestartLoop:
         {
             next = this->next;
             elements = *eltptr;
+
+            /*
+             * FIXME:
+             * It is not safe to let a function change the resource
+             * table we are reading!
+             */
+
+            #ifdef NXAGENT_SERVER
+            nxagentResChangedFlag = 0;
+            #endif
             (*func)(this->value, this->id, this->type, cdata);
+
+            /*
+             * Avoid that a call to RebuildTable() could invalidate the
+             * pointer. This is safe enough, because in RebuildTable()
+             * the new pointer is allocated just before the old one is
+             * freed, so it can't point to the same address.
+             */
+
             #ifdef NXAGENT_SERVER
             if (*resptr != resources)
                 goto RestartLoop;
             #endif
+
+            /*
+             * It's not enough to check if the number of elements has
+             * changed, beacause it could happen that the number of
+             * resources that have been added matches the number of
+             * the freed ones.
+             * 'nxagentResChangedFlag' is set if a resource has been
+             * added or freed.
+             */
+
+            #ifdef NXAGENT_SERVER
+            if (*eltptr != elements || nxagentResChangedFlag)
+            #else
             if (*eltptr != elements)
+            #endif
                 next = resources[i]; /* start over */
         }
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index e3e4f4b83..a6d638ea7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -967,8 +967,17 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-		   client);
+    /* 
+     * There's a potential integer overflow in this check:
+     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+     *                client);
+     * the version below ought to avoid it
+     */
+    if (stuff->totalHeight != 0 && 
+	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+	client->errorValue = stuff->totalWidth;
+	return BadValue;
+    }
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index e3e4f4b83..a6d638ea7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -967,8 +967,17 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-		   client);
+    /* 
+     * There's a potential integer overflow in this check:
+     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+     *                client);
+     * the version below ought to avoid it
+     */
+    if (stuff->totalHeight != 0 && 
+	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+	client->errorValue = stuff->totalWidth;
+	return BadValue;
+    }
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
index e2cf8cd24..f25bb9b5d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
@@ -863,8 +863,17 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-		   client);
+    /* 
+     * There's a potential integer overflow in this check:
+     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+     *                client);
+     * the version below ought to avoid it
+     */
+    if (stuff->totalHeight != 0 && 
+	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+	client->errorValue = stuff->totalWidth;
+	return BadValue;
+    }
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
index 7ba468ac0..24dad322f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -153,6 +153,9 @@ extern Bool nxagentScreenTrap;
  *
  ******/
 
+static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
+static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+
 int screenIsSaved = SCREEN_SAVER_OFF;
 
 ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
@@ -355,18 +358,7 @@ void nxagentClearSplash(WindowPtr pW)
     (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
 }
 
-static void
-#if NeedFunctionPrototypes
-MakeRootTile(WindowPtr pWin)
-#else
-MakeRootTile(pWin)
-    WindowPtr pWin;
-#endif
-{
-    nxagentRootTileWindow = pWin;
-}
-
-#else /* NXAGENT_SERVER */
+#endif /* NXAGENT_SERVER */
 
 static void
 MakeRootTile(WindowPtr pWin)
@@ -412,9 +404,10 @@ MakeRootTile(WindowPtr pWin)
 
    FreeScratchGC(pGC);
 
-}
-
+#ifdef NXAGENT_SERVER
+   nxagentRootTileWindow = pWin;
 #endif /* NXAGENT_SERVER */
+}
 
 WindowPtr
 AllocateWindow(ScreenPtr pScreen)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
index 7ba468ac0..24dad322f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -153,6 +153,9 @@ extern Bool nxagentScreenTrap;
  *
  ******/
 
+static unsigned char _back_lsb[4] = {0x88, 0x22, 0x44, 0x11};
+static unsigned char _back_msb[4] = {0x11, 0x44, 0x22, 0x88};
+
 int screenIsSaved = SCREEN_SAVER_OFF;
 
 ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
@@ -355,18 +358,7 @@ void nxagentClearSplash(WindowPtr pW)
     (*pScreen->ChangeWindowAttributes)(pW, CWBackPixmap|CWBackPixel);
 }
 
-static void
-#if NeedFunctionPrototypes
-MakeRootTile(WindowPtr pWin)
-#else
-MakeRootTile(pWin)
-    WindowPtr pWin;
-#endif
-{
-    nxagentRootTileWindow = pWin;
-}
-
-#else /* NXAGENT_SERVER */
+#endif /* NXAGENT_SERVER */
 
 static void
 MakeRootTile(WindowPtr pWin)
@@ -412,9 +404,10 @@ MakeRootTile(WindowPtr pWin)
 
    FreeScratchGC(pGC);
 
-}
-
+#ifdef NXAGENT_SERVER
+   nxagentRootTileWindow = pWin;
 #endif /* NXAGENT_SERVER */
+}
 
 WindowPtr
 AllocateWindow(ScreenPtr pScreen)
-- 
cgit v1.2.3


From b79164001d1eb06f4591c59b7a7c2c0fb29e992b Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:55 +0200
Subject: Imported nxagent-3.2.0-5.tar.gz

Summary: Imported nxagent-3.2.0-5.tar.gz
Keywords:

Imported nxagent-3.2.0-5.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |   12 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |   34 -
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig  | 5959 --------------------
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |   22 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.c        |   56 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |  145 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.c         |    2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      |    2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   19 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   19 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.X.original      |   14 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |   18 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |   18 +-
 .../Xserver/hw/nxagent/X/NXrender.c.X.original     |   18 +-
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |    8 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~ | 1250 ++++
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   13 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   13 +-
 .../Xserver/hw/nxagent/X/NXshm.c.X.original        |   13 +-
 19 files changed, 1346 insertions(+), 6289 deletions(-)
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig
 create mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index c74bc3f56..5b336279e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -2080,8 +2080,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 4096;
-      tileHeight = 4096;
+      tileWidth  = 65536;
+      tileHeight = 65536;
 
       break;
     }
@@ -2091,8 +2091,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 4096;
-      tileHeight = 4096;
+      tileWidth  = 65536;
+      tileHeight = 65536;
 
       break;
     }
@@ -2103,8 +2103,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 4096;
-      tileHeight = 4096;
+      tileWidth  = 65536;
+      tileHeight = 65536;
 
       break;
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 1c10208ae..4d930b9b5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,39 +1,5 @@
 ChangeLog:
 
-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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig
deleted file mode 100644
index 539a7b829..000000000
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG.orig
+++ /dev/null
@@ -1,5959 +0,0 @@
-ChangeLog:
-
-nxagent-3.2.0-8-MAR1
-
-- Fixed TR07F02091. Scalable fonts were not correctly listed among
-  available fonts.
-
-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/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 2c1b07fa5..abc228e9c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -371,7 +371,6 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   int nBox;
   int x, y;
   int w, h;
-  int extentWidth, extentHeight;
   int tileWidth, tileHeight;
   int length, format, leftPad;
   int i;
@@ -591,20 +590,8 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
               pDrawable -> x, pDrawable -> y, pDrawable -> width, pDrawable -> height);
   #endif
 
-  /*
-   * We are going to synchronize the corrupted
-   * area, so we use the corrupted extents as
-   * maximum size of the image data. It's im-
-   * portant to avoid using the drawable size,
-   * because in case of a huge window it had to
-   * result in a failed data memory allocation.
-   */
-
-  extentWidth  = clipRegion -> extents.x2 - clipRegion -> extents.x1;
-  extentHeight = clipRegion -> extents.y2 - clipRegion -> extents.y1;
-
-  w = tileWidth  = (nxagentOption(TileWidth)  > extentWidth  ? extentWidth  : nxagentOption(TileWidth));
-  h = tileHeight = (nxagentOption(TileHeight) > extentHeight ? extentHeight : nxagentOption(TileHeight));
+  w = tileWidth  = (nxagentOption(TileWidth)  > pDrawable -> width  ? pDrawable -> width  : nxagentOption(TileWidth));
+  h = tileHeight = (nxagentOption(TileHeight) > pDrawable -> height ? pDrawable -> height : nxagentOption(TileHeight));
 
   #ifdef DEBUG
   fprintf(stderr, "nxagentSynchronizeRegion: Using tiles of size [%dx%d].\n", tileWidth, tileHeight);
@@ -2626,10 +2613,7 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
    * FIXME: A better way it would be create the bitmap
    * with the same extents of the clipRegion. This
    * requires to save the offset with respect to the
-   * drawable origin like in the backing store. This
-   * becomes particularly important when the drawable
-   * is a huge window, because the pixmap creation
-   * would fail.
+   * drawable origin like in the backing store.
    */
 
   pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index b37d81adf..90fb7641b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -2261,11 +2261,7 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         {
           pScreen = nxagentScreen(X -> xmap.window);
 
-          XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
-
-          XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                             DefaultScreen(nxagentDisplay));
-
+          nxagentMaximizeToFullScreen(pScreen);
         }
 
         if (X -> xclient.window == (nxagentOption(Fullscreen) ?
@@ -3062,6 +3058,56 @@ int nxagentHandleReparentNotify(XEvent* X)
 
     return 1;
   }
+  else
+  {
+    /*
+     * This code is supposed to detect if a window manager
+     * is running but in some cases it may be unreliable.
+     * Each window manager behaves differently so the check
+     * can fail for some less common WMs.
+     */
+
+    if (!nxagentWMIsRunning && nxagentOption(Fullscreen) &&
+            X -> xreparent.window == nxagentDefaultWindows[pScreen -> myNum])
+    {
+      #ifdef WARNING
+      fprintf(stderr, "Warning: The agent window was reparented. Is a "
+                  "window manager running?\n");
+      #endif
+
+      /*
+       * If no window manager is running and we are supposed to
+       * be in fullscreen mode then don't wait for the reparent
+       * event. We can assume that there is an undetected window
+       * manager and, as switching to fullscreen could have fail-
+       * ed, we try it again.
+       */
+
+      nxagentSwitchFullscreen(pScreen, True);
+
+      nxagentWMIsRunning = True;
+    }
+    else if (nxagentWMIsRunning && X -> xreparent.window ==
+                 nxagentDefaultWindows[pScreen -> myNum] && X -> xreparent.parent ==
+                     RootWindow(nxagentDisplay, (pScreen -> myNum)))
+    {
+      #ifdef WARNING
+
+      fprintf(stderr, "Warning: The agent window has been reparented to the root.\n");
+
+      fprintf(stderr, "Warning: No window manager seems to be running.\n");
+
+      #endif
+
+      /*
+       * The agent window was unexpectedly reparented
+       * to the root window. We assume that the window
+       * manager was terminated.
+       */
+
+      nxagentWMIsRunning = False;
+    }
+  }
 
   return 1;
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index e552f826b..6fb34f221 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -101,8 +101,6 @@ static XFontStruct *nxagentLoadQueryFont(register Display *dpy , char *fontName
 int nxagentFreeFont(XFontStruct *fs);
 static Bool nxagentGetFontServerPath(char * fontServerPath);
 
-static char * nxagentMakeScalableFontName(const char *fontName, int scalableResolution);
-
 RESTYPE RT_NX_FONT;
 
 #ifdef NXAGENT_RECONNECT_FONT_DEBUG
@@ -421,59 +419,13 @@ Bool nxagentFontFind(const char *name, int *pos)
 Bool nxagentFontLookUp(const char *name)
 {
   int i;
-  int result;
-
-  char *scalable;
-
-  if (name != NULL && strlen(name) == 0)
-  {
-    return 0;
-  }
-
-  result = nxagentFontFind(name, &i);
-
-  scalable = NULL;
-
-  /*
-   * Let's try with the scalable font description.
-   */
-
-  if (result == 0)
-  {
-    scalable = nxagentMakeScalableFontName(name, 0); 
-
-    if (scalable != NULL)
-    {
-      result = nxagentFontFind(scalable, &i);
-
-      free(scalable);
-    }
-  }
-
-  /*
-   * Let's try again after replacing zero to xdpi and ydpi in the pattern.
-   */
-
-  if (result == 0)
-  {
-    scalable = nxagentMakeScalableFontName(name, 1); 
-
-    if (scalable != NULL)
-    {
-      result = nxagentFontFind(scalable, &i);
-
-      free(scalable);
-    }
-  }
-
-  if (result == 0)
-  {
-    return 0;
-  }
-  else
-  {
+  if (name)
+    if (!strlen(name))
+       return 0;
+  if (nxagentFontFind(name, &i))
     return (nxagentRemoteFontList.list[i]->status > 0);
-  }
+  else
+    return 0;
 }
 
 Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont)
@@ -1746,88 +1698,3 @@ int nxagentSplitString(char *string, char *fields[], int nfields, char *sep)
   return i;
 }
 
-char *nxagentMakeScalableFontName(const char *fontName, int scalableResolution)
-{
-  char *scalableFontName;
-  const char *s;
-  int len;
-  int field;
-
-  len = strlen(fontName) + 1;
-
-  scalableFontName = malloc(len);
-
-  if (scalableFontName == NULL)
-  {
-    #ifdef PANIC
-    fprintf(stderr, "nxagentMakeScalableFontName: PANIC! malloc() failed.\n");
-    #endif
-
-    return NULL;
-  }
-
-  scalableFontName[0] = 0;
-
-  if (*fontName != '-')
-  {
-    goto MakeScalableFontNameError;
-  }
-
-  s = fontName;
-
-  field = 0;
-
-  while (s != NULL)
-  {
-    s = strchr(s + 1, '-');
-
-    if (s != NULL)
-    {
-      if (field == 6 || field == 7 || field == 11)
-      {
-        /*
-         * PIXEL_SIZE || POINT_SIZE || AVERAGE_WIDTH
-         */
-
-        strcat(scalableFontName, "-0");
-      }
-      else if (scalableResolution == 1 && (field == 8 || field == 9))
-      {
-        /*
-         * RESOLUTION_X || RESOLUTION_Y
-         */
-
-        strcat(scalableFontName, "-0");
-      }
-      else
-      {
-        strncat(scalableFontName, fontName, s - fontName);
-      }
-
-      fontName = s;
-    }
-    else
-    {
-      strcat(scalableFontName, fontName);
-    }
-
-    field++;
-  }
-
-  if (field != 14)
-  {
-    goto MakeScalableFontNameError;
-  }
-
-  return scalableFontName;
-
-MakeScalableFontNameError:
-
-  free(scalableFontName);
-
-  #ifdef DEBUG
-  fprintf(stderr, "nxagentMakeScalableFontName: Invalid font name.\n");
-  #endif
-
-  return NULL;
-}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index 4e08f6bf1..5b40f32e9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -1176,7 +1176,7 @@ FIXME: Should use an unpack resource here.
    */
 
   pack = (nxagentOption(LinkType) != LINK_TYPE_NONE &&
-              packMethod != PACK_NONE && depth > 8 && format == ZPixmap);
+              packMethod != PACK_NONE && depth > 8);
 
   lossless = (packMethod == nxagentPackLossless);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 88e99a1a0..1cc6898d7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -444,7 +444,7 @@ N/A
                                      max_keycode - min_keycode + 1,
                                      &mapWidth);
 
-        if (keymap64 == NULL)
+        if (keymap == NULL)
         {
           XFreeModifiermap(modifier_keymap);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index f51a8bce9..06dabddaa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -69,17 +69,6 @@
 #undef  DEBUG
 #undef  TEST
 
-#else
-
-#include "picturestr.h"
-#include "glyphstr.h"
-
-#endif
-
-#if HAVE_STDINT_H
-#include <stdint.h>
-#elif !defined(UINT32_MAX)
-#define UINT32_MAX 0xffffffffU
 #endif
 
 /*
@@ -412,12 +401,8 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-    size_t	     padded_width;
-    
-    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
-    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
-	return 0;
-    size = gi->height * padded_width;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index f51a8bce9..06dabddaa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -69,17 +69,6 @@
 #undef  DEBUG
 #undef  TEST
 
-#else
-
-#include "picturestr.h"
-#include "glyphstr.h"
-
-#endif
-
-#if HAVE_STDINT_H
-#include <stdint.h>
-#elif !defined(UINT32_MAX)
-#define UINT32_MAX 0xffffffffU
 #endif
 
 /*
@@ -412,12 +401,8 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-    size_t	     padded_width;
-    
-    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
-    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
-	return 0;
-    size = gi->height * padded_width;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
index 9f4d1c87b..45c5dd975 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
@@ -43,12 +43,6 @@
 #include "picturestr.h"
 #include "glyphstr.h"
 
-#if HAVE_STDINT_H
-#include <stdint.h>
-#elif !defined(UINT32_MAX)
-#define UINT32_MAX 0xffffffffU
-#endif
-
 /*
  * From Knuth -- a good choice for hash/rehash values is p, p-2 where
  * p and p-2 are both prime.  These tables are sized to have an extra 10%
@@ -340,12 +334,8 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-    size_t	     padded_width;
-    
-    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
-    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
-	return 0;
-    size = gi->height * padded_width;
+
+    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index de2df855f..00c55cde7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -1893,8 +1893,6 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
-    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
-	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -2355,8 +2353,6 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2959,18 +2955,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int num)
+static void swapStops(void *stuff, int n)
 {
-    int i, n;
+    int i;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < num; ++i) {
+    for (i = 0; i < n; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*num; ++i) {
+    for (i = 0; i < 4*n; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2993,8 +2989,6 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3022,8 +3016,6 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3048,8 +3040,6 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index de2df855f..00c55cde7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -1893,8 +1893,6 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
-    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
-	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -2355,8 +2353,6 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2959,18 +2955,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int num)
+static void swapStops(void *stuff, int n)
 {
-    int i, n;
+    int i;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < num; ++i) {
+    for (i = 0; i < n; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*num; ++i) {
+    for (i = 0; i < 4*n; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2993,8 +2989,6 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3022,8 +3016,6 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3048,8 +3040,6 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
index d25d49756..d2759ab10 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
@@ -1505,8 +1505,6 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
-    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
-	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -1920,8 +1918,6 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2493,18 +2489,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int num)
+static void swapStops(void *stuff, int n)
 {
-    int i, n;
+    int i;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < num; ++i) {
+    for (i = 0; i < n; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*num; ++i) {
+    for (i = 0; i < 4*n; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2527,8 +2523,6 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2556,8 +2550,6 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2582,8 +2574,6 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
-    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
-	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index 91e03cb0e..7dd021a6e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -194,6 +194,10 @@ static DeleteType *DeleteFuncs = (DeleteType *)NULL;
 
 Atom * ResourceNames = NULL;
 
+#ifdef NXAGENT_SERVER
+static int nxagentResChangedFlag = 0;
+#endif
+
 void RegisterResourceName (RESTYPE type, char *name)
 {
     ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
@@ -201,10 +205,6 @@ void RegisterResourceName (RESTYPE type, char *name)
 
 #endif
 
-#ifdef NXAGENT_SERVER
-static int nxagentResChangedFlag = 0;
-#endif
-
 RESTYPE
 CreateNewResourceType(DeleteType deleteFunc)
 {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~
new file mode 100644
index 000000000..7dd021a6e
--- /dev/null
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~
@@ -0,0 +1,1250 @@
+/**************************************************************************/
+/*                                                                        */
+/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
+/*                                                                        */
+/* All rights reserved.                                                   */
+/*                                                                        */
+/**************************************************************************/
+
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+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.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+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 Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL 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 panoramix components contained the following notice */
+/*****************************************************************
+
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
+/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
+/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
+
+/*	Routines to manage various kinds of resources:
+ *
+ *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
+ *	FakeClientID, AddResource, FreeResource, FreeClientResources,
+ *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
+ */
+
+/* 
+ *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
+ *	off-limits for client-visible resources.  The next 8 bits are
+ *      used as client ID, and the low 22 bits come from the client.
+ *	A resource ID is "hashed" by extracting and xoring subfields
+ *      (varying with the size of the hash table).
+ *
+ *      It is sometimes necessary for the server to create an ID that looks
+ *      like it belongs to a client.  This ID, however,  must not be one
+ *      the client actually can create, or we have the potential for conflict.
+ *      The 31st bit of the ID is reserved for the server's use for this
+ *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
+ *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
+ *      resource "owned" by the client.
+ */
+/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
+
+#define NEED_EVENTS
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "os.h"
+#include "resource.h"
+#include "dixstruct.h" 
+#include "opaque.h"
+#include "windowstr.h"
+#include "dixfont.h"
+#include "colormap.h"
+#include "inputstr.h"
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "cursor.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include <assert.h>
+
+#ifdef NXAGENT_SERVER
+
+#include "Agent.h"
+#include "Font.h"
+#include "Pixmaps.h"
+#include "GCs.h"
+
+#define PANIC
+#define WARNING
+#undef  TEST
+#undef  DEBUG
+
+#endif
+
+static void RebuildTable(
+    int /*client*/
+);
+
+#define SERVER_MINID 32
+
+#define INITBUCKETS 64
+#define INITHASHSIZE 6
+#define MAXHASHSIZE 11
+
+typedef struct _Resource {
+    struct _Resource	*next;
+    XID			id;
+    RESTYPE		type;
+    pointer		value;
+} ResourceRec, *ResourcePtr;
+#define NullResource ((ResourcePtr)NULL)
+
+typedef struct _ClientResource {
+    ResourcePtr *resources;
+    int		elements;
+    int		buckets;
+    int		hashsize;	/* log(2)(buckets) */
+    XID		fakeID;
+    XID		endFakeID;
+    XID		expectID;
+} ClientResourceRec;
+
+RESTYPE lastResourceType;
+static RESTYPE lastResourceClass;
+RESTYPE TypeMask;
+
+static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+
+#ifdef XResExtension
+
+Atom * ResourceNames = NULL;
+
+#ifdef NXAGENT_SERVER
+static int nxagentResChangedFlag = 0;
+#endif
+
+void RegisterResourceName (RESTYPE type, char *name)
+{
+    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
+}
+
+#endif
+
+RESTYPE
+CreateNewResourceType(DeleteType deleteFunc)
+{
+    RESTYPE next = lastResourceType + 1;
+    DeleteType *funcs;
+
+    if (next & lastResourceClass)
+	return 0;
+    funcs = (DeleteType *)xrealloc(DeleteFuncs,
+				   (next + 1) * sizeof(DeleteType));
+    if (!funcs)
+	return 0;
+
+#ifdef XResExtension
+    {
+       Atom *newnames;
+       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
+       if(!newnames)
+           return 0;
+       ResourceNames = newnames;
+       ResourceNames[next] = 0;
+    }
+#endif
+
+    lastResourceType = next;
+    DeleteFuncs = funcs;
+    DeleteFuncs[next] = deleteFunc;
+    return next;
+}
+
+RESTYPE
+CreateNewResourceClass()
+{
+    RESTYPE next = lastResourceClass >> 1;
+
+    if (next & lastResourceType)
+	return 0;
+    lastResourceClass = next;
+    TypeMask = next - 1;
+    return next;
+}
+
+ClientResourceRec clientTable[MAXCLIENTS];
+
+/*****************
+ * InitClientResources
+ *    When a new client is created, call this to allocate space
+ *    in resource table
+ *****************/
+
+Bool
+InitClientResources(ClientPtr client)
+{
+    register int i, j;
+ 
+    if (client == serverClient)
+    {
+	lastResourceType = RT_LASTPREDEF;
+	lastResourceClass = RC_LASTPREDEF;
+	TypeMask = RC_LASTPREDEF - 1;
+	if (DeleteFuncs)
+	    xfree(DeleteFuncs);
+	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
+					   sizeof(DeleteType));
+	if (!DeleteFuncs)
+	    return FALSE;
+	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
+	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
+	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
+	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
+	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
+	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
+	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
+	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
+	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
+	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+
+#ifdef XResExtension
+        if(ResourceNames)
+            xfree(ResourceNames);
+        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
+        if(!ResourceNames)
+           return FALSE;
+#endif
+    }
+    clientTable[i = client->index].resources =
+	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
+    if (!clientTable[i].resources)
+	return FALSE;
+    clientTable[i].buckets = INITBUCKETS;
+    clientTable[i].elements = 0;
+    clientTable[i].hashsize = INITHASHSIZE;
+    /* Many IDs allocated from the server client are visible to clients,
+     * so we don't use the SERVER_BIT for them, but we have to start
+     * past the magic value constants used in the protocol.  For normal
+     * clients, we can start from zero, with SERVER_BIT set.
+     */
+    clientTable[i].fakeID = client->clientAsMask |
+			    (client->index ? SERVER_BIT : SERVER_MINID);
+    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
+    clientTable[i].expectID = client->clientAsMask;
+    for (j=0; j<INITBUCKETS; j++) 
+    {
+        clientTable[i].resources[j] = NullResource;
+    }
+    return TRUE;
+}
+
+
+static int
+Hash(int client, register XID id)
+{
+    id &= RESOURCE_ID_MASK;
+    switch (clientTable[client].hashsize)
+    {
+	case 6:
+	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
+	case 7:
+	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
+	case 8:
+	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
+	case 9:
+	    return ((int)(0x1FF & (id ^ (id>>9))));
+	case 10:
+	    return ((int)(0x3FF & (id ^ (id>>10))));
+	case 11:
+	    return ((int)(0x7FF & (id ^ (id>>11))));
+    }
+    return -1;
+}
+
+static XID
+AvailableID(
+    register int client,
+    register XID id,
+    register XID maxid,
+    register XID goodid)
+{
+    register ResourcePtr res;
+
+    if ((goodid >= id) && (goodid <= maxid))
+	return goodid;
+    for (; id <= maxid; id++)
+    {
+	res = clientTable[client].resources[Hash(client, id)];
+	while (res && (res->id != id))
+	    res = res->next;
+	if (!res)
+	    return id;
+    }
+    return 0;
+}
+
+void
+GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
+{
+    register XID id, maxid;
+    register ResourcePtr *resp;
+    register ResourcePtr res;
+    register int i;
+    XID goodid;
+
+    id = (Mask)client << CLIENTOFFSET;
+    if (server)
+	id |= client ? SERVER_BIT : SERVER_MINID;
+    maxid = id | RESOURCE_ID_MASK;
+    goodid = 0;
+    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
+	 --i >= 0;)
+    {
+	for (res = *resp++; res; res = res->next)
+	{
+	    if ((res->id < id) || (res->id > maxid))
+		continue;
+	    if (((res->id - id) >= (maxid - res->id)) ?
+		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
+		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
+		maxid = res->id - 1;
+	    else
+		id = res->id + 1;
+	}
+    }
+    if (id > maxid)
+	id = maxid = 0;
+    *minp = id;
+    *maxp = maxid;
+}
+
+/**
+ *  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
+ *  This function tries to find count unused XIDs for the given client.  It 
+ *  puts the IDs in the array pids and returns the number found, which should
+ *  almost always be the number requested.
+ *
+ *  The circumstances that lead to a call to this function are very rare.
+ *  Xlib must run out of IDs while trying to generate a request that wants
+ *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
+ *
+ *  No rocket science in the implementation; just iterate over all
+ *  possible IDs for the given client and pick the first count IDs
+ *  that aren't in use.  A more efficient algorithm could probably be
+ *  invented, but this will be used so rarely that this should suffice.
+ */
+
+unsigned int
+GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
+{
+    unsigned int found = 0;
+    XID id = pClient->clientAsMask;
+    XID maxid;
+
+    maxid = id | RESOURCE_ID_MASK;
+    while ( (found < count) && (id <= maxid) )
+    {
+	if (!LookupIDByClass(id, RC_ANY))
+	{
+	    pids[found++] = id;
+	}
+	id++;
+    }
+    return found;
+}
+
+/*
+ * Return the next usable fake client ID.
+ *
+ * Normally this is just the next one in line, but if we've used the last
+ * in the range, we need to find a new range of safe IDs to avoid
+ * over-running another client.
+ */
+
+XID
+FakeClientID(register int client)
+{
+    XID id, maxid;
+
+    id = clientTable[client].fakeID++;
+    if (id != clientTable[client].endFakeID)
+	return id;
+    GetXIDRange(client, TRUE, &id, &maxid);
+    if (!id) {
+	if (!client)
+	    FatalError("FakeClientID: server internal ids exhausted\n");
+	MarkClientException(clients[client]);
+	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
+	maxid = id | RESOURCE_ID_MASK;
+    }
+    clientTable[client].fakeID = id + 1;
+    clientTable[client].endFakeID = maxid + 1;
+    return id;
+}
+
+#ifdef NXAGENT_SERVER
+
+int nxagentFindClientResource(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  int i;
+
+  for (i = 0; i < clientTable[client].buckets; i++)
+  {
+    resources = clientTable[client].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == type && pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
+                    "for client [%d].\n", (void *) value,
+                        pResource -> type, client);
+        #endif
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
+{
+  ResourcePtr pResource;
+  ResourcePtr *resources;
+
+  RESTYPE internalType = 0;
+
+  int i;
+
+  if (type == RT_PIXMAP)
+  {
+    internalType = RT_NX_PIXMAP;
+  }
+  else if (type == RT_GC)
+  {
+    internalType = RT_NX_GC;
+  }
+  else if (type == RT_FONT)
+  {
+    internalType = RT_NX_FONT;
+  }
+  else
+  {
+    return 0;
+  }
+
+  if (client == serverClient -> index)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
+                client);
+    #endif
+
+    return 0;
+  }
+
+  for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
+  {
+    resources = clientTable[serverClient -> index].resources;
+
+    for (pResource = resources[i]; pResource; pResource = pResource -> next)
+    {
+      if (pResource -> type == internalType &&
+              pResource -> value == value)
+      {
+        #ifdef TEST
+        fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
+                    "[%lu] for server client [%d].\n", (void *) value,
+                        (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
+        #endif
+
+        FreeResource(pResource -> id, RT_NONE);
+
+        return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+#endif
+
+Bool
+AddResource(XID id, RESTYPE type, pointer value)
+{
+    int client;
+    register ClientResourceRec *rrec;
+    register ResourcePtr res, *head;
+
+    client = CLIENT_ID(id);
+    rrec = &clientTable[client];
+    if (!rrec->buckets)
+    {
+	ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
+		(unsigned long)id, type, (unsigned long)value, client);
+        FatalError("client not in use\n");
+    }
+
+#ifdef NXAGENT_SERVER
+
+    nxagentSwitchResourceType(client, type, value);
+
+    #ifdef TEST
+    fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
+                client, (unsigned long) type, (void *) value, (unsigned long) id);
+    #endif
+
+#endif
+
+    if ((rrec->elements >= 4*rrec->buckets) &&
+	(rrec->hashsize < MAXHASHSIZE))
+	RebuildTable(client);
+    head = &rrec->resources[Hash(client, id)];
+    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
+    if (!res)
+    {
+	(*DeleteFuncs[type & TypeMask])(value, id);
+	return FALSE;
+    }
+    res->next = *head;
+    res->id = id;
+    res->type = type;
+    res->value = value;
+    *head = res;
+    rrec->elements++;
+    #ifdef NXAGENT_SERVER
+    nxagentResChangedFlag = 1;
+    #endif
+    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
+	rrec->expectID = id + 1;
+    return TRUE;
+}
+
+static void
+RebuildTable(int client)
+{
+    register int j;
+    register ResourcePtr res, next;
+    ResourcePtr **tails, *resources;
+    register ResourcePtr **tptr, *rptr;
+
+    /*
+     * For now, preserve insertion order, since some ddx layers depend
+     * on resources being free in the opposite order they are added.
+     */
+
+    j = 2 * clientTable[client].buckets;
+    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
+    if (!tails)
+	return;
+    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
+    if (!resources)
+    {
+	DEALLOCATE_LOCAL(tails);
+	return;
+    }
+    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
+    {
+	*rptr = NullResource;
+	*tptr = rptr;
+    }
+    clientTable[client].hashsize++;
+    for (j = clientTable[client].buckets,
+	 rptr = clientTable[client].resources;
+	 --j >= 0;
+	 rptr++)
+    {
+	for (res = *rptr; res; res = next)
+	{
+	    next = res->next;
+	    res->next = NullResource;
+	    tptr = &tails[Hash(client, res->id)];
+	    **tptr = res;
+	    *tptr = &res->next;
+	}
+    }
+    DEALLOCATE_LOCAL(tails);
+    clientTable[client].buckets *= 2;
+    xfree(clientTable[client].resources);
+    clientTable[client].resources = resources;
+}
+
+void
+FreeResource(XID id, RESTYPE skipDeleteFuncType)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    register	int *eltptr;
+    int		elements;
+    Bool	gotOne = FALSE;
+
+#ifdef NXAGENT_SERVER
+
+    #ifdef TEST
+    fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
+    #endif
+
+#endif
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+	eltptr = &clientTable[cid].elements;
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id)
+	    {
+		RESTYPE rtype = res->type;
+		*prev = res->next;
+		elements = --*eltptr;
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 1;
+                #endif
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (rtype != skipDeleteFuncType)
+		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+		xfree(res);
+		if (*eltptr != elements)
+		    prev = head; /* prev may no longer be valid */
+		gotOne = TRUE;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+    if (!gotOne)
+	ErrorF("Freeing resource id=%lX which isn't there.\n",
+		   (unsigned long)id);
+}
+
+
+void
+FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
+{
+    int		cid;
+    register    ResourcePtr res;
+    register	ResourcePtr *prev, *head;
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	head = &clientTable[cid].resources[Hash(cid, id)];
+
+	prev = head;
+	while ( (res = *prev) )
+	{
+	    if (res->id == id && res->type == type)
+	    {
+		*prev = res->next;
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 1;
+                #endif
+		if (type & RC_CACHED)
+		    FlushClientCaches(res->id);
+		if (!skipFree)
+		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+		xfree(res);
+		break;
+	    }
+	    else
+		prev = &res->next;
+        }
+	if(clients[cid] && (id == clients[cid]->lastDrawableID))
+	{
+	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
+	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
+	}
+    }
+}
+
+/*
+ * Change the value associated with a resource id.  Caller
+ * is responsible for "doing the right thing" with the old
+ * data
+ */
+
+Bool
+ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(res->id);
+		res->value = value;
+		return TRUE;
+	    }
+    }
+    return FALSE;
+}
+
+/* Note: if func adds or deletes resources, then func can get called
+ * more than once for some resources.  If func adds new resources,
+ * func might or might not get called for them.  func cannot both
+ * add and delete an equal number of resources!
+ */
+
+void
+FindClientResourcesByType(
+    ClientPtr client,
+    RESTYPE type,
+    FindResType func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    #ifdef NXAGENT_SERVER
+    register ResourcePtr **resptr;
+    #endif
+
+    if (!client)
+	client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++) 
+    {
+        for (this = resources[i]; this; this = next)
+	{
+	    next = this->next;
+	    if (!type || this->type == type) {
+		elements = *eltptr;
+
+                /*
+                 * FIXME:
+                 * It is not safe to let a function change the resource
+                 * table we are reading!
+                 */
+
+                #ifdef NXAGENT_SERVER
+                nxagentResChangedFlag = 0;
+                #endif
+		(*func)(this->value, this->id, cdata);
+
+                /*
+                 * Avoid that a call to RebuildTable() could invalidate the
+                 * pointer. This is safe enough, because in RebuildTable()
+                 * the new pointer is allocated just before the old one is
+                 * freed, so it can't point to the same address.
+                 */
+
+                #ifdef NXAGENT_SERVER
+                if (*resptr != resources)
+                   goto RestartLoop;
+                #endif
+
+                /*
+                 * It's not enough to check if the number of elements has
+                 * changed, beacause it could happen that the number of
+                 * resources that have been added matches the number of
+                 * the freed ones.
+                 * 'nxagentResChangedFlag' is set if a resource has been
+                 * added or freed.
+                 */
+
+                #ifdef NXAGENT_SERVER
+                if (*eltptr != elements || nxagentResChangedFlag)
+                #else
+		if (*eltptr != elements)
+                #endif
+		    next = resources[i]; /* start over */
+	    }
+	}
+    }
+}
+
+void
+FindAllClientResources(
+    ClientPtr client,
+    FindAllRes func,
+    pointer cdata
+){
+    register ResourcePtr *resources;
+    register ResourcePtr this, next;
+    int i, elements;
+    register int *eltptr;
+
+    #ifdef NXAGENT_SERVER
+    register ResourcePtr **resptr;
+    #endif
+
+    if (!client)
+        client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    eltptr = &clientTable[client->index].elements;
+    for (i = 0; i < clientTable[client->index].buckets; i++)
+    {
+        for (this = resources[i]; this; this = next)
+        {
+            next = this->next;
+            elements = *eltptr;
+
+            /*
+             * FIXME:
+             * It is not safe to let a function change the resource
+             * table we are reading!
+             */
+
+            #ifdef NXAGENT_SERVER
+            nxagentResChangedFlag = 0;
+            #endif
+            (*func)(this->value, this->id, this->type, cdata);
+
+            /*
+             * Avoid that a call to RebuildTable() could invalidate the
+             * pointer. This is safe enough, because in RebuildTable()
+             * the new pointer is allocated just before the old one is
+             * freed, so it can't point to the same address.
+             */
+
+            #ifdef NXAGENT_SERVER
+            if (*resptr != resources)
+                goto RestartLoop;
+            #endif
+
+            /*
+             * It's not enough to check if the number of elements has
+             * changed, beacause it could happen that the number of
+             * resources that have been added matches the number of
+             * the freed ones.
+             * 'nxagentResChangedFlag' is set if a resource has been
+             * added or freed.
+             */
+
+            #ifdef NXAGENT_SERVER
+            if (*eltptr != elements || nxagentResChangedFlag)
+            #else
+            if (*eltptr != elements)
+            #endif
+                next = resources[i]; /* start over */
+        }
+    }
+}
+
+
+pointer
+LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata
+){
+    ResourcePtr *resources;
+    ResourcePtr this;
+    int i;
+
+    #ifdef NXAGENT_SERVER
+    ResourcePtr **resptr;
+    Bool res;
+    #endif
+
+    if (!client)
+	client = serverClient;
+
+/*
+ * If func triggers a resource table
+ * rebuild then restart the loop.
+ */
+
+#ifdef NXAGENT_SERVER
+RestartLoop:
+#endif
+
+    resources = clientTable[client->index].resources;
+
+    #ifdef NXAGENT_SERVER
+    resptr = &clientTable[client->index].resources;
+    #endif
+
+    for (i = 0; i < clientTable[client->index].buckets; i++) {
+        for (this = resources[i]; this; this = this->next) {
+	    if (!type || this->type == type) {
+                #ifdef NXAGENT_SERVER
+                res = (*func)(this->value, this->id, cdata);
+
+                if (*resptr != resources)
+                    goto RestartLoop;
+
+                if (res)
+                    return this->value;
+                #else
+		if((*func)(this->value, this->id, cdata))
+		    return this->value;
+                #endif
+	    }
+	}
+    }
+    return NULL;
+}
+
+
+void
+FreeClientNeverRetainResources(ClientPtr client)
+{
+    ResourcePtr *resources;
+    ResourcePtr this;
+    ResourcePtr *prev;
+    int j;
+
+    if (!client)
+	return;
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+	prev = &resources[j];
+        while ( (this = *prev) )
+	{
+	    RESTYPE rtype = this->type;
+	    if (rtype & RC_NEVERRETAIN)
+	    {
+		*prev = this->next;
+		if (rtype & RC_CACHED)
+		    FlushClientCaches(this->id);
+		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+		xfree(this);	    
+	    }
+	    else
+		prev = &this->next;
+	}
+    }
+}
+
+void
+FreeClientResources(ClientPtr client)
+{
+    register ResourcePtr *resources;
+    register ResourcePtr this;
+    int j;
+
+    /* This routine shouldn't be called with a null client, but just in
+	case ... */
+
+    if (!client)
+	return;
+
+    HandleSaveSet(client);
+
+    resources = clientTable[client->index].resources;
+    for (j=0; j < clientTable[client->index].buckets; j++) 
+    {
+        /* It may seem silly to update the head of this resource list as
+	we delete the members, since the entire list will be deleted any way, 
+	but there are some resource deletion functions "FreeClientPixels" for 
+	one which do a LookupID on another resource id (a Colormap id in this
+	case), so the resource list must be kept valid up to the point that
+	it is deleted, so every time we delete a resource, we must update the
+	head, just like in FreeResource. I hope that this doesn't slow down
+	mass deletion appreciably. PRH */
+
+	ResourcePtr *head;
+
+	head = &resources[j];
+
+        for (this = *head; this; this = *head)
+	{
+	    RESTYPE rtype = this->type;
+	    *head = this->next;
+	    if (rtype & RC_CACHED)
+		FlushClientCaches(this->id);
+	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+	    xfree(this);	    
+	}
+    }
+    xfree(clientTable[client->index].resources);
+    clientTable[client->index].resources = NULL;
+    clientTable[client->index].buckets = 0;
+}
+
+void
+FreeAllResources()
+{
+    int	i;
+
+    for (i = currentMaxClients; --i >= 0; ) 
+    {
+        if (clientTable[i].buckets) 
+	    FreeClientResources(clients[i]);
+    }
+}
+
+Bool
+LegalNewID(XID id, register ClientPtr client)
+{
+
+#ifdef PANORAMIX
+    XID 	minid, maxid;
+
+	if (!noPanoramiXExtension) { 
+	    minid = client->clientAsMask | (client->index ? 
+			                    SERVER_BIT : SERVER_MINID);
+	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
+            if ((id >= minid) && (id <= maxid))
+	        return TRUE;
+	}
+#endif /* PANORAMIX */
+	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
+	    ((clientTable[client->index].expectID <= id) ||
+	     !LookupIDByClass(id, RC_ANY)));
+}
+
+#ifdef XCSECURITY
+
+/* SecurityLookupIDByType and SecurityLookupIDByClass:
+ * These are the heart of the resource ID security system.  They take
+ * two additional arguments compared to the old LookupID functions:
+ * the client doing the lookup, and the access mode (see resource.h).
+ * The resource is returned if it exists and the client is allowed access,
+ * else NULL is returned.
+ */
+
+pointer
+SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
+{
+    int    cid;
+    register    ResourcePtr res;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert( (rtype & TypeMask) <= lastResourceType);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
+    return retval;
+}
+
+
+pointer
+SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
+{
+    int    cid;
+    register ResourcePtr res = NULL;
+    pointer retval = NULL;
+
+    assert(client == NullClient ||
+     (client->index <= currentMaxClients && clients[client->index] == client));
+    assert (classes >= lastResourceClass);
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+	    {
+		retval = res->value;
+		break;
+	    }
+    }
+    if (retval && client && client->CheckAccess)
+	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
+    return retval;
+}
+
+/* We can't replace the LookupIDByType and LookupIDByClass functions with
+ * macros because of compatibility with loadable servers.
+ */
+
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    return SecurityLookupIDByType(NullClient, id, rtype,
+				  SecurityUnknownAccess);
+}
+
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    return SecurityLookupIDByClass(NullClient, id, classes,
+				   SecurityUnknownAccess);
+}
+
+#else /* not XCSECURITY */
+
+/*
+ *  LookupIDByType returns the object with the given id and type, else NULL.
+ */ 
+pointer
+LookupIDByType(XID id, RESTYPE rtype)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type == rtype))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+/*
+ *  LookupIDByClass returns the object with the given id and any one of the
+ *  given classes, else NULL.
+ */ 
+pointer
+LookupIDByClass(XID id, RESTYPE classes)
+{
+    int    cid;
+    register    ResourcePtr res;
+
+    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
+	clientTable[cid].buckets)
+    {
+	res = clientTable[cid].resources[Hash(cid, id)];
+
+	for (; res; res = res->next)
+	    if ((res->id == id) && (res->type & classes))
+		return res->value;
+    }
+    return (pointer)NULL;
+}
+
+#endif /* XCSECURITY */
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index a6d638ea7..e3e4f4b83 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -967,17 +967,8 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    /* 
-     * There's a potential integer overflow in this check:
-     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-     *                client);
-     * the version below ought to avoid it
-     */
-    if (stuff->totalHeight != 0 && 
-	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
-	client->errorValue = stuff->totalWidth;
-	return BadValue;
-    }
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index a6d638ea7..e3e4f4b83 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -967,17 +967,8 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    /* 
-     * There's a potential integer overflow in this check:
-     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-     *                client);
-     * the version below ought to avoid it
-     */
-    if (stuff->totalHeight != 0 && 
-	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
-	client->errorValue = stuff->totalWidth;
-	return BadValue;
-    }
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
index f25bb9b5d..e2cf8cd24 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
@@ -863,17 +863,8 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    /* 
-     * There's a potential integer overflow in this check:
-     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-     *                client);
-     * the version below ought to avoid it
-     */
-    if (stuff->totalHeight != 0 && 
-	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
-	client->errorValue = stuff->totalWidth;
-	return BadValue;
-    }
+    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+		   client);
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
-- 
cgit v1.2.3


From c9983230f1f37db868f628856122739566a9286d Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:55 +0200
Subject: Imported nxagent-3.2.0-6.tar.gz

Summary: Imported nxagent-3.2.0-6.tar.gz
Keywords:

Imported nxagent-3.2.0-6.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG |  9 +++++
 nx-X11/programs/Xserver/hw/nxagent/Events.c  | 56 +++-------------------------
 nx-X11/programs/Xserver/hw/nxagent/Image.c   |  2 +-
 3 files changed, 15 insertions(+), 52 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 4d930b9b5..e3b71e645 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,14 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 90fb7641b..b37d81adf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -2261,7 +2261,11 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         {
           pScreen = nxagentScreen(X -> xmap.window);
 
-          nxagentMaximizeToFullScreen(pScreen);
+          XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+          XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                             DefaultScreen(nxagentDisplay));
+
         }
 
         if (X -> xclient.window == (nxagentOption(Fullscreen) ?
@@ -3058,56 +3062,6 @@ int nxagentHandleReparentNotify(XEvent* X)
 
     return 1;
   }
-  else
-  {
-    /*
-     * This code is supposed to detect if a window manager
-     * is running but in some cases it may be unreliable.
-     * Each window manager behaves differently so the check
-     * can fail for some less common WMs.
-     */
-
-    if (!nxagentWMIsRunning && nxagentOption(Fullscreen) &&
-            X -> xreparent.window == nxagentDefaultWindows[pScreen -> myNum])
-    {
-      #ifdef WARNING
-      fprintf(stderr, "Warning: The agent window was reparented. Is a "
-                  "window manager running?\n");
-      #endif
-
-      /*
-       * If no window manager is running and we are supposed to
-       * be in fullscreen mode then don't wait for the reparent
-       * event. We can assume that there is an undetected window
-       * manager and, as switching to fullscreen could have fail-
-       * ed, we try it again.
-       */
-
-      nxagentSwitchFullscreen(pScreen, True);
-
-      nxagentWMIsRunning = True;
-    }
-    else if (nxagentWMIsRunning && X -> xreparent.window ==
-                 nxagentDefaultWindows[pScreen -> myNum] && X -> xreparent.parent ==
-                     RootWindow(nxagentDisplay, (pScreen -> myNum)))
-    {
-      #ifdef WARNING
-
-      fprintf(stderr, "Warning: The agent window has been reparented to the root.\n");
-
-      fprintf(stderr, "Warning: No window manager seems to be running.\n");
-
-      #endif
-
-      /*
-       * The agent window was unexpectedly reparented
-       * to the root window. We assume that the window
-       * manager was terminated.
-       */
-
-      nxagentWMIsRunning = False;
-    }
-  }
 
   return 1;
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index 5b40f32e9..4e08f6bf1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -1176,7 +1176,7 @@ FIXME: Should use an unpack resource here.
    */
 
   pack = (nxagentOption(LinkType) != LINK_TYPE_NONE &&
-              packMethod != PACK_NONE && depth > 8);
+              packMethod != PACK_NONE && depth > 8 && format == ZPixmap);
 
   lossless = (packMethod == nxagentPackLossless);
 
-- 
cgit v1.2.3


From c4e7705d299fcfc058baaa0867e1a1e29d626c6f Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:55 +0200
Subject: Imported nxagent-3.2.0-7.tar.gz

Summary: Imported nxagent-3.2.0-7.tar.gz
Keywords:

Imported nxagent-3.2.0-7.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |    7 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   19 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   19 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.X.original      |   14 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |   18 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |   18 +-
 .../Xserver/hw/nxagent/X/NXrender.c.X.original     |   18 +-
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |    8 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~ | 1250 --------------------
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   13 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   13 +-
 .../Xserver/hw/nxagent/X/NXshm.c.X.original        |   13 +-
 12 files changed, 132 insertions(+), 1278 deletions(-)
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index e3b71e645..7cf04acc0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,12 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index 06dabddaa..f51a8bce9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -69,6 +69,17 @@
 #undef  DEBUG
 #undef  TEST
 
+#else
+
+#include "picturestr.h"
+#include "glyphstr.h"
+
+#endif
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
 #endif
 
 /*
@@ -401,8 +412,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-
-    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    size_t	     padded_width;
+    
+    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
+	return 0;
+    size = gi->height * padded_width;
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index 06dabddaa..f51a8bce9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -69,6 +69,17 @@
 #undef  DEBUG
 #undef  TEST
 
+#else
+
+#include "picturestr.h"
+#include "glyphstr.h"
+
+#endif
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
 #endif
 
 /*
@@ -401,8 +412,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-
-    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    size_t	     padded_width;
+    
+    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
+	return 0;
+    size = gi->height * padded_width;
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
index 45c5dd975..9f4d1c87b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.X.original
@@ -43,6 +43,12 @@
 #include "picturestr.h"
 #include "glyphstr.h"
 
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif !defined(UINT32_MAX)
+#define UINT32_MAX 0xffffffffU
+#endif
+
 /*
  * From Knuth -- a good choice for hash/rehash values is p, p-2 where
  * p and p-2 are both prime.  These tables are sized to have an extra 10%
@@ -334,8 +340,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
 {
     int		size;
     GlyphPtr	glyph;
-
-    size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    size_t	     padded_width;
+    
+    padded_width = PixmapBytePad (gi->width, glyphDepths[fdepth]);
+    if (gi->height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi->height)
+	return 0;
+    size = gi->height * padded_width;
     glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec));
     if (!glyph)
 	return 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index 00c55cde7..de2df855f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -1893,6 +1893,8 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
+    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -2353,6 +2355,8 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2955,18 +2959,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int n)
+static void swapStops(void *stuff, int num)
 {
-    int i;
+    int i, n;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < n; ++i) {
+    for (i = 0; i < num; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*n; ++i) {
+    for (i = 0; i < 4*num; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2989,6 +2993,8 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3016,6 +3022,8 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3040,6 +3048,8 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index 00c55cde7..de2df855f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -1893,6 +1893,8 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
+    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -2353,6 +2355,8 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2955,18 +2959,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int n)
+static void swapStops(void *stuff, int num)
 {
-    int i;
+    int i, n;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < n; ++i) {
+    for (i = 0; i < num; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*n; ++i) {
+    for (i = 0; i < 4*num; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2989,6 +2993,8 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3016,6 +3022,8 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -3040,6 +3048,8 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
index d2759ab10..d25d49756 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.X.original
@@ -1505,6 +1505,8 @@ ProcRenderCreateCursor (ClientPtr client)
     pScreen = pSrc->pDrawable->pScreen;
     width = pSrc->pDrawable->width;
     height = pSrc->pDrawable->height;
+    if (height && width > UINT32_MAX/(height*sizeof(CARD32)))
+	return BadAlloc;
     if ( stuff->x > width 
       || stuff->y > height )
 	return (BadMatch);
@@ -1918,6 +1920,8 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
     LEGAL_NEW_RESOURCE(stuff->pid, client);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2489,18 +2493,18 @@ SProcRenderCreateSolidFill(ClientPtr client)
     return (*ProcRenderVector[stuff->renderReqType]) (client);
 }
 
-static void swapStops(void *stuff, int n)
+static void swapStops(void *stuff, int num)
 {
-    int i;
+    int i, n;
     CARD32 *stops;
     CARD16 *colors;
     stops = (CARD32 *)(stuff);
-    for (i = 0; i < n; ++i) {
+    for (i = 0; i < num; ++i) {
         swapl(stops, n);
         ++stops;
     }
     colors = (CARD16 *)(stops);
-    for (i = 0; i < 4*n; ++i) {
+    for (i = 0; i < 4*num; ++i) {
         swaps(stops, n);
         ++stops;
     }
@@ -2523,6 +2527,8 @@ SProcRenderCreateLinearGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2550,6 +2556,8 @@ SProcRenderCreateRadialGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
@@ -2574,6 +2582,8 @@ SProcRenderCreateConicalGradient (ClientPtr client)
     swapl(&stuff->nStops, n);
 
     len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq);
+    if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor)))
+	return BadLength;
     if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor)))
         return BadLength;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index 7dd021a6e..91e03cb0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -194,10 +194,6 @@ static DeleteType *DeleteFuncs = (DeleteType *)NULL;
 
 Atom * ResourceNames = NULL;
 
-#ifdef NXAGENT_SERVER
-static int nxagentResChangedFlag = 0;
-#endif
-
 void RegisterResourceName (RESTYPE type, char *name)
 {
     ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
@@ -205,6 +201,10 @@ void RegisterResourceName (RESTYPE type, char *name)
 
 #endif
 
+#ifdef NXAGENT_SERVER
+static int nxagentResChangedFlag = 0;
+#endif
+
 RESTYPE
 CreateNewResourceType(DeleteType deleteFunc)
 {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~
deleted file mode 100644
index 7dd021a6e..000000000
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c~
+++ /dev/null
@@ -1,1250 +0,0 @@
-/**************************************************************************/
-/*                                                                        */
-/* Copyright (c) 2001, 2007 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 NoMachine S.r.l.                    */
-/*                                                                        */
-/* All rights reserved.                                                   */
-/*                                                                        */
-/**************************************************************************/
-
-/************************************************************
-
-Copyright 1987, 1998  The Open Group
-
-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.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-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 Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL 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 panoramix components contained the following notice */
-/*****************************************************************
-
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-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
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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.
-
-Except as contained in this notice, the name of Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-
-******************************************************************/
-
-/* $Xorg: resource.c,v 1.5 2001/02/09 02:04:40 xorgcvs Exp $ */
-/* $XdotOrg: xc/programs/Xserver/dix/resource.c,v 1.8 2005/07/03 08:53:38 daniels Exp $ */
-/* $TOG: resource.c /main/41 1998/02/09 14:20:31 kaleb $ */
-
-/*	Routines to manage various kinds of resources:
- *
- *	CreateNewResourceType, CreateNewResourceClass, InitClientResources,
- *	FakeClientID, AddResource, FreeResource, FreeClientResources,
- *	FreeAllResources, LookupIDByType, LookupIDByClass, GetXIDRange
- */
-
-/* 
- *      A resource ID is a 32 bit quantity, the upper 2 bits of which are
- *	off-limits for client-visible resources.  The next 8 bits are
- *      used as client ID, and the low 22 bits come from the client.
- *	A resource ID is "hashed" by extracting and xoring subfields
- *      (varying with the size of the hash table).
- *
- *      It is sometimes necessary for the server to create an ID that looks
- *      like it belongs to a client.  This ID, however,  must not be one
- *      the client actually can create, or we have the potential for conflict.
- *      The 31st bit of the ID is reserved for the server's use for this
- *      purpose.  By setting CLIENT_ID(id) to the client, the SERVER_BIT to
- *      1, and an otherwise arbitrary ID in the low 22 bits, we can create a
- *      resource "owned" by the client.
- */
-/* $XFree86: xc/programs/Xserver/dix/resource.c,v 3.13 2003/09/24 02:43:13 dawes Exp $ */
-
-#define NEED_EVENTS
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include "misc.h"
-#include "os.h"
-#include "resource.h"
-#include "dixstruct.h" 
-#include "opaque.h"
-#include "windowstr.h"
-#include "dixfont.h"
-#include "colormap.h"
-#include "inputstr.h"
-#include "dixevents.h"
-#include "dixgrabs.h"
-#include "cursor.h"
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-#include <assert.h>
-
-#ifdef NXAGENT_SERVER
-
-#include "Agent.h"
-#include "Font.h"
-#include "Pixmaps.h"
-#include "GCs.h"
-
-#define PANIC
-#define WARNING
-#undef  TEST
-#undef  DEBUG
-
-#endif
-
-static void RebuildTable(
-    int /*client*/
-);
-
-#define SERVER_MINID 32
-
-#define INITBUCKETS 64
-#define INITHASHSIZE 6
-#define MAXHASHSIZE 11
-
-typedef struct _Resource {
-    struct _Resource	*next;
-    XID			id;
-    RESTYPE		type;
-    pointer		value;
-} ResourceRec, *ResourcePtr;
-#define NullResource ((ResourcePtr)NULL)
-
-typedef struct _ClientResource {
-    ResourcePtr *resources;
-    int		elements;
-    int		buckets;
-    int		hashsize;	/* log(2)(buckets) */
-    XID		fakeID;
-    XID		endFakeID;
-    XID		expectID;
-} ClientResourceRec;
-
-RESTYPE lastResourceType;
-static RESTYPE lastResourceClass;
-RESTYPE TypeMask;
-
-static DeleteType *DeleteFuncs = (DeleteType *)NULL;
-
-#ifdef XResExtension
-
-Atom * ResourceNames = NULL;
-
-#ifdef NXAGENT_SERVER
-static int nxagentResChangedFlag = 0;
-#endif
-
-void RegisterResourceName (RESTYPE type, char *name)
-{
-    ResourceNames[type & TypeMask] =  MakeAtom(name, strlen(name), TRUE);
-}
-
-#endif
-
-RESTYPE
-CreateNewResourceType(DeleteType deleteFunc)
-{
-    RESTYPE next = lastResourceType + 1;
-    DeleteType *funcs;
-
-    if (next & lastResourceClass)
-	return 0;
-    funcs = (DeleteType *)xrealloc(DeleteFuncs,
-				   (next + 1) * sizeof(DeleteType));
-    if (!funcs)
-	return 0;
-
-#ifdef XResExtension
-    {
-       Atom *newnames;
-       newnames = xrealloc(ResourceNames, (next + 1) * sizeof(Atom));
-       if(!newnames)
-           return 0;
-       ResourceNames = newnames;
-       ResourceNames[next] = 0;
-    }
-#endif
-
-    lastResourceType = next;
-    DeleteFuncs = funcs;
-    DeleteFuncs[next] = deleteFunc;
-    return next;
-}
-
-RESTYPE
-CreateNewResourceClass()
-{
-    RESTYPE next = lastResourceClass >> 1;
-
-    if (next & lastResourceType)
-	return 0;
-    lastResourceClass = next;
-    TypeMask = next - 1;
-    return next;
-}
-
-ClientResourceRec clientTable[MAXCLIENTS];
-
-/*****************
- * InitClientResources
- *    When a new client is created, call this to allocate space
- *    in resource table
- *****************/
-
-Bool
-InitClientResources(ClientPtr client)
-{
-    register int i, j;
- 
-    if (client == serverClient)
-    {
-	lastResourceType = RT_LASTPREDEF;
-	lastResourceClass = RC_LASTPREDEF;
-	TypeMask = RC_LASTPREDEF - 1;
-	if (DeleteFuncs)
-	    xfree(DeleteFuncs);
-	DeleteFuncs = (DeleteType *)xalloc((lastResourceType + 1) *
-					   sizeof(DeleteType));
-	if (!DeleteFuncs)
-	    return FALSE;
-	DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
-	DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
-	DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
-	DeleteFuncs[RT_GC & TypeMask] = FreeGC;
-	DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
-	DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
-	DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
-	DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
-	DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
-	DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
-
-#ifdef XResExtension
-        if(ResourceNames)
-            xfree(ResourceNames);
-        ResourceNames = xalloc((lastResourceType + 1) * sizeof(Atom));
-        if(!ResourceNames)
-           return FALSE;
-#endif
-    }
-    clientTable[i = client->index].resources =
-	(ResourcePtr *)xalloc(INITBUCKETS*sizeof(ResourcePtr));
-    if (!clientTable[i].resources)
-	return FALSE;
-    clientTable[i].buckets = INITBUCKETS;
-    clientTable[i].elements = 0;
-    clientTable[i].hashsize = INITHASHSIZE;
-    /* Many IDs allocated from the server client are visible to clients,
-     * so we don't use the SERVER_BIT for them, but we have to start
-     * past the magic value constants used in the protocol.  For normal
-     * clients, we can start from zero, with SERVER_BIT set.
-     */
-    clientTable[i].fakeID = client->clientAsMask |
-			    (client->index ? SERVER_BIT : SERVER_MINID);
-    clientTable[i].endFakeID = (clientTable[i].fakeID | RESOURCE_ID_MASK) + 1;
-    clientTable[i].expectID = client->clientAsMask;
-    for (j=0; j<INITBUCKETS; j++) 
-    {
-        clientTable[i].resources[j] = NullResource;
-    }
-    return TRUE;
-}
-
-
-static int
-Hash(int client, register XID id)
-{
-    id &= RESOURCE_ID_MASK;
-    switch (clientTable[client].hashsize)
-    {
-	case 6:
-	    return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12))));
-	case 7:
-	    return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13))));
-	case 8:
-	    return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16))));
-	case 9:
-	    return ((int)(0x1FF & (id ^ (id>>9))));
-	case 10:
-	    return ((int)(0x3FF & (id ^ (id>>10))));
-	case 11:
-	    return ((int)(0x7FF & (id ^ (id>>11))));
-    }
-    return -1;
-}
-
-static XID
-AvailableID(
-    register int client,
-    register XID id,
-    register XID maxid,
-    register XID goodid)
-{
-    register ResourcePtr res;
-
-    if ((goodid >= id) && (goodid <= maxid))
-	return goodid;
-    for (; id <= maxid; id++)
-    {
-	res = clientTable[client].resources[Hash(client, id)];
-	while (res && (res->id != id))
-	    res = res->next;
-	if (!res)
-	    return id;
-    }
-    return 0;
-}
-
-void
-GetXIDRange(int client, Bool server, XID *minp, XID *maxp)
-{
-    register XID id, maxid;
-    register ResourcePtr *resp;
-    register ResourcePtr res;
-    register int i;
-    XID goodid;
-
-    id = (Mask)client << CLIENTOFFSET;
-    if (server)
-	id |= client ? SERVER_BIT : SERVER_MINID;
-    maxid = id | RESOURCE_ID_MASK;
-    goodid = 0;
-    for (resp = clientTable[client].resources, i = clientTable[client].buckets;
-	 --i >= 0;)
-    {
-	for (res = *resp++; res; res = res->next)
-	{
-	    if ((res->id < id) || (res->id > maxid))
-		continue;
-	    if (((res->id - id) >= (maxid - res->id)) ?
-		(goodid = AvailableID(client, id, res->id - 1, goodid)) :
-		!(goodid = AvailableID(client, res->id + 1, maxid, goodid)))
-		maxid = res->id - 1;
-	    else
-		id = res->id + 1;
-	}
-    }
-    if (id > maxid)
-	id = maxid = 0;
-    *minp = id;
-    *maxp = maxid;
-}
-
-/**
- *  GetXIDList is called by the XC-MISC extension's MiscGetXIDList function.
- *  This function tries to find count unused XIDs for the given client.  It 
- *  puts the IDs in the array pids and returns the number found, which should
- *  almost always be the number requested.
- *
- *  The circumstances that lead to a call to this function are very rare.
- *  Xlib must run out of IDs while trying to generate a request that wants
- *  multiple ID's, like the Multi-buffering CreateImageBuffers request.
- *
- *  No rocket science in the implementation; just iterate over all
- *  possible IDs for the given client and pick the first count IDs
- *  that aren't in use.  A more efficient algorithm could probably be
- *  invented, but this will be used so rarely that this should suffice.
- */
-
-unsigned int
-GetXIDList(ClientPtr pClient, unsigned count, XID *pids)
-{
-    unsigned int found = 0;
-    XID id = pClient->clientAsMask;
-    XID maxid;
-
-    maxid = id | RESOURCE_ID_MASK;
-    while ( (found < count) && (id <= maxid) )
-    {
-	if (!LookupIDByClass(id, RC_ANY))
-	{
-	    pids[found++] = id;
-	}
-	id++;
-    }
-    return found;
-}
-
-/*
- * Return the next usable fake client ID.
- *
- * Normally this is just the next one in line, but if we've used the last
- * in the range, we need to find a new range of safe IDs to avoid
- * over-running another client.
- */
-
-XID
-FakeClientID(register int client)
-{
-    XID id, maxid;
-
-    id = clientTable[client].fakeID++;
-    if (id != clientTable[client].endFakeID)
-	return id;
-    GetXIDRange(client, TRUE, &id, &maxid);
-    if (!id) {
-	if (!client)
-	    FatalError("FakeClientID: server internal ids exhausted\n");
-	MarkClientException(clients[client]);
-	id = ((Mask)client << CLIENTOFFSET) | (SERVER_BIT * 3);
-	maxid = id | RESOURCE_ID_MASK;
-    }
-    clientTable[client].fakeID = id + 1;
-    clientTable[client].endFakeID = maxid + 1;
-    return id;
-}
-
-#ifdef NXAGENT_SERVER
-
-int nxagentFindClientResource(int client, RESTYPE type, pointer value)
-{
-  ResourcePtr pResource;
-  ResourcePtr *resources;
-
-  int i;
-
-  for (i = 0; i < clientTable[client].buckets; i++)
-  {
-    resources = clientTable[client].resources;
-
-    for (pResource = resources[i]; pResource; pResource = pResource -> next)
-    {
-      if (pResource -> type == type && pResource -> value == value)
-      {
-        #ifdef TEST
-        fprintf(stderr, "nxagentFindClientResource: Found resource [%p] type [%lu] "
-                    "for client [%d].\n", (void *) value,
-                        pResource -> type, client);
-        #endif
-
-        return 1;
-      }
-    }
-  }
-
-  return 0;
-}
-
-int nxagentSwitchResourceType(int client, RESTYPE type, pointer value)
-{
-  ResourcePtr pResource;
-  ResourcePtr *resources;
-
-  RESTYPE internalType = 0;
-
-  int i;
-
-  if (type == RT_PIXMAP)
-  {
-    internalType = RT_NX_PIXMAP;
-  }
-  else if (type == RT_GC)
-  {
-    internalType = RT_NX_GC;
-  }
-  else if (type == RT_FONT)
-  {
-    internalType = RT_NX_FONT;
-  }
-  else
-  {
-    return 0;
-  }
-
-  if (client == serverClient -> index)
-  {
-    #ifdef TEST
-    fprintf(stderr, "nxagentSwitchResourceType: Requesting client is [%d]. Skipping the resource switch.\n",
-                client);
-    #endif
-
-    return 0;
-  }
-
-  for (i = 0; i < clientTable[serverClient -> index].buckets; i++)
-  {
-    resources = clientTable[serverClient -> index].resources;
-
-    for (pResource = resources[i]; pResource; pResource = pResource -> next)
-    {
-      if (pResource -> type == internalType &&
-              pResource -> value == value)
-      {
-        #ifdef TEST
-        fprintf(stderr, "nxagentSwitchResourceType: Changing resource [%p] type from [%lu] to "
-                    "[%lu] for server client [%d].\n", (void *) value,
-                        (unsigned long) pResource -> type, (unsigned long) type, serverClient -> index);
-        #endif
-
-        FreeResource(pResource -> id, RT_NONE);
-
-        return 1;
-      }
-    }
-  }
-
-  return 0;
-}
-
-#endif
-
-Bool
-AddResource(XID id, RESTYPE type, pointer value)
-{
-    int client;
-    register ClientResourceRec *rrec;
-    register ResourcePtr res, *head;
-
-    client = CLIENT_ID(id);
-    rrec = &clientTable[client];
-    if (!rrec->buckets)
-    {
-	ErrorF("AddResource(%lx, %lx, %lx), client=%d \n",
-		(unsigned long)id, type, (unsigned long)value, client);
-        FatalError("client not in use\n");
-    }
-
-#ifdef NXAGENT_SERVER
-
-    nxagentSwitchResourceType(client, type, value);
-
-    #ifdef TEST
-    fprintf(stderr, "AddResource: Adding resource for client [%d] type [%lu] value [%p] id [%lu].\n",
-                client, (unsigned long) type, (void *) value, (unsigned long) id);
-    #endif
-
-#endif
-
-    if ((rrec->elements >= 4*rrec->buckets) &&
-	(rrec->hashsize < MAXHASHSIZE))
-	RebuildTable(client);
-    head = &rrec->resources[Hash(client, id)];
-    res = (ResourcePtr)xalloc(sizeof(ResourceRec));
-    if (!res)
-    {
-	(*DeleteFuncs[type & TypeMask])(value, id);
-	return FALSE;
-    }
-    res->next = *head;
-    res->id = id;
-    res->type = type;
-    res->value = value;
-    *head = res;
-    rrec->elements++;
-    #ifdef NXAGENT_SERVER
-    nxagentResChangedFlag = 1;
-    #endif
-    if (!(id & SERVER_BIT) && (id >= rrec->expectID))
-	rrec->expectID = id + 1;
-    return TRUE;
-}
-
-static void
-RebuildTable(int client)
-{
-    register int j;
-    register ResourcePtr res, next;
-    ResourcePtr **tails, *resources;
-    register ResourcePtr **tptr, *rptr;
-
-    /*
-     * For now, preserve insertion order, since some ddx layers depend
-     * on resources being free in the opposite order they are added.
-     */
-
-    j = 2 * clientTable[client].buckets;
-    tails = (ResourcePtr **)ALLOCATE_LOCAL(j * sizeof(ResourcePtr *));
-    if (!tails)
-	return;
-    resources = (ResourcePtr *)xalloc(j * sizeof(ResourcePtr));
-    if (!resources)
-    {
-	DEALLOCATE_LOCAL(tails);
-	return;
-    }
-    for (rptr = resources, tptr = tails; --j >= 0; rptr++, tptr++)
-    {
-	*rptr = NullResource;
-	*tptr = rptr;
-    }
-    clientTable[client].hashsize++;
-    for (j = clientTable[client].buckets,
-	 rptr = clientTable[client].resources;
-	 --j >= 0;
-	 rptr++)
-    {
-	for (res = *rptr; res; res = next)
-	{
-	    next = res->next;
-	    res->next = NullResource;
-	    tptr = &tails[Hash(client, res->id)];
-	    **tptr = res;
-	    *tptr = &res->next;
-	}
-    }
-    DEALLOCATE_LOCAL(tails);
-    clientTable[client].buckets *= 2;
-    xfree(clientTable[client].resources);
-    clientTable[client].resources = resources;
-}
-
-void
-FreeResource(XID id, RESTYPE skipDeleteFuncType)
-{
-    int		cid;
-    register    ResourcePtr res;
-    register	ResourcePtr *prev, *head;
-    register	int *eltptr;
-    int		elements;
-    Bool	gotOne = FALSE;
-
-#ifdef NXAGENT_SERVER
-
-    #ifdef TEST
-    fprintf(stderr, "FreeResource: Freeing resource id [%lu].\n", (unsigned long) id);
-    #endif
-
-#endif
-
-    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
-    {
-	head = &clientTable[cid].resources[Hash(cid, id)];
-	eltptr = &clientTable[cid].elements;
-
-	prev = head;
-	while ( (res = *prev) )
-	{
-	    if (res->id == id)
-	    {
-		RESTYPE rtype = res->type;
-		*prev = res->next;
-		elements = --*eltptr;
-                #ifdef NXAGENT_SERVER
-                nxagentResChangedFlag = 1;
-                #endif
-		if (rtype & RC_CACHED)
-		    FlushClientCaches(res->id);
-		if (rtype != skipDeleteFuncType)
-		    (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
-		xfree(res);
-		if (*eltptr != elements)
-		    prev = head; /* prev may no longer be valid */
-		gotOne = TRUE;
-	    }
-	    else
-		prev = &res->next;
-        }
-	if(clients[cid] && (id == clients[cid]->lastDrawableID))
-	{
-	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
-	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
-	}
-    }
-    if (!gotOne)
-	ErrorF("Freeing resource id=%lX which isn't there.\n",
-		   (unsigned long)id);
-}
-
-
-void
-FreeResourceByType(XID id, RESTYPE type, Bool skipFree)
-{
-    int		cid;
-    register    ResourcePtr res;
-    register	ResourcePtr *prev, *head;
-    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
-    {
-	head = &clientTable[cid].resources[Hash(cid, id)];
-
-	prev = head;
-	while ( (res = *prev) )
-	{
-	    if (res->id == id && res->type == type)
-	    {
-		*prev = res->next;
-                #ifdef NXAGENT_SERVER
-                nxagentResChangedFlag = 1;
-                #endif
-		if (type & RC_CACHED)
-		    FlushClientCaches(res->id);
-		if (!skipFree)
-		    (*DeleteFuncs[type & TypeMask])(res->value, res->id);
-		xfree(res);
-		break;
-	    }
-	    else
-		prev = &res->next;
-        }
-	if(clients[cid] && (id == clients[cid]->lastDrawableID))
-	{
-	    clients[cid]->lastDrawable = (DrawablePtr)WindowTable[0];
-	    clients[cid]->lastDrawableID = WindowTable[0]->drawable.id;
-	}
-    }
-}
-
-/*
- * Change the value associated with a resource id.  Caller
- * is responsible for "doing the right thing" with the old
- * data
- */
-
-Bool
-ChangeResourceValue (XID id, RESTYPE rtype, pointer value)
-{
-    int    cid;
-    register    ResourcePtr res;
-
-    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets)
-    {
-	res = clientTable[cid].resources[Hash(cid, id)];
-
-	for (; res; res = res->next)
-	    if ((res->id == id) && (res->type == rtype))
-	    {
-		if (rtype & RC_CACHED)
-		    FlushClientCaches(res->id);
-		res->value = value;
-		return TRUE;
-	    }
-    }
-    return FALSE;
-}
-
-/* Note: if func adds or deletes resources, then func can get called
- * more than once for some resources.  If func adds new resources,
- * func might or might not get called for them.  func cannot both
- * add and delete an equal number of resources!
- */
-
-void
-FindClientResourcesByType(
-    ClientPtr client,
-    RESTYPE type,
-    FindResType func,
-    pointer cdata
-){
-    register ResourcePtr *resources;
-    register ResourcePtr this, next;
-    int i, elements;
-    register int *eltptr;
-
-    #ifdef NXAGENT_SERVER
-    register ResourcePtr **resptr;
-    #endif
-
-    if (!client)
-	client = serverClient;
-
-/*
- * If func triggers a resource table
- * rebuild then restart the loop.
- */
-
-#ifdef NXAGENT_SERVER
-RestartLoop:
-#endif
-
-    resources = clientTable[client->index].resources;
-
-    #ifdef NXAGENT_SERVER
-    resptr = &clientTable[client->index].resources;
-    #endif
-
-    eltptr = &clientTable[client->index].elements;
-    for (i = 0; i < clientTable[client->index].buckets; i++) 
-    {
-        for (this = resources[i]; this; this = next)
-	{
-	    next = this->next;
-	    if (!type || this->type == type) {
-		elements = *eltptr;
-
-                /*
-                 * FIXME:
-                 * It is not safe to let a function change the resource
-                 * table we are reading!
-                 */
-
-                #ifdef NXAGENT_SERVER
-                nxagentResChangedFlag = 0;
-                #endif
-		(*func)(this->value, this->id, cdata);
-
-                /*
-                 * Avoid that a call to RebuildTable() could invalidate the
-                 * pointer. This is safe enough, because in RebuildTable()
-                 * the new pointer is allocated just before the old one is
-                 * freed, so it can't point to the same address.
-                 */
-
-                #ifdef NXAGENT_SERVER
-                if (*resptr != resources)
-                   goto RestartLoop;
-                #endif
-
-                /*
-                 * It's not enough to check if the number of elements has
-                 * changed, beacause it could happen that the number of
-                 * resources that have been added matches the number of
-                 * the freed ones.
-                 * 'nxagentResChangedFlag' is set if a resource has been
-                 * added or freed.
-                 */
-
-                #ifdef NXAGENT_SERVER
-                if (*eltptr != elements || nxagentResChangedFlag)
-                #else
-		if (*eltptr != elements)
-                #endif
-		    next = resources[i]; /* start over */
-	    }
-	}
-    }
-}
-
-void
-FindAllClientResources(
-    ClientPtr client,
-    FindAllRes func,
-    pointer cdata
-){
-    register ResourcePtr *resources;
-    register ResourcePtr this, next;
-    int i, elements;
-    register int *eltptr;
-
-    #ifdef NXAGENT_SERVER
-    register ResourcePtr **resptr;
-    #endif
-
-    if (!client)
-        client = serverClient;
-
-/*
- * If func triggers a resource table
- * rebuild then restart the loop.
- */
-
-#ifdef NXAGENT_SERVER
-RestartLoop:
-#endif
-
-    resources = clientTable[client->index].resources;
-
-    #ifdef NXAGENT_SERVER
-    resptr = &clientTable[client->index].resources;
-    #endif
-
-    eltptr = &clientTable[client->index].elements;
-    for (i = 0; i < clientTable[client->index].buckets; i++)
-    {
-        for (this = resources[i]; this; this = next)
-        {
-            next = this->next;
-            elements = *eltptr;
-
-            /*
-             * FIXME:
-             * It is not safe to let a function change the resource
-             * table we are reading!
-             */
-
-            #ifdef NXAGENT_SERVER
-            nxagentResChangedFlag = 0;
-            #endif
-            (*func)(this->value, this->id, this->type, cdata);
-
-            /*
-             * Avoid that a call to RebuildTable() could invalidate the
-             * pointer. This is safe enough, because in RebuildTable()
-             * the new pointer is allocated just before the old one is
-             * freed, so it can't point to the same address.
-             */
-
-            #ifdef NXAGENT_SERVER
-            if (*resptr != resources)
-                goto RestartLoop;
-            #endif
-
-            /*
-             * It's not enough to check if the number of elements has
-             * changed, beacause it could happen that the number of
-             * resources that have been added matches the number of
-             * the freed ones.
-             * 'nxagentResChangedFlag' is set if a resource has been
-             * added or freed.
-             */
-
-            #ifdef NXAGENT_SERVER
-            if (*eltptr != elements || nxagentResChangedFlag)
-            #else
-            if (*eltptr != elements)
-            #endif
-                next = resources[i]; /* start over */
-        }
-    }
-}
-
-
-pointer
-LookupClientResourceComplex(
-    ClientPtr client,
-    RESTYPE type,
-    FindComplexResType func,
-    pointer cdata
-){
-    ResourcePtr *resources;
-    ResourcePtr this;
-    int i;
-
-    #ifdef NXAGENT_SERVER
-    ResourcePtr **resptr;
-    Bool res;
-    #endif
-
-    if (!client)
-	client = serverClient;
-
-/*
- * If func triggers a resource table
- * rebuild then restart the loop.
- */
-
-#ifdef NXAGENT_SERVER
-RestartLoop:
-#endif
-
-    resources = clientTable[client->index].resources;
-
-    #ifdef NXAGENT_SERVER
-    resptr = &clientTable[client->index].resources;
-    #endif
-
-    for (i = 0; i < clientTable[client->index].buckets; i++) {
-        for (this = resources[i]; this; this = this->next) {
-	    if (!type || this->type == type) {
-                #ifdef NXAGENT_SERVER
-                res = (*func)(this->value, this->id, cdata);
-
-                if (*resptr != resources)
-                    goto RestartLoop;
-
-                if (res)
-                    return this->value;
-                #else
-		if((*func)(this->value, this->id, cdata))
-		    return this->value;
-                #endif
-	    }
-	}
-    }
-    return NULL;
-}
-
-
-void
-FreeClientNeverRetainResources(ClientPtr client)
-{
-    ResourcePtr *resources;
-    ResourcePtr this;
-    ResourcePtr *prev;
-    int j;
-
-    if (!client)
-	return;
-
-    resources = clientTable[client->index].resources;
-    for (j=0; j < clientTable[client->index].buckets; j++) 
-    {
-	prev = &resources[j];
-        while ( (this = *prev) )
-	{
-	    RESTYPE rtype = this->type;
-	    if (rtype & RC_NEVERRETAIN)
-	    {
-		*prev = this->next;
-		if (rtype & RC_CACHED)
-		    FlushClientCaches(this->id);
-		(*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
-		xfree(this);	    
-	    }
-	    else
-		prev = &this->next;
-	}
-    }
-}
-
-void
-FreeClientResources(ClientPtr client)
-{
-    register ResourcePtr *resources;
-    register ResourcePtr this;
-    int j;
-
-    /* This routine shouldn't be called with a null client, but just in
-	case ... */
-
-    if (!client)
-	return;
-
-    HandleSaveSet(client);
-
-    resources = clientTable[client->index].resources;
-    for (j=0; j < clientTable[client->index].buckets; j++) 
-    {
-        /* It may seem silly to update the head of this resource list as
-	we delete the members, since the entire list will be deleted any way, 
-	but there are some resource deletion functions "FreeClientPixels" for 
-	one which do a LookupID on another resource id (a Colormap id in this
-	case), so the resource list must be kept valid up to the point that
-	it is deleted, so every time we delete a resource, we must update the
-	head, just like in FreeResource. I hope that this doesn't slow down
-	mass deletion appreciably. PRH */
-
-	ResourcePtr *head;
-
-	head = &resources[j];
-
-        for (this = *head; this; this = *head)
-	{
-	    RESTYPE rtype = this->type;
-	    *head = this->next;
-	    if (rtype & RC_CACHED)
-		FlushClientCaches(this->id);
-	    (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
-	    xfree(this);	    
-	}
-    }
-    xfree(clientTable[client->index].resources);
-    clientTable[client->index].resources = NULL;
-    clientTable[client->index].buckets = 0;
-}
-
-void
-FreeAllResources()
-{
-    int	i;
-
-    for (i = currentMaxClients; --i >= 0; ) 
-    {
-        if (clientTable[i].buckets) 
-	    FreeClientResources(clients[i]);
-    }
-}
-
-Bool
-LegalNewID(XID id, register ClientPtr client)
-{
-
-#ifdef PANORAMIX
-    XID 	minid, maxid;
-
-	if (!noPanoramiXExtension) { 
-	    minid = client->clientAsMask | (client->index ? 
-			                    SERVER_BIT : SERVER_MINID);
-	    maxid = (clientTable[client->index].fakeID | RESOURCE_ID_MASK) + 1;
-            if ((id >= minid) && (id <= maxid))
-	        return TRUE;
-	}
-#endif /* PANORAMIX */
-	return ((client->clientAsMask == (id & ~RESOURCE_ID_MASK)) &&
-	    ((clientTable[client->index].expectID <= id) ||
-	     !LookupIDByClass(id, RC_ANY)));
-}
-
-#ifdef XCSECURITY
-
-/* SecurityLookupIDByType and SecurityLookupIDByClass:
- * These are the heart of the resource ID security system.  They take
- * two additional arguments compared to the old LookupID functions:
- * the client doing the lookup, and the access mode (see resource.h).
- * The resource is returned if it exists and the client is allowed access,
- * else NULL is returned.
- */
-
-pointer
-SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, Mask mode)
-{
-    int    cid;
-    register    ResourcePtr res;
-    pointer retval = NULL;
-
-    assert(client == NullClient ||
-     (client->index <= currentMaxClients && clients[client->index] == client));
-    assert( (rtype & TypeMask) <= lastResourceType);
-
-    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
-	clientTable[cid].buckets)
-    {
-	res = clientTable[cid].resources[Hash(cid, id)];
-
-	for (; res; res = res->next)
-	    if ((res->id == id) && (res->type == rtype))
-	    {
-		retval = res->value;
-		break;
-	    }
-    }
-    if (retval && client && client->CheckAccess)
-	retval = (* client->CheckAccess)(client, id, rtype, mode, retval);
-    return retval;
-}
-
-
-pointer
-SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, Mask mode)
-{
-    int    cid;
-    register ResourcePtr res = NULL;
-    pointer retval = NULL;
-
-    assert(client == NullClient ||
-     (client->index <= currentMaxClients && clients[client->index] == client));
-    assert (classes >= lastResourceClass);
-
-    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
-	clientTable[cid].buckets)
-    {
-	res = clientTable[cid].resources[Hash(cid, id)];
-
-	for (; res; res = res->next)
-	    if ((res->id == id) && (res->type & classes))
-	    {
-		retval = res->value;
-		break;
-	    }
-    }
-    if (retval && client && client->CheckAccess)
-	retval = (* client->CheckAccess)(client, id, res->type, mode, retval);
-    return retval;
-}
-
-/* We can't replace the LookupIDByType and LookupIDByClass functions with
- * macros because of compatibility with loadable servers.
- */
-
-pointer
-LookupIDByType(XID id, RESTYPE rtype)
-{
-    return SecurityLookupIDByType(NullClient, id, rtype,
-				  SecurityUnknownAccess);
-}
-
-pointer
-LookupIDByClass(XID id, RESTYPE classes)
-{
-    return SecurityLookupIDByClass(NullClient, id, classes,
-				   SecurityUnknownAccess);
-}
-
-#else /* not XCSECURITY */
-
-/*
- *  LookupIDByType returns the object with the given id and type, else NULL.
- */ 
-pointer
-LookupIDByType(XID id, RESTYPE rtype)
-{
-    int    cid;
-    register    ResourcePtr res;
-
-    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
-	clientTable[cid].buckets)
-    {
-	res = clientTable[cid].resources[Hash(cid, id)];
-
-	for (; res; res = res->next)
-	    if ((res->id == id) && (res->type == rtype))
-		return res->value;
-    }
-    return (pointer)NULL;
-}
-
-/*
- *  LookupIDByClass returns the object with the given id and any one of the
- *  given classes, else NULL.
- */ 
-pointer
-LookupIDByClass(XID id, RESTYPE classes)
-{
-    int    cid;
-    register    ResourcePtr res;
-
-    if (((cid = CLIENT_ID(id)) < MAXCLIENTS) &&
-	clientTable[cid].buckets)
-    {
-	res = clientTable[cid].resources[Hash(cid, id)];
-
-	for (; res; res = res->next)
-	    if ((res->id == id) && (res->type & classes))
-		return res->value;
-    }
-    return (pointer)NULL;
-}
-
-#endif /* XCSECURITY */
-
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index e3e4f4b83..a6d638ea7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -967,8 +967,17 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-		   client);
+    /* 
+     * There's a potential integer overflow in this check:
+     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+     *                client);
+     * the version below ought to avoid it
+     */
+    if (stuff->totalHeight != 0 && 
+	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+	client->errorValue = stuff->totalWidth;
+	return BadValue;
+    }
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index e3e4f4b83..a6d638ea7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -967,8 +967,17 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-		   client);
+    /* 
+     * There's a potential integer overflow in this check:
+     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+     *                client);
+     * the version below ought to avoid it
+     */
+    if (stuff->totalHeight != 0 && 
+	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+	client->errorValue = stuff->totalWidth;
+	return BadValue;
+    }
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
index e2cf8cd24..f25bb9b5d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.X.original
@@ -863,8 +863,17 @@ ProcShmPutImage(client)
         return BadValue;
     }
 
-    VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
-		   client);
+    /* 
+     * There's a potential integer overflow in this check:
+     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+     *                client);
+     * the version below ought to avoid it
+     */
+    if (stuff->totalHeight != 0 && 
+	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+	client->errorValue = stuff->totalWidth;
+	return BadValue;
+    }
     if (stuff->srcX > stuff->totalWidth)
     {
 	client->errorValue = stuff->srcX;
-- 
cgit v1.2.3


From 97fe7650e309c529085abef6e6418796b36f421c Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:55 +0200
Subject: Imported nxagent-3.2.0-8.tar.gz

Summary: Imported nxagent-3.2.0-8.tar.gz
Keywords:

Imported nxagent-3.2.0-8.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG  | 5 +++++
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 7cf04acc0..c45c97bbb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,10 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 1cc6898d7..88e99a1a0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -444,7 +444,7 @@ N/A
                                      max_keycode - min_keycode + 1,
                                      &mapWidth);
 
-        if (keymap == NULL)
+        if (keymap64 == NULL)
         {
           XFreeModifiermap(modifier_keymap);
 
-- 
cgit v1.2.3


From 1a74e03235ced7003989b8c02bc4d955234431c1 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:55 +0200
Subject: Imported nxagent-3.3.0-10.tar.gz

Summary: Imported nxagent-3.3.0-10.tar.gz
Keywords:

Imported nxagent-3.3.0-10.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |  20 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  93 +++++
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      | 116 ++++--
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 152 ++++++-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          | 188 ++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Imakefile       |   1 +
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      | 463 ++++++++++++++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   4 +
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |  31 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      |  63 ++-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        |   3 +-
 nx-X11/programs/Xserver/hw/nxagent/Window.c        | 127 ++++++
 nx-X11/programs/Xserver/hw/nxagent/Windows.h       |  18 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    | 119 +++++-
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    | 119 +++++-
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |   4 +
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |   4 +
 19 files changed, 1399 insertions(+), 137 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 5b336279e..5d344729c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -1140,13 +1140,13 @@ static void nxagentParseOptions(char *name, char *value)
   }
   else if (!strcmp(name, "resize"))
   {
-    if (!strcmp(value, "1"))
+    if (nxagentOption(DesktopResize) == 0 || strcmp(value, "0") == 0)
     {
-      nxagentResizeDesktopAtStartup = True;
+      nxagentResizeDesktopAtStartup = 0;
     }
-    else if (!strcmp(value, "0"))
+    else if (strcmp(value, "1") == 0)
     {
-      nxagentResizeDesktopAtStartup = False;
+      nxagentResizeDesktopAtStartup = 1;
     }
     else
     {
@@ -2080,8 +2080,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 65536;
-      tileHeight = 65536;
+      tileWidth  = 4096;
+      tileHeight = 4096;
 
       break;
     }
@@ -2091,8 +2091,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 65536;
-      tileHeight = 65536;
+      tileWidth  = 4096;
+      tileHeight = 4096;
 
       break;
     }
@@ -2103,8 +2103,8 @@ void nxagentSetDeferLevel()
 
       deferTimeout = 200;
 
-      tileWidth  = 65536;
-      tileHeight = 65536;
+      tileWidth  = 4096;
+      tileHeight = 4096;
 
       break;
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index c45c97bbb..9e746bb78 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,98 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index abc228e9c..82723b5a0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -32,6 +32,7 @@
 #include "Handlers.h"
 #include "Pixels.h"
 #include "Reconnect.h"
+#include "GCOps.h"
 
 #include "NXlib.h"
 
@@ -371,6 +372,7 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   int nBox;
   int x, y;
   int w, h;
+  int extentWidth, extentHeight;
   int tileWidth, tileHeight;
   int length, format, leftPad;
   int i;
@@ -417,13 +419,14 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   if (useStoredBitmap != 0)
   {
     #ifdef TEST
-    fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap "
+    fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap at [%p] "
                 "[%d,%d,%d,%d] with [%ld] rects.\n", nxagentDrawableType(pDrawable),
-                    (void *) pDrawable, nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
-                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
-                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
-                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
-                                    REGION_NUM_RECTS(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
+                    (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable),
+                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+                                    nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
+                                        REGION_NUM_RECTS(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
     #endif
 
     clipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
@@ -580,8 +583,7 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
   #ifdef TEST
   fprintf(stderr, "nxagentSynchronizeRegion: Going to synchronize [%ld] rects of [%s] at [%p].\n",
-              REGION_NUM_RECTS(clipRegion), (pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window"),
-                  (void *) pDrawable);
+              REGION_NUM_RECTS(clipRegion), nxagentDrawableType(pDrawable), (void *) pDrawable);
 
   fprintf(stderr, "nxagentSynchronizeRegion: Extents geometry [%d,%d,%d,%d].\n",
           clipRegion -> extents.x1, clipRegion -> extents.y1, clipRegion -> extents.x2, clipRegion -> extents.y2);
@@ -590,8 +592,20 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
               pDrawable -> x, pDrawable -> y, pDrawable -> width, pDrawable -> height);
   #endif
 
-  w = tileWidth  = (nxagentOption(TileWidth)  > pDrawable -> width  ? pDrawable -> width  : nxagentOption(TileWidth));
-  h = tileHeight = (nxagentOption(TileHeight) > pDrawable -> height ? pDrawable -> height : nxagentOption(TileHeight));
+  /*
+   * We are going to synchronize the corrupted
+   * area, so we use the corrupted extents as
+   * maximum size of the image data. It's im-
+   * portant to avoid using the drawable size,
+   * because in case of a huge window it had to
+   * result in a failed data memory allocation.
+   */
+
+  extentWidth  = clipRegion -> extents.x2 - clipRegion -> extents.x1;
+  extentHeight = clipRegion -> extents.y2 - clipRegion -> extents.y1;
+
+  w = tileWidth  = (nxagentOption(TileWidth)  > extentWidth  ? extentWidth  : nxagentOption(TileWidth));
+  h = tileHeight = (nxagentOption(TileHeight) > extentHeight ? extentHeight : nxagentOption(TileHeight));
 
   #ifdef DEBUG
   fprintf(stderr, "nxagentSynchronizeRegion: Using tiles of size [%dx%d].\n", tileWidth, tileHeight);
@@ -602,7 +616,22 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   if (data == NULL)
   {
     #ifdef WARNING
+
     fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to allocate memory for synchronization.\n");
+
+    /*
+     * Print detailed informations if the
+     * image length is zero.
+     */
+
+    if (length == 0)
+    {
+      fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] with region geometry [%ld][%d,%d,%d,%d].\n",
+                  nxagentDrawableType(pDrawable), (void *) pDrawable, REGION_NUM_RECTS(clipRegion),
+                      clipRegion -> extents.x1, clipRegion -> extents.y1,
+                          clipRegion -> extents.x2, clipRegion -> extents.y2);
+    }
+
     #endif
 
     goto nxagentSynchronizeRegionFree;
@@ -657,10 +686,14 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
         if (nxagentDrawableStatus(pDrawable) == Synchronized)
         {
           #ifdef WARNING
+
           if (pDrawable -> type == DRAWABLE_WINDOW && pSrcDrawable != pDrawable)
+          {
             fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Trying to synchronize "
                         "the clean drawable type [%d] at [%p] with source at [%p].\n",
                             pDrawable -> type, (void *) pDrawable, (void *) pSrcDrawable);
+          }
+
           #endif
 
           goto nxagentSynchronizeRegionStop;
@@ -735,9 +768,6 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
         nxagentGetImage(pSrcDrawable, x, y, w, h, format, AllPlanes, data);
 
-        nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
-                                x, y, w, h, leftPad, format, data);
-
         /*
          * Going to unmark the synchronized
          * region.
@@ -792,6 +822,13 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
                 nxagentUnmarkCorruptedRegion(pDrawable, &tileRegion);
               }
+              #ifdef TEST
+              else
+              {
+                fprintf(stderr, "nxagentSynchronizeRegion: Tile [%d,%d,%d,%d] on drawable [%p] doesn't match.\n",
+                            x, y, x + w, y + h, (void *) pDrawable);
+              }
+              #endif
             }
             else
             {
@@ -822,6 +859,14 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
           }
         }
 
+        /*
+         * Realize the image after comparing the
+         * source data with the bitmap data.
+         */
+
+        nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
+                                x, y, w, h, leftPad, format, data);
+
         REGION_UNINIT(pDrawable -> pScreen, &tileRegion);
 
         #if !defined(COLLECTED_UPDATES)
@@ -2542,16 +2587,13 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
   GCPtr pGC = NULL;
   RegionPtr pClipRegion = NullRegion;
 
-  char *data = NULL;
-
   int x, y;
   int w, h;
-  int length, format;
   int saveTrap;
 
   #ifdef TEST
-  fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for drawable at [%p].\n",
-              (void *) pDrawable);
+  fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for [%s] at [%p].\n",
+              nxagentDrawableType(pDrawable), (void *) pDrawable);
   #endif
 
   /*
@@ -2613,7 +2655,10 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
    * FIXME: A better way it would be create the bitmap
    * with the same extents of the clipRegion. This
    * requires to save the offset with respect to the
-   * drawable origin like in the backing store.
+   * drawable origin like in the backing store. This
+   * becomes particularly important when the drawable
+   * is a huge window, because the pixmap creation
+   * would fail.
    */
 
   pBitmap = nxagentCreatePixmap(pDrawable -> pScreen, pDrawable -> width, pDrawable -> height, pDrawable -> depth);
@@ -2636,24 +2681,8 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
   w = pClipRegion -> extents.x2 - pClipRegion -> extents.x1;
   h = pClipRegion -> extents.y2 - pClipRegion -> extents.y1;
 
-  data = nxagentAllocateImageData(w, h, pDrawable -> depth, &length, &format);
-
-  if (data == NULL)
-  {
-    #ifdef WARNING
-    fprintf(stderr, "nxagentCreateDrawableBitmap: Cannot allocate memory for the bitmap data.\n");
-    #endif
-
-    nxagentDestroyPixmap(pBitmap);
-
-    goto nxagentCreateDrawableBitmapEnd;
-  }
+  nxagentCopyArea(pDrawable, (DrawablePtr) pBitmap, pGC, x, y, w, h, x, y);
 
-  nxagentGetImage(pDrawable, x, y, w, h, format, AllPlanes, data);
-
-  nxagentPutImage((DrawablePtr) pBitmap, pGC, pBitmap -> drawable.depth, x, y, w, h,
-                      0, format, data);
- 
   REGION_UNION(pDrawable -> pScreen, nxagentCorruptedRegion((DrawablePtr) pBitmap),
                    nxagentCorruptedRegion((DrawablePtr) pBitmap), pClipRegion);
 
@@ -2695,11 +2724,6 @@ nxagentCreateDrawableBitmapEnd:
     nxagentFreeRegion(pDrawable, pClipRegion);
   }
 
-  if (data != NULL)
-  {
-    xfree(data);
-  }
-
   if (pGC != NULL)
   {
     FreeScratchGC(pGC);
@@ -3075,6 +3099,16 @@ void nxagentSendBackgroundExpose(WindowPtr pWin, PixmapPtr pBackground, RegionPt
 
   REGION_INTERSECT(pWin -> pScreen, &expose, &expose, &pWin -> clipList);
 
+  /*
+   * Reduce the overall region to expose.
+   */
+  
+  REGION_TRANSLATE(pWin -> pScreen, &expose, -pWin -> drawable.x, -pWin -> drawable.y);
+  
+  REGION_SUBTRACT(pWin -> pScreen, pExpose, pExpose, &expose);
+  
+  REGION_TRANSLATE(pWin -> pScreen, &expose, pWin -> drawable.x, pWin -> drawable.y);
+
   miWindowExposures(pWin, &expose, &expose);
 
 nxagentSendBackgroundExposeEnd:
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index b37d81adf..3c1458cb7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -63,7 +63,13 @@
 #include "NXproto.h"
 
 #include "xfixesproto.h"
+#define Window     XlibWindow
+#define Atom   XlibAtom
+#define Time XlibXID
 #include <X11/extensions/Xfixes.h>
+#undef Window
+#undef Atom
+#undef Time
 
 #ifdef NXAGENT_FIXKEYS
 #include "inputstr.h"
@@ -113,6 +119,10 @@ extern int nxagentSplashCount;
 
 extern int nxagentLastClipboardClient;
 
+#ifdef NX_DEBUG_INPUT
+int nxagentDebugInput = 0;
+#endif
+
 #ifdef DEBUG
 extern Bool nxagentRootlessTreesMatch(void);
 #endif
@@ -172,6 +182,8 @@ static Cursor viewportCursor;
 
 static Mask defaultEventMask;
 
+static int lastEventSerial = 0;
+
 #define MAX_INC 200
 #define INC_STEP 5
 #define nextinc(x)  ((x) < MAX_INC ? (x) += INC_STEP : (x))
@@ -252,6 +264,13 @@ void nxagentRemoveDuplicatedKeys(XEvent *X);
 
 void ProcessInputEvents()
 {
+  #ifdef NX_DEBUG_INPUT
+  if (nxagentDebugInput == 1)
+  {
+    fprintf(stderr, "ProcessInputEvents: Processing input.\n");
+  }
+  #endif
+
   mieqProcessInputEvents();
 }
 
@@ -282,6 +301,11 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentRRSetScreenConfig(pScreen, nxagentOption(Width), nxagentOption(Height));
 
+    if (nxagentOption(ClientOs) == ClientOsWinnt)
+    {
+      NXSetExposeParameters(nxagentDisplay, 0, 0, 0);
+    }
+
     sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
     sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
   }
@@ -771,8 +795,9 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         }
 
         x.u.u.type = KeyRelease;
-        x.u.u.detail = X.xkey.keycode;
-        x.u.keyButtonPointer.time = nxagentLastKeyPressTime + (X.xkey.time - nxagentLastServerTime);
+        x.u.u.detail = nxagentConvertKeycode(X.xkey.keycode);
+        x.u.keyButtonPointer.time = nxagentLastKeyPressTime +
+            (X.xkey.time - nxagentLastServerTime);
 
         nxagentLastServerTime = X.xkey.time;
 
@@ -794,8 +819,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
       }
       case ButtonPress:
       {
-        #ifdef TEST
-        fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonPress event.\n");
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInput == 1)
+        {
+          fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonPress event.\n");
+        }
         #endif
 
         nxagentInputEvent = 1;
@@ -860,6 +888,13 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
             x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
           }
 
+          #ifdef NX_DEBUG_INPUT
+          if (nxagentDebugInput == 1)
+          {
+            fprintf(stderr, "nxagentDispatchEvents: Adding ButtonPress event.\n");
+          }
+          #endif
+
           mieqEnqueue(&x);
 
           CriticalOutputPending = 1;
@@ -887,8 +922,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
       }
       case ButtonRelease:
       {
-        #ifdef TEST
-        fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonRelease event.\n");
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInput == 1)
+        {
+          fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonRelease event.\n");
+        }
         #endif
 
         nxagentInputEvent = 1;
@@ -923,6 +961,13 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
             x.u.keyButtonPointer.rootY = X.xmotion.y - nxagentOption(RootY);
           }
 
+          #ifdef NX_DEBUG_INPUT
+          if (nxagentDebugInput == 1)
+          {
+            fprintf(stderr, "nxagentDispatchEvents: Adding ButtonRelease event.\n");
+          }
+          #endif
+
           mieqEnqueue(&x);
 
           CriticalOutputPending = 1;
@@ -956,12 +1001,15 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         fprintf(stderr, "nxagentDispatchEvents: Going to handle new MotionNotify event.\n");
         #endif
 
-        #ifdef TEST
-        fprintf(stderr, "nxagentDispatchEvents: Handling motion notify window [%ld] root [%ld] child [%ld].\n",
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInput == 1)
+        {
+          fprintf(stderr, "nxagentDispatchEvents: Handling motion notify window [%ld] root [%ld] child [%ld].\n",
                     X.xmotion.window, X.xmotion.root, X.xmotion.subwindow);
 
-        fprintf(stderr, "nxagentDispatchEvents: Pointer at [%d][%d] relative root [%d][%d].\n",
+          fprintf(stderr, "nxagentDispatchEvents: Pointer at [%d][%d] relative root [%d][%d].\n",
                     X.xmotion.x, X.xmotion.y, X.xmotion.x_root, X.xmotion.y_root);
+        }
         #endif
 
         x.u.u.type = MotionNotify;
@@ -975,18 +1023,17 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
             nxagentLastEnteredWindow = pWin;
           }
 
-          if (nxagentPulldownDialogPid == 0 && (X.xmotion.y_root <
-                  nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
+          if (nxagentPulldownDialogPid == 0 && nxagentLastEnteredTopLevelWindow &&
+                  (X.xmotion.y_root < nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
           {
-            if (pWin && nxagentLastEnteredTopLevelWindow &&
-                    nxagentClientIsDialog(wClient(pWin)) == 0 &&
-                        nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
-                            nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
-                                X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
-                                    (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
-                                        X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
-                                            (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
-                                                nxagentOption(Menu) == 1)
+            if (pWin && nxagentClientIsDialog(wClient(pWin)) == 0 &&
+                    nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
+                        nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
+                            X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
+                                    X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                        (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
+                                            nxagentOption(Menu) == 1)
             {
               nxagentPulldownDialog(nxagentLastEnteredTopLevelWindow -> drawable.id);
             }
@@ -1008,6 +1055,14 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
                     X.xmotion.window == nxagentDefaultWindows[pScreen -> myNum]
                         && X.xmotion.subwindow == None))
         {
+          #ifdef NX_DEBUG_INPUT
+          if (nxagentDebugInput == 1)
+          {
+            fprintf(stderr, "nxagentDispatchEvents: Adding motion event [%d, %d] to the queue.\n",
+                        x.u.keyButtonPointer.rootX, x.u.keyButtonPointer.rootY);
+          }
+          #endif
+
           mieqEnqueue(&x);
         }
 
@@ -1644,6 +1699,21 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
     } /* End of switch (X.type) */
 
+    if (X.xany.serial < lastEventSerial)
+    {
+      /*
+       * Start over.
+       */
+
+      nxagentDeleteStaticResizedWindow(0);
+    }
+    else
+    {
+      nxagentDeleteStaticResizedWindow(X.xany.serial - 1);
+    }
+
+    lastEventSerial = X.xany.serial;
+
   } /* End of while (...) */
 
   /*
@@ -1848,8 +1918,9 @@ int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
 
   nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
 
+  
   x.u.u.type = KeyPress;
-  x.u.u.detail = X -> xkey.keycode;
+  x.u.u.detail = nxagentConvertKeycode(X -> xkey.keycode);
   x.u.keyButtonPointer.time = nxagentLastKeyPressTime;
 
   nxagentLastServerTime = X -> xkey.time;
@@ -1914,6 +1985,8 @@ int nxagentHandleExposeEvent(XEvent *X)
   int index = 0;
   int overlap = 0;
 
+  StaticResizedWindowStruct *resizedWinPtr = NULL;
+
   #ifdef DEBUG
   fprintf(stderr, "nxagentHandleExposeEvent: Checking remote expose events.\n");
   #endif
@@ -1944,6 +2017,19 @@ FIXME: This can be maybe optimized by consuming the
       box.x1 = pWin -> drawable.x + wBorderWidth(pWin) + X -> xexpose.x;
       box.y1 = pWin -> drawable.y + wBorderWidth(pWin) + X -> xexpose.y;
 
+      resizedWinPtr = nxagentFindStaticResizedWindow(X -> xany.serial);
+
+      while (resizedWinPtr)
+      {
+        if (resizedWinPtr -> pWin == pWin)
+        {
+          box.x1 += resizedWinPtr -> offX;
+          box.y1 += resizedWinPtr -> offY;
+        }
+
+        resizedWinPtr = resizedWinPtr -> prev;
+      }
+
       box.x2 = box.x1 + X -> xexpose.width;
       box.y2 = box.y1 + X -> xexpose.height;
 
@@ -3913,3 +3999,27 @@ int nxagentWaitEvents(Display *dpy, struct timeval *tm)
 
   return 1;
 }
+
+#ifdef NX_DEBUG_INPUT
+
+void nxagentDumpInputInfo(void)
+{
+  fprintf(stderr, "Dumping input info ON.\n");
+}
+
+void nxagentGuessDumpInputInfo(ClientPtr client, Atom property, char *data)
+{
+  if (strcmp(validateString(NameForAtom(property)), "NX_DEBUG_INPUT") == 0)
+  {
+    if (*data != 0)
+    {
+      nxagentDebugInput = 1;
+    }
+    else
+    {
+      nxagentDebugInput = 0;
+    }
+  }
+}
+
+#endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index 6fb34f221..87f9f0201 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -65,26 +65,34 @@ is" without express or implied warranty.
 #define NXAGENT_ALTERNATE_FONT_DIR    "/usr/share/X11/fonts"
 #define NXAGENT_ALTERNATE_FONT_DIR_2  "/usr/share/fonts/X11"
 #define NXAGENT_ALTERNATE_FONT_DIR_3  "/usr/share/fonts"
+#define NXAGENT_ALTERNATE_FONT_DIR_4  "/usr/NX/share/fonts"
 
 #define NXAGENT_DEFAULT_FONT_PATH  \
 "/usr/X11R6/lib/X11/fonts/misc/,/usr/X11R6/lib/X11/fonts/Speedo/,\
 /usr/X11R6/lib/X11/fonts/Type1/,/usr/X11R6/lib/X11/fonts/75dpi/,\
-/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/"
+/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/,\
+/usr/NX/share/fonts/base"
 
 #define NXAGENT_ALTERNATE_FONT_PATH  \
 "/usr/share/X11/fonts/misc/,/usr/share/X11/fonts/Speedo/,\
 /usr/share/X11/fonts/Type1/,/usr/share/X11/fonts/75dpi/,\
-/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/"
+/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/,\
+/usr/NX/share/fonts/base"
 
 #define NXAGENT_ALTERNATE_FONT_PATH_2  \
 "/usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Speedo/,\
 /usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,\
-/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/"
+/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/,\
+/usr/NX/share/fonts/base"
 
 #define NXAGENT_ALTERNATE_FONT_PATH_3  \
 "/usr/share/fonts/misc/,/usr/share/fonts/Speedo/,\
 /usr/share/fonts/Type1/,/usr/share/fonts/75dpi/,\
-/usr/share/fonts/100dpi/,/usr/share/fonts/TTF/"
+/usr/share/fonts/100dpi/,/usr/share/fonts/TTF/,\
+/usr/NX/share/fonts/base"
+
+#define NXAGENT_ALTERNATE_FONT_PATH_4  \
+"/usr/NX/share/fonts/base"
 
 #undef NXAGENT_FONTCACHE_DEBUG
 #undef NXAGENT_RECONNECT_FONT_DEBUG
@@ -101,6 +109,8 @@ static XFontStruct *nxagentLoadQueryFont(register Display *dpy , char *fontName
 int nxagentFreeFont(XFontStruct *fs);
 static Bool nxagentGetFontServerPath(char * fontServerPath);
 
+static char * nxagentMakeScalableFontName(const char *fontName, int scalableResolution);
+
 RESTYPE RT_NX_FONT;
 
 #ifdef NXAGENT_RECONNECT_FONT_DEBUG
@@ -419,13 +429,59 @@ Bool nxagentFontFind(const char *name, int *pos)
 Bool nxagentFontLookUp(const char *name)
 {
   int i;
-  if (name)
-    if (!strlen(name))
-       return 0;
-  if (nxagentFontFind(name, &i))
-    return (nxagentRemoteFontList.list[i]->status > 0);
-  else
+  int result;
+
+  char *scalable;
+
+  if (name != NULL && strlen(name) == 0)
+  {
     return 0;
+  }
+
+  result = nxagentFontFind(name, &i);
+
+  scalable = NULL;
+
+  /*
+   * Let's try with the scalable font description.
+   */
+
+  if (result == 0)
+  {
+    scalable = nxagentMakeScalableFontName(name, 0); 
+
+    if (scalable != NULL)
+    {
+      result = nxagentFontFind(scalable, &i);
+
+      free(scalable);
+    }
+  }
+
+  /*
+   * Let's try again after replacing zero to xdpi and ydpi in the pattern.
+   */
+
+  if (result == 0)
+  {
+    scalable = nxagentMakeScalableFontName(name, 1); 
+
+    if (scalable != NULL)
+    {
+      result = nxagentFontFind(scalable, &i);
+
+      free(scalable);
+    }
+  }
+
+  if (result == 0)
+  {
+    return 0;
+  }
+  else
+  {
+    return (nxagentRemoteFontList.list[i]->status > 0);
+  }
 }
 
 Bool nxagentRealizeFont(ScreenPtr pScreen, FontPtr pFont)
@@ -700,7 +756,7 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
   substFontBuf = (char *) xalloc(sizeof(char) * 512);
 
 
-  numFontFields = nxagentSplitString(fontName, fontNameFields, FIELDS, "-");
+  numFontFields = nxagentSplitString(fontName, fontNameFields, FIELDS + 1, "-");
 
   memcpy(substFontBuf, "fixed\0", strlen("fixed") + 1);
 
@@ -1505,6 +1561,31 @@ void nxagentVerifyDefaultFontPath(void)
     strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_3);
   }
 
+  if (stat(NXAGENT_ALTERNATE_FONT_DIR_4, &dirStat) == 0 &&
+          S_ISDIR(dirStat.st_mode) != 0)
+  {
+    /*
+     * Let's use the "/usr/NX/share/fonts" path.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+                validateString(NXAGENT_ALTERNATE_FONT_DIR_4));
+    #endif
+
+    if (*fontPath != '\0')
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_4) + 2);
+      strcat(fontPath, ",");
+    }
+    else
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_4) + 1);
+    }
+
+    strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_4);
+  }
+
   if (*fontPath == '\0') 
   {
     #ifdef WARNING
@@ -1698,3 +1779,88 @@ int nxagentSplitString(char *string, char *fields[], int nfields, char *sep)
   return i;
 }
 
+char *nxagentMakeScalableFontName(const char *fontName, int scalableResolution)
+{
+  char *scalableFontName;
+  const char *s;
+  int len;
+  int field;
+
+  len = strlen(fontName) + 1;
+
+  scalableFontName = malloc(len);
+
+  if (scalableFontName == NULL)
+  {
+    #ifdef PANIC
+    fprintf(stderr, "nxagentMakeScalableFontName: PANIC! malloc() failed.\n");
+    #endif
+
+    return NULL;
+  }
+
+  scalableFontName[0] = 0;
+
+  if (*fontName != '-')
+  {
+    goto MakeScalableFontNameError;
+  }
+
+  s = fontName;
+
+  field = 0;
+
+  while (s != NULL)
+  {
+    s = strchr(s + 1, '-');
+
+    if (s != NULL)
+    {
+      if (field == 6 || field == 7 || field == 11)
+      {
+        /*
+         * PIXEL_SIZE || POINT_SIZE || AVERAGE_WIDTH
+         */
+
+        strcat(scalableFontName, "-0");
+      }
+      else if (scalableResolution == 1 && (field == 8 || field == 9))
+      {
+        /*
+         * RESOLUTION_X || RESOLUTION_Y
+         */
+
+        strcat(scalableFontName, "-0");
+      }
+      else
+      {
+        strncat(scalableFontName, fontName, s - fontName);
+      }
+
+      fontName = s;
+    }
+    else
+    {
+      strcat(scalableFontName, fontName);
+    }
+
+    field++;
+  }
+
+  if (field != 14)
+  {
+    goto MakeScalableFontNameError;
+  }
+
+  return scalableFontName;
+
+MakeScalableFontNameError:
+
+  free(scalableFontName);
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentMakeScalableFontName: Invalid font name.\n");
+  #endif
+
+  return NULL;
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
index 804f95f78..633e17a22 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -205,6 +205,7 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \
           -DNXAGENT_ONSTART \
           -DNXAGENT_SPLASH \
           -DNXAGENT_ARTSD \
+          -UNX_DEBUG_INPUT \
           -UPANORAMIX
 
 all:: $(OBJS)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 4e47f8f81..81ed0c43e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -74,7 +74,7 @@ is" without express or implied warranty.
 #undef  DEBUG
 #undef  DUMP
 
-#define NXAGENT_VERSION  "3.2.0"
+#define NXAGENT_VERSION  "3.3.0"
 
 /*
  * ProcVector array defined in tables.c.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 88e99a1a0..6c14e20bf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -55,12 +55,28 @@ is" without express or implied warranty.
 
 #include "NXlib.h"
 
+#include "Shadow.h"
+
 #ifdef XKB
 
+#include "globals.h"
+#include "property.h"
+
 #include <X11/extensions/XKB.h>
+
+#define XKBSRV_NEED_FILE_FUNCS
 #include <X11/extensions/XKBsrv.h>
 #include <X11/extensions/XKBconfig.h>
 
+#include "X11/extensions/XKBrules.h"
+
+#include "Xatom.h"
+
+static int nxagentXkbGetNames(char **rules, char **model, char **layout,
+                                  char **variant, char **options);
+
+static void nxagentKeycodeConversionSetup(void);
+
 #endif /* XKB */
 
 /*
@@ -175,6 +191,281 @@ unsigned int nxagentAltMetaMask;
 
 void nxagentCheckAltMetaKeys(CARD8, int);
 
+static CARD8 nxagentConvertedKeycodes[] =
+{
+  /* evdev  pc105*/
+  /*   0 */   0,
+  /*   1 */   1,
+  /*   2 */   2,
+  /*   3 */   3,
+  /*   4 */   4,
+  /*   5 */   5,
+  /*   6 */   6,
+  /*   7 */   7,
+  /*   8 */   8,
+  /*   9 */   9,
+  /*  10 */   10,
+  /*  11 */   11,
+  /*  12 */   12,
+  /*  13 */   13,
+  /*  14 */   14,
+  /*  15 */   15,
+  /*  16 */   16,
+  /*  17 */   17,
+  /*  18 */   18,
+  /*  19 */   19,
+  /*  20 */   20,
+  /*  21 */   21,
+  /*  22 */   22,
+  /*  23 */   23,
+  /*  24 */   24,
+  /*  25 */   25,
+  /*  26 */   26,
+  /*  27 */   27,
+  /*  28 */   28,
+  /*  29 */   29,
+  /*  30 */   30,
+  /*  31 */   31,
+  /*  32 */   32,
+  /*  33 */   33,
+  /*  34 */   34,
+  /*  35 */   35,
+  /*  36 */   36,
+  /*  37 */   37,
+  /*  38 */   38,
+  /*  39 */   39,
+  /*  40 */   40,
+  /*  41 */   41,
+  /*  42 */   42,
+  /*  43 */   43,
+  /*  44 */   44,
+  /*  45 */   45,
+  /*  46 */   46,
+  /*  47 */   47,
+  /*  48 */   48,
+  /*  49 */   49,
+  /*  50 */   50,
+  /*  51 */   51,
+  /*  52 */   52,
+  /*  53 */   53,
+  /*  54 */   54,
+  /*  55 */   55,
+  /*  56 */   56,
+  /*  57 */   57,
+  /*  58 */   58,
+  /*  59 */   59,
+  /*  60 */   60,
+  /*  61 */   61,
+  /*  62 */   62,
+  /*  63 */   63,
+  /*  64 */   64,
+  /*  65 */   65,
+  /*  66 */   66,
+  /*  67 */   67,
+  /*  68 */   68,
+  /*  69 */   69,
+  /*  70 */   70,
+  /*  71 */   71,
+  /*  72 */   72,
+  /*  73 */   73,
+  /*  74 */   74,
+  /*  75 */   75,
+  /*  76 */   76,
+  /*  77 */   77,
+  /*  78 */   78,
+  /*  79 */   79,
+  /*  80 */   80,
+  /*  81 */   81,
+  /*  82 */   82,
+  /*  83 */   83,
+  /*  84 */   84,
+  /*  85 */   85,
+  /*  86 */   86,
+  /*  87 */   87,
+  /*  88 */   88,
+  /*  89 */   89,
+  /*  90 */   90,
+  /*  91 */   91,
+  /*  92 */  124,
+  /*  93 */   93,
+  /*  94 */   94,
+  /*  95 */   95,
+  /*  96 */   96,
+  /*  97 */  211,
+  /*  98 */   98,
+  /*  99 */   99,
+  /* 100 */  100,
+  /* 101 */  208,
+  /* 102 */  102,
+  /* 103 */  103,
+  /* 104 */  108,
+  /* 105 */  109,
+  /* 106 */  112,
+  /* 107 */  111,
+  /* 108 */  113,
+  /* 109 */  109,
+  /* 110 */   97,
+  /* 111 */   98,
+  /* 112 */   99,
+  /* 113 */  100,
+  /* 114 */  102,
+  /* 115 */  103,
+  /* 116 */  104,
+  /* 117 */  105,
+  /* 118 */  106,
+  /* 119 */  107,
+  /* 120 */  120,
+  /* 121 */  121,
+  /* 122 */  122,
+  /* 123 */  123,
+  /* 124 */  124,
+  /* 125 */  126,
+  /* 126 */  126,
+  /* 127 */  110,
+  /* 128 */  128,
+  /* 129 */  129,
+  /* 130 */  130,
+  /* 131 */  131,
+  /* 132 */  133,
+  /* 133 */  115,
+  /* 134 */  116,
+  /* 135 */  117,
+  /* 136 */  136,
+  /* 137 */  137,
+  /* 138 */  138,
+  /* 139 */  139,
+  /* 140 */  140,
+  /* 141 */  141,
+  /* 142 */  142,
+  /* 143 */  143,
+  /* 144 */  144,
+  /* 145 */  145,
+  /* 146 */  146,
+  /* 147 */  147,
+  /* 148 */  148,
+  /* 149 */  149,
+  /* 150 */  150,
+  /* 151 */  151,
+  /* 152 */  152,
+  /* 153 */  153,
+  /* 154 */  154,
+  /* 155 */  155,
+  /* 156 */  156,
+  /* 157 */  157,
+  /* 158 */  158,
+  /* 159 */  159,
+  /* 160 */  160,
+  /* 161 */  161,
+  /* 162 */  162,
+  /* 163 */  163,
+  /* 164 */  164,
+  /* 165 */  165,
+  /* 166 */  166,
+  /* 167 */  167,
+  /* 168 */  168,
+  /* 169 */  169,
+  /* 170 */  170,
+  /* 171 */  171,
+  /* 172 */  172,
+  /* 173 */  173,
+  /* 174 */  174,
+  /* 175 */  175,
+  /* 176 */  176,
+  /* 177 */  177,
+  /* 178 */  178,
+  /* 179 */  179,
+  /* 180 */  180,
+  /* 181 */  181,
+  /* 182 */  182,
+  /* 183 */  183,
+  /* 184 */  184,
+  /* 185 */  185,
+  /* 186 */  186,
+  /* 187 */  187,
+  /* 188 */  188,
+  /* 189 */  189,
+  /* 190 */  190,
+  /* 191 */  118,
+  /* 192 */  119,
+  /* 193 */  120,
+  /* 194 */  121,
+  /* 195 */  122,
+  /* 196 */  196,
+  /* 197 */  197,
+  /* 198 */  198,
+  /* 199 */  199,
+  /* 200 */  200,
+  /* 201 */  201,
+  /* 202 */  202,
+  /* 203 */   93,
+  /* 204 */  125,
+  /* 205 */  156,
+  /* 206 */  127,
+  /* 207 */  128,
+  /* 208 */  208,
+  /* 209 */  209,
+  /* 210 */  210,
+  /* 211 */  211,
+  /* 212 */  212,
+  /* 213 */  213,
+  /* 214 */  214,
+  /* 215 */  215,
+  /* 216 */  216,
+  /* 217 */  217,
+  /* 218 */  218,
+  /* 219 */  219,
+  /* 220 */  220,
+  /* 221 */  221,
+  /* 222 */  222,
+  /* 223 */  223,
+  /* 224 */  224,
+  /* 225 */  225,
+  /* 226 */  226,
+  /* 227 */  227,
+  /* 228 */  228,
+  /* 229 */  229,
+  /* 230 */  230,
+  /* 231 */  231,
+  /* 232 */  232,
+  /* 233 */  233,
+  /* 234 */  234,
+  /* 235 */  235,
+  /* 236 */  236,
+  /* 237 */  237,
+  /* 238 */  238,
+  /* 239 */  239,
+  /* 240 */  240,
+  /* 241 */  241,
+  /* 242 */  242,
+  /* 243 */  243,
+  /* 244 */  244,
+  /* 245 */  245,
+  /* 246 */  246,
+  /* 247 */  247,
+  /* 248 */  248,
+  /* 249 */  249,
+  /* 250 */  250,
+  /* 251 */  251,
+  /* 252 */  252,
+  /* 253 */  253,
+  /* 254 */  254,
+  /* 255 */  255
+};
+
+static int nxagentKeycodeConversion = 0;
+
+CARD8 nxagentConvertKeycode(CARD8 k)
+{
+ if (nxagentKeycodeConversion != 0)
+ {
+   return nxagentConvertedKeycodes[k];
+ }
+ else
+ {
+   return k;
+ }
+}
+
 static int nxagentSaveKeyboardDeviceData(DeviceIntPtr dev, DeviceIntPtr devBackup);
 
 static int nxagentRestoreKeyboardDeviceData(DeviceIntPtr devBackup, DeviceIntPtr dev);
@@ -655,14 +946,21 @@ XkbError:
 
         xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
 
+        nxagentKeycodeConversionSetup();
+
         if (xkb == NULL || xkb->geom == NULL)
         {
           #ifdef TEST
           fprintf(stderr, "nxagentKeyboardProc: No current keyboard.\n");
-          #endif
-
-          #ifdef TEST
-          fprintf(stderr, "nxagentKeyboardProc: No keyboard, going to set rules and init device.\n");
+          if (xkb == NULL)
+          {
+            fprintf(stderr, "nxagentKeyboardProc: xkb is null.\n");
+          }
+          else
+          {
+            fprintf(stderr, "nxagentKeyboardProc: xkb->geom is null.\n");
+          }
+          fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device.\n");
           #endif
 
           XkbSetRulesDflts(rules, model, layout, variants, options);
@@ -777,6 +1075,12 @@ XkbError:
         XkbDDXChangeControls((pointer)pDev, xkb->ctrls, xkb->ctrls);
 
 XkbEnd:
+
+        if (nxagentOption(Shadow) == 1 && pDev && pDev->key)
+        {
+          NXShadowInitKeymap(&(pDev->key->curKeySyms));
+        }
+
         if (free_model) 
         {
           free_model = 0;
@@ -790,7 +1094,6 @@ XkbEnd:
         }
 
         XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
-
         xkb = NULL;
       }
 #endif
@@ -1358,4 +1661,154 @@ void nxagentTuneXkbWrapper(void)
   }
 }
 
+static int nxagentXkbGetNames(char **rules, char **model, char **layout,
+                                  char **variant, char **options)
+{
+  Atom atom;
+  #ifdef _XSERVER64
+  Atom64 type;
+  #else
+  Atom type;
+  #endif
+  int format;
+  unsigned long n;
+  unsigned long after;
+  char *data;
+  char *name;
+  Status result;
+
+  data = name = NULL;
+
+  *rules = NULL;
+  *model = NULL;
+  *layout = NULL;
+  *variant = NULL;
+  *options = NULL;
+
+  atom = XInternAtom(nxagentDisplay, "_XKB_RULES_NAMES", 1);
+
+  if (atom == 0)
+  {
+    return 0; 
+  }
+
+  result = XGetWindowProperty(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                                  atom, 0, 256, 0, XA_STRING, &type, &format,
+                                      &n, &after, (unsigned char **)&data);
+
+  if (result !=Success || data == NULL)
+  {
+    return 0;
+  }
+
+  if ((after > 0) || (type != XA_STRING) || (format != 8))
+  {
+    if (data != NULL)
+    {
+      XFree(data);
+      return 0;
+    }
+  }
+
+  name = data;
+
+  if (name < data + n)
+  {
+    *rules =  name;
+    name += strlen(name) + 1;
+  }
+
+  if (name < data + n)
+  {
+    *model = name;
+    name += strlen(name) + 1;
+  }
+
+  if (name < data + n)
+  {
+    *layout = name;
+    name += strlen(name) + 1;
+  }
+
+  if (name < data + n)
+  {
+    *variant = name;
+    name += strlen(name) + 1;
+  }
+
+  if (name < data + n)
+  {
+    *options = name;
+    name += strlen(name) + 1;
+  }
+
+  return n;
+}
+
+void nxagentKeycodeConversionSetup(void)
+{
+  char *drules = 0;
+  char *dmodel = 0;
+  char *dlayout = 0;
+  char *dvariant = 0;
+  char *doptions = 0;
+  unsigned int drulesLen;
+
+  nxagentKeycodeConversion = 0;
+
+  drulesLen = nxagentXkbGetNames(&drules, &dmodel, &dlayout,
+                                     &dvariant, &doptions);
+
+  #ifdef DEBUG
+  if (drulesLen != 0 && drules != NULL && dmodel != NULL)
+  {
+    fprintf(stderr, "nxagentKeycodeConversionSetup: "
+                "Remote: [%s,%s,%s,%s,%s].\n", drules, dmodel, dlayout,
+                    dvariant, doptions);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentKeycodeConversionSetup: "
+                "Failed to retrieve remote rules.\n");
+  }
+  #endif
+
+  if (nxagentOption(ClientOs) == ClientOsLinux &&
+            drules != NULL && dmodel != NULL &&
+                (strcmp(drules, "evdev") == 0 ||
+                    strcmp(dmodel, "evdev") == 0))
+  {
+    nxagentKeycodeConversion = 1;
+  }
+
+  if (drules != NULL)
+  {
+    XFree(drules);
+  }
+}
+
+void nxagentResetKeycodeConversion(void)
+{
+  int result;
+  XkbAgentInfoRec info;
+
+  result = XkbQueryExtension(nxagentDisplay, &info.Opcode, &info.EventBase,
+                                 &info.ErrorBase, &info.MajorVersion,
+                                     &info.MinorVersion);
+
+  if (result != 0)
+  {
+    nxagentKeycodeConversionSetup();
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentResetKeycodeConversion: "
+                "WARNING! Failed to query XKB extension.\n");
+    #endif
+
+    nxagentKeycodeConversion = 0;
+  }
+}
+
 #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index f292402d2..50dd2be78 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -109,6 +109,10 @@ void nxagentEnableXkbExtension(void);
 
 void nxagentTuneXkbWrapper(void);
 
+void nxagentResetKeycodeConversion(void);
+
 #endif
 
+CARD8 nxagentConvertKeycode(CARD8 k);
+
 #endif /* __Keyboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index ce3e6ee05..69b73a942 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -547,28 +547,29 @@ Bool nxagentReconnectSession(void)
     goto nxagentReconnectError;
   }
 
-  if (nxagentOption(ResetKeyboardAtResume))
+  if (nxagentOption(ResetKeyboardAtResume) == 1 &&
+         (nxagentKeyboard  == NULL || nxagentOldKeyboard == NULL ||
+             strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
+                 strcmp(nxagentKeyboard, "query") == 0))
   {
-    if (nxagentKeyboard  == NULL || nxagentOldKeyboard == NULL ||
-           strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
-               strcmp(nxagentKeyboard, "query") == 0)
+    if (nxagentResetKeyboard() == 0)
     {
-
-      if (nxagentResetKeyboard() == 0)
+      #ifdef WARNING
+      if (nxagentVerbose == 1)
       {
-        #ifdef WARNING
-        if (nxagentVerbose == 1)
-        {
-          fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
-        }
-        #endif
+        fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
+      }
+      #endif
 
-        failedStep = WINDOW_STEP;
+      failedStep = WINDOW_STEP;
 
-        goto nxagentReconnectError;
-      }
+      goto nxagentReconnectError;
     }
   }
+  else
+  {
+    nxagentResetKeycodeConversion();
+  }
 
   nxagentXkbState.Initialized = 0;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index b1ff219e7..f2d7b15f9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -2270,8 +2270,7 @@ void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
 
   normalizedImages = NULL;
 
-  if (glyphDepths[glyphSet -> fdepth] == 1 &&
-          nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
+  if (sizeImages > 0)
   {
     normalizedImages = xalloc(sizeImages);
 
@@ -2279,7 +2278,11 @@ void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
     {
       memcpy(normalizedImages, images, sizeImages);
 
-      BitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
+      if (glyphDepths[glyphSet -> fdepth] == 1 &&
+              nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
+      {
+        BitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
+      }
     }
     else
     {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index cd69af665..79cb74efa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -46,6 +46,20 @@
  * initialized.
  */
 
+typedef struct
+{
+  CARD32 flags;
+  CARD32 input;
+  CARD32 initial_state;
+  CARD32 icon_pixmap;
+  CARD32 icon_window;
+  INT32  icon_x;
+  INT32  icon_y;
+  CARD32 icon_mask;
+  CARD32 window_group;
+}
+nxagentWMHints;
+
 WindowPtr nxagentRootlessWindow = NULL;
 
 #define TOP_LEVEL_TABLE_UNIT 100
@@ -414,7 +428,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
   char *propertyS, *typeS;
   Atom propertyX, typeX;
   char *output = NULL;
-  XWMHints wmHints;
+  nxagentWMHints wmHints;
   Bool export = False;
   Bool freeMem = False;
 
@@ -470,7 +484,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
   else if (strcmp(typeS, "WM_HINTS") == 0)
   {
     ClientPtr pClient = wClient(pWin);
-    wmHints = *(XWMHints*)value;
+    wmHints = *(nxagentWMHints*)value;
 
     wmHints.flags |= InputHint;
     wmHints.input = True;
@@ -497,9 +511,10 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
         wmHints.flags &= ~IconPixmapHint;
 
         #ifdef WARNING
-        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon pixmap %lx from hint "
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon pixmap %x from hint "
                     "exporting property %s type %s on window %p.\n",
-                        wmHints.icon_pixmap, propertyS, typeS, (void*)pWin);
+                        (unsigned int) wmHints.icon_pixmap, propertyS, typeS,
+                            (void*)pWin);
         #endif
       }
     }
@@ -518,9 +533,10 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
         wmHints.flags &= ~IconWindowHint;
 
         #ifdef WARNING
-        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon window %lx from hint "
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon window %x from hint "
                     "exporting property %s type %s on window %p.\n",
-                        wmHints.icon_window, propertyS, typeS, (void*)pWin);
+                        (unsigned int) wmHints.icon_window, propertyS, typeS,
+                            (void*)pWin);
         #endif
       }
     }
@@ -539,9 +555,10 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
         wmHints.flags &= ~IconMaskHint;
 
         #ifdef WARNING
-        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon mask %lx from hint "
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon mask %x from hint "
                     "exporting property %s type %s on window %p.\n",
-                        wmHints.icon_mask, propertyS, typeS, (void*)pWin);
+                        (unsigned int) wmHints.icon_mask, propertyS, typeS,
+                            (void*)pWin);
         #endif
       }
     }
@@ -560,9 +577,10 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
         wmHints.flags &= ~WindowGroupHint;
 
         #ifdef WARNING
-        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window group %lx from hint "
+        fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window group %x from hint "
                     "exporting property %s type %s on window %p.\n",
-                        wmHints.window_group, propertyS, typeS, (void*)pWin);
+                        (unsigned int) wmHints.window_group, propertyS, typeS,
+                            (void*)pWin);
         #endif
       }
     }
@@ -654,7 +672,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
   {
     #ifdef TEST
     fprintf(stderr, "nxagentExportProperty: WARNING! Ignored ChangeProperty "
-                "on %swindow %lx property %s type %s nUnits %ld format %d\n",
+                "on %swindow %x property %s type %s nUnits %ld format %d\n",
                     nxagentWindowTopLevel(pWin) ? "toplevel " : "",
                         nxagentWindow(pWin), validateString(propertyS), validateString(typeS),
                             nUnits, format);
@@ -683,7 +701,7 @@ void nxagentImportProperty(Window window,
   WindowPtr pWin;
   Bool import = False;
   Bool freeMem = False;
-  XWMHints wmHints;
+  nxagentWMHints wmHints;
 
   typedef struct {
       CARD32 state;
@@ -797,7 +815,7 @@ void nxagentImportProperty(Window window,
   }
   else if (strcmp(typeS, "WM_HINTS") == 0)
   {
-    wmHints = *(XWMHints*)buffer;
+    wmHints = *(nxagentWMHints*)buffer;
     output = (char*) &wmHints;
     import = True;
 
@@ -815,8 +833,9 @@ void nxagentImportProperty(Window window,
 
         #ifdef WARNING
         fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote icon "
-                    "pixmap %ld from hint importing property [%ld] type %s on window %p.\n",
-                        wmHints.icon_pixmap, (long int) property, typeS, (void *) pWin);
+                    "pixmap %d from hint importing property [%ld] type %s on window %p.\n",
+                        (unsigned int) wmHints.icon_pixmap, (long int) property,
+                            typeS, (void *) pWin);
         #endif
       }
     }
@@ -835,8 +854,9 @@ void nxagentImportProperty(Window window,
 
         #ifdef WARNING
         fprintf(stderr, "nxagenImportProperty: WARNING! Failed to look up remote icon "
-                    "window %lx from hint importing property [%ld] type %s on window %p.\n",
-                         wmHints.icon_window, (long int) property, typeS, (void *) pWin);
+                    "window %x from hint importing property [%ld] type %s on window %p.\n",
+                         (unsigned int) wmHints.icon_window,
+                             (long int) property, typeS, (void *) pWin);
         #endif
       }
     }
@@ -855,8 +875,8 @@ void nxagentImportProperty(Window window,
 
         #ifdef WARNING
         fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote icon "
-                    "mask %lx from hint importing property [%ld] type %s on window %p.\n",
-                          wmHints.icon_mask, (long int) property, typeS, (void *) pWin);
+                    "mask %x from hint importing property [%ld] type %s on window %p.\n",
+                          (unsigned int) wmHints.icon_mask, (long int) property, typeS, (void *) pWin);
         #endif
       }
     }
@@ -875,8 +895,9 @@ void nxagentImportProperty(Window window,
 
         #ifdef WARNING
         fprintf(stderr, "nxagentImportProperty: WARNING! Failed to look up remote window "
-                    "group %lx from hint importing property [%ld] type %s on window %p.\n",
-                          wmHints.window_group, (long int) property, typeS, (void *) pWin);
+                    "group %x from hint importing property [%ld] type %s on window %p.\n",
+                          (unsigned int) wmHints.window_group,
+                              (long int) property, typeS, (void *) pWin);
         #endif
       }
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 34d498fb0..524bafd10 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -958,7 +958,8 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
 
     nxagentChangeOption(Fullscreen, True);
 
-    if (nxagentOption(ClientOs) == ClientOsWinnt)
+    if (nxagentOption(ClientOs) == ClientOsWinnt &&
+            (nxagentReconnectTrap == False || nxagentResizeDesktopAtStartup))
     {
       NXSetExposeParameters(nxagentDisplay, 0, 0, 0);
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index ff775f272..8da5d8bd1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -1136,6 +1136,11 @@ void nxagentConfigureWindow(WindowPtr pWin, unsigned int mask)
 {
   unsigned int valuemask;
   XWindowChanges values;
+  int offX, offY;
+  int i, j;
+
+  offX = nxagentWindowPriv(pWin)->x - pWin->origin.x;
+  offY = nxagentWindowPriv(pWin)->y - pWin->origin.y;
 
   if (nxagentScreenTrap == 1)
   {
@@ -1221,6 +1226,29 @@ void nxagentConfigureWindow(WindowPtr pWin, unsigned int mask)
                 (void *) pWin, nxagentWindow(pWin), valuemask);
     #endif
 
+    if (pWin->bitGravity == StaticGravity &&
+            ((mask & CWX) || (mask & CWY)) &&
+                ((mask & CWWidth) || (mask & CWHeight)))
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentConfigureWindow: Window has StaticGravity. Going to translate Expose events by offset [%d, %d].\n",
+                  offX, offY);
+      #endif
+
+      nxagentAddStaticResizedWindow(pWin, XNextRequest(nxagentDisplay), offX, offY);
+
+      for (j = 0; j < nxagentExposeQueue.length; j++)
+      {
+        i = (nxagentExposeQueue.start + j) % EXPOSED_SIZE;
+
+        if (nxagentExposeQueue.exposures[i].pWindow == pWin &&
+                nxagentExposeQueue.exposures[i].remoteRegion != NullRegion)
+        {
+          REGION_TRANSLATE(pWin -> drawable.pScreen, nxagentExposeQueue.exposures[i].remoteRegion, offX, offY);
+        }
+      }
+    }
+
     XConfigureWindow(nxagentDisplay, nxagentWindow(pWin), valuemask, &values);
 
     MAKE_SYNC_CONFIGURE_WINDOW;
@@ -3424,6 +3452,105 @@ void nxagentDeleteConfiguredWindow(WindowPtr pWin)
   return;
 }
 
+void nxagentAddStaticResizedWindow(WindowPtr pWin, unsigned long sequence, int offX, int offY)
+{
+  if (nxagentStaticResizedWindowList == NULL)
+  {
+    nxagentStaticResizedWindowList = malloc(sizeof(StaticResizedWindowStruct));
+    nxagentStaticResizedWindowList -> next = NULL;
+    nxagentStaticResizedWindowList -> prev = NULL;
+  }
+  else
+  {
+    StaticResizedWindowStruct *tmp;
+
+    tmp = malloc(sizeof(StaticResizedWindowStruct));
+
+    tmp -> next = nxagentStaticResizedWindowList;
+    nxagentStaticResizedWindowList -> prev = tmp;
+    tmp -> prev = NULL;
+    nxagentStaticResizedWindowList = tmp;
+  }
+
+  nxagentStaticResizedWindowList -> pWin = pWin;
+  nxagentStaticResizedWindowList -> sequence = sequence;
+  nxagentStaticResizedWindowList -> offX = offX;
+  nxagentStaticResizedWindowList -> offY = offY;
+}
+
+void nxagentDeleteStaticResizedWindow(unsigned long sequence)
+{
+  StaticResizedWindowStruct *index, *previous, *tmp;
+
+  index = nxagentStaticResizedWindowList;
+
+  while (index)
+  {
+    if (index -> sequence <= sequence)
+    {
+      if (index -> prev == NULL && index -> next == NULL)
+      {
+        free(nxagentStaticResizedWindowList);
+        nxagentStaticResizedWindowList = NULL;
+
+        return;
+      }
+      else if (index -> prev == NULL)
+      {
+        tmp = nxagentStaticResizedWindowList;
+        index = nxagentStaticResizedWindowList = tmp -> next;
+        free(tmp);
+        nxagentStaticResizedWindowList -> prev = NULL;
+
+        continue;
+      }
+      else if (index -> next == NULL)
+      {
+        tmp = index;
+        index = index -> prev;
+        free(tmp);
+        index -> next = NULL;
+
+        return;
+      }
+
+      previous = index -> prev;
+      tmp = index;
+      index = index -> next;
+      previous -> next = index;
+      index -> prev = previous;
+      free(tmp);
+
+      continue;
+    }
+
+    index = index -> next;
+  }
+
+  return;
+}
+
+StaticResizedWindowStruct *nxagentFindStaticResizedWindow(unsigned long sequence)
+{
+  StaticResizedWindowStruct *index;
+  StaticResizedWindowStruct *ret = NULL;
+
+  if (nxagentStaticResizedWindowList == NULL)
+  {
+    return NULL;
+  }
+
+  index = nxagentStaticResizedWindowList;
+
+  while (index && index -> sequence > sequence)
+  {
+    ret = index;
+    index = index -> next;
+  }
+
+  return ret;
+}
+
 void nxagentEmptyBackingStoreRegion(pointer param0, XID param1, pointer data_buffer)
 {
   WindowPtr pWin = (WindowPtr) param0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
index 239d558b4..ca33f1448 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Windows.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -287,6 +287,18 @@ typedef struct _ConfiguredWindow
 
 ConfiguredWindowStruct *nxagentConfiguredWindowList;
 
+typedef struct _StaticResizedWindow
+{
+  WindowPtr pWin;
+  struct _StaticResizedWindow *next;
+  struct _StaticResizedWindow *prev;
+  unsigned long sequence;
+  int offX;
+  int offY;
+} StaticResizedWindowStruct;
+
+StaticResizedWindowStruct *nxagentStaticResizedWindowList;
+
 void nxagentPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind);
 
 void nxagentFlushConfigureWindow(void);
@@ -295,6 +307,12 @@ void nxagentAddConfiguredWindow(WindowPtr pWin, unsigned int valuemask);
 
 void nxagentDeleteConfiguredWindow(WindowPtr pWin);
 
+void nxagentAddStaticResizedWindow(WindowPtr pWin, unsigned long sequence, int offX, int offY);
+
+void nxagentDeleteStaticResizedWindow(unsigned long sequence);
+
+StaticResizedWindowStruct *nxagentFindStaticResizedWindow(unsigned long sequence);
+
 void nxagentEmptyAllBackingStoreRegions(void);
 
 #endif /* __Window_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index 91e290996..a8a2a68bd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -189,6 +189,10 @@ xEvent *xeviexE;
 #include "Windows.h"
 #include "Args.h"
 
+#ifdef NX_DEBUG_INPUT
+extern int nxagentDebugInput;
+#endif
+ 
 extern Display *nxagentDisplay;
 
 extern WindowPtr nxagentLastEnteredWindow;
@@ -1682,10 +1686,27 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
     int i;
     int type;
 
-#ifdef DEBUG
+#ifdef NX_DEBUG_INPUT
+    if (grab && nxagentDebugInput && grab->window)
+    {
+	fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n",
+		(unsigned int)grab->window->drawable.id);
+	if (!SameClient(grab, client))
+		fprintf(stderr, "TryClientEvents: Events are going to be "
+			    "discarded.\n");
+    }
+#endif
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask,
+	client->index);
+#else
     if (debug_events) ErrorF(
 	"Event([%d, %d], mask=0x%x), client=%d",
 	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
 #endif
     if ((client) && (client != serverClient) && (!client->clientGone) &&
 	((filter == CantBeFiltered) || (mask & filter)))
@@ -1700,9 +1721,16 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
 		    pEvents->u.keyButtonPointer.event)
 		{
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+    {
+	fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n");
+    }
+#else
 		    if (debug_events) ErrorF("\n");
 	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
 #endif
 		    return 1; /* don't send, but pretend we did */
 		}
@@ -1740,15 +1768,25 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 	}
 
 	WriteEventsToClient(client, count, pEvents);
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, " delivered\n");
+#else
 	if (debug_events) ErrorF(  " delivered\n");
+#endif
 #endif
 	return 1;
     }
     else
     {
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "\n");
+#else
 	if (debug_events) ErrorF("\n");
+#endif
 #endif
 	return 0;
     }
@@ -3116,6 +3154,12 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
         xevieEventSent = 0;
       else {
         xeviemouse = mouse;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInput == 1)
+        {
+          fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n");
+        }
+        #endif
         WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
         return;
       }
@@ -3170,14 +3214,38 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
+	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonPress.\n");
+		}
+		return;
+	    }
+	    #else
 	    if (xE->u.u.detail == 0)
 		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!grab)
+	    #ifdef NX_DEBUG_INPUT
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		{
+		    if (nxagentDebugInput == 1)
+		    {
+			fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs"
+				" returned True for ButtonPress.\n");
+		    }
+		    return;
+		}
+	    #else
 		if (CheckDeviceGrabs(mouse, xE, 0, count))
 		    return;
+	    #endif
 	    break;
 	case ButtonRelease: 
 	    mouse->valuator->motionHintWindow = NullWindow;
@@ -3189,8 +3257,20 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
 	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonRelease.\n");
+		}
 		return;
+	    }
+	    #else
+	    if (xE->u.u.detail == 0)
+		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 	    filters[MotionNotify] = Motion_Filter(butc);
@@ -3201,6 +3281,36 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 	    FatalError("bogus pointer event from ddx");
 	}
     }
+    #ifdef NX_DEBUG_INPUT
+    else if (!CheckMotion(xE))
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False"
+		    " for MotionNotify.\n");
+	}
+	return;
+    }
+    if (grab)
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed "
+		    "events (count = %d).\n", count);
+	}
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    }
+    else
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver device "
+		    "events (count = %d).\n", count);
+	}
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    }
+    #else
     else if (!CheckMotion(xE))
 	return;
     if (grab)
@@ -3208,6 +3318,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     else
 	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
 			    mouse, count);
+    #endif
     if (deactivateGrab)
         (*mouse->DeactivateGrab)(mouse);
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index 91e290996..a8a2a68bd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -189,6 +189,10 @@ xEvent *xeviexE;
 #include "Windows.h"
 #include "Args.h"
 
+#ifdef NX_DEBUG_INPUT
+extern int nxagentDebugInput;
+#endif
+ 
 extern Display *nxagentDisplay;
 
 extern WindowPtr nxagentLastEnteredWindow;
@@ -1682,10 +1686,27 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
     int i;
     int type;
 
-#ifdef DEBUG
+#ifdef NX_DEBUG_INPUT
+    if (grab && nxagentDebugInput && grab->window)
+    {
+	fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n",
+		(unsigned int)grab->window->drawable.id);
+	if (!SameClient(grab, client))
+		fprintf(stderr, "TryClientEvents: Events are going to be "
+			    "discarded.\n");
+    }
+#endif
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask,
+	client->index);
+#else
     if (debug_events) ErrorF(
 	"Event([%d, %d], mask=0x%x), client=%d",
 	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
 #endif
     if ((client) && (client != serverClient) && (!client->clientGone) &&
 	((filter == CantBeFiltered) || (mask & filter)))
@@ -1700,9 +1721,16 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
 		    pEvents->u.keyButtonPointer.event)
 		{
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+    {
+	fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n");
+    }
+#else
 		    if (debug_events) ErrorF("\n");
 	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
 #endif
 		    return 1; /* don't send, but pretend we did */
 		}
@@ -1740,15 +1768,25 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 	}
 
 	WriteEventsToClient(client, count, pEvents);
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, " delivered\n");
+#else
 	if (debug_events) ErrorF(  " delivered\n");
+#endif
 #endif
 	return 1;
     }
     else
     {
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "\n");
+#else
 	if (debug_events) ErrorF("\n");
+#endif
 #endif
 	return 0;
     }
@@ -3116,6 +3154,12 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
         xevieEventSent = 0;
       else {
         xeviemouse = mouse;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInput == 1)
+        {
+          fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n");
+        }
+        #endif
         WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
         return;
       }
@@ -3170,14 +3214,38 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
+	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonPress.\n");
+		}
+		return;
+	    }
+	    #else
 	    if (xE->u.u.detail == 0)
 		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!grab)
+	    #ifdef NX_DEBUG_INPUT
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		{
+		    if (nxagentDebugInput == 1)
+		    {
+			fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs"
+				" returned True for ButtonPress.\n");
+		    }
+		    return;
+		}
+	    #else
 		if (CheckDeviceGrabs(mouse, xE, 0, count))
 		    return;
+	    #endif
 	    break;
 	case ButtonRelease: 
 	    mouse->valuator->motionHintWindow = NullWindow;
@@ -3189,8 +3257,20 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
 	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonRelease.\n");
+		}
 		return;
+	    }
+	    #else
+	    if (xE->u.u.detail == 0)
+		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 	    filters[MotionNotify] = Motion_Filter(butc);
@@ -3201,6 +3281,36 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 	    FatalError("bogus pointer event from ddx");
 	}
     }
+    #ifdef NX_DEBUG_INPUT
+    else if (!CheckMotion(xE))
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False"
+		    " for MotionNotify.\n");
+	}
+	return;
+    }
+    if (grab)
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed "
+		    "events (count = %d).\n", count);
+	}
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    }
+    else
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver device "
+		    "events (count = %d).\n", count);
+	}
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    }
+    #else
     else if (!CheckMotion(xE))
 	return;
     if (grab)
@@ -3208,6 +3318,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     else
 	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
 			    mouse, count);
+    #endif
     if (deactivateGrab)
         (*mouse->DeactivateGrab)(mouse);
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
index f58163488..772a1fbe5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -336,6 +336,10 @@ ProcChangeProperty(ClientPtr client)
 
       nxagentGuessShadowHint(client, stuff->property);
 
+      #ifdef NX_DEBUG_INPUT
+      nxagentGuessDumpInputInfo(client, stuff->property, (char *) &stuff[1]);
+      #endif
+
       return client->noClientException;
     }
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
index f58163488..772a1fbe5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -336,6 +336,10 @@ ProcChangeProperty(ClientPtr client)
 
       nxagentGuessShadowHint(client, stuff->property);
 
+      #ifdef NX_DEBUG_INPUT
+      nxagentGuessDumpInputInfo(client, stuff->property, (char *) &stuff[1]);
+      #endif
+
       return client->noClientException;
     }
 }
-- 
cgit v1.2.3


From fc05e5e04843762820effb5b5bb145536ddd41f0 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:56 +0200
Subject: Imported nxagent-3.3.0-13.tar.gz

Summary: Imported nxagent-3.3.0-13.tar.gz
Keywords:

Imported nxagent-3.3.0-13.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  24 +++
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 181 +++++++++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |  23 +++
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  53 ++++++
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |   5 +
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |   2 +
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |   8 +
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        |  21 ++-
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |   3 +
 nx-X11/programs/Xserver/hw/nxagent/Window.c        |   2 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |   4 +
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |   4 +
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    | 106 ++++++++++++
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    | 106 ++++++++++++
 14 files changed, 540 insertions(+), 2 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 9e746bb78..90f4949ee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,29 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 3c1458cb7..e456989cd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -803,6 +803,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         nxagentLastEventTime = GetTimeInMillis();
 
+        if (x.u.keyButtonPointer.time > nxagentLastEventTime)
+        {
+          x.u.keyButtonPointer.time = nxagentLastEventTime;
+        }
+
         if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)))
         {
           mieqEnqueue(&x);
@@ -4022,4 +4027,180 @@ void nxagentGuessDumpInputInfo(ClientPtr client, Atom property, char *data)
   }
 }
 
+void nxagentDeactivateInputDevicesGrabs()
+{
+  fprintf(stderr, "Info: Deactivating input devices grabs.\n");
+
+  if (inputInfo.pointer -> grab)
+  {
+    (*inputInfo.pointer -> DeactivateGrab)(inputInfo.pointer);
+  }
+
+  if (inputInfo.keyboard -> grab)
+  {
+    (*inputInfo.keyboard -> DeactivateGrab)(inputInfo.keyboard);
+  }
+}
+
+static const char *nxagentGrabStateToString(int state)
+{
+  switch (state)
+  {
+    case 0:
+      return "NOT_GRABBED";
+    case 1:
+      return "THAWED";
+    case 2:
+      return "THAWED_BOTH";
+    case 3:
+      return "FREEZE_NEXT_EVENT";
+    case 4:
+      return "FREEZE_BOTH_NEXT_EVENT";
+    case 5:
+      return "FROZEN_NO_EVENT";
+    case 6:
+      return "FROZEN_WITH_EVENT";
+    case 7:
+      return "THAW_OTHERS";
+    default:
+      return "unknown state";
+  }
+}
+
+void nxagentDumpInputDevicesState(void)
+{
+  int i, k;
+  int mask = 1;
+  CARD8 val;
+  DeviceIntPtr dev;
+  GrabPtr grab;
+  WindowPtr pWin = NULL;
+
+  fprintf(stderr, "\n*** Dump input devices state: BEGIN ***"
+              "\nKeys down:");
+
+  dev = inputInfo.keyboard;
+
+  for (i = 0; i < DOWN_LENGTH; i++)
+  {
+    val = dev -> key -> down[i];
+
+    if (val != 0)
+    {
+      for (k = 0; k < 8; k++)
+      {
+        if (val & (mask << k))
+        {
+          fprintf(stderr, "\n\t[%d] [%s]", i * 8 + k,
+                      XKeysymToString(XKeycodeToKeysym(nxagentDisplay, i * 8 + k, 0)));
+        }
+      }
+    }
+  }
+
+  fprintf(stderr, "\nKeyboard device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
+              "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
+                  "\n\tfrom passive grab [%s]\n\tactivating key [%d]", dev,
+                      dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes": "No",
+                          nxagentGrabStateToString(dev -> sync.state),
+                              dev -> sync.other, dev -> sync.evcount,
+                                  dev -> fromPassiveGrab ? "Yes" : "No",
+                                      dev -> activatingKey);
+
+  grab = dev -> grab;
+
+  if (grab)
+  {
+    fprintf(stderr, "\nKeyboard grab state: \n\twindow pointer [%p]"
+                "\n\towner events flag [%s]\n\tgrab mode [%s]",
+                    grab -> window, grab -> ownerEvents ? "True" : "False",
+                        grab -> keyboardMode ? "asynchronous" : "synchronous");
+
+   /*
+    * Passive grabs.
+    */
+
+    pWin = grab -> window;
+    grab = wPassiveGrabs(pWin);
+
+    while (grab)
+    {
+      fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
+                  "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
+                      "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
+                          grab -> device, grab -> ownerEvents ? "True" : "False",
+                              grab -> pointerMode ? "asynchronous" : "synchronous",
+                                  grab -> keyboardMode ? "asynchronous" : "synchronous",
+                                      grab -> type, grab -> modifiersDetail.exact,
+                                          grab -> detail.exact, grab -> eventMask);
+
+      grab = grab -> next;
+    }
+  }
+
+  fprintf(stderr, "\nButtons down:");
+
+  dev = inputInfo.pointer;
+
+  for (i = 0; i < DOWN_LENGTH; i++)
+  {
+    val = dev -> button -> down[i];
+
+    if (val != 0)
+    {
+      for (k = 0; k < 8; k++)
+      {
+        if (val & (mask << k))
+        {
+          fprintf(stderr, "\n\t[%d]", i * 8 + k);
+        }
+      }
+    }
+  }
+
+  fprintf(stderr, "\nPointer device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
+              "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
+                  "\n\tfrom passive grab [%s]\n\tactivating button [%d]", dev,
+                      dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes" : "No",
+                          nxagentGrabStateToString(dev -> sync.state),
+                              dev -> sync.other, dev -> sync.evcount,
+                                  dev -> fromPassiveGrab ? "Yes" : "No",
+                                      dev -> activatingKey);
+
+  grab = dev -> grab;
+
+  if (grab)
+  {
+    fprintf(stderr, "\nPointer grab state: \n\twindow pointer [%p]"
+                "\n\towner events flag [%s]\n\tgrab mode [%s]",
+                    grab -> window, grab -> ownerEvents ? "True" : "False",
+                        grab -> pointerMode ? "asynchronous" : "synchronous");
+
+    if (grab -> window != pWin)
+    {
+      /*
+       * Passive grabs.
+       */
+
+      grab = wPassiveGrabs(grab -> window);
+
+      while (grab)
+      {
+        fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
+                    "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
+                        "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
+                            grab -> device, grab -> ownerEvents ? "True" : "False",
+                                grab -> pointerMode ? "asynchronous" : "synchronous",
+                                    grab -> keyboardMode ? "asynchronous" : "synchronous",
+                                        grab -> type, grab -> modifiersDetail.exact,
+                                            grab -> detail.exact, grab -> eventMask);
+
+        grab = grab -> next;
+      }
+    }
+  }
+
+  fprintf(stderr, "\n*** Dump input devices state: FINISH ***\n");
+}
+
 #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index 3abc3575f..3d94e63af 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -105,6 +105,13 @@
 
 #define MINIMUM_DISPLAY_BUFFER   512
 
+#ifdef NX_DEBUG_INPUT
+extern int nxagentDebugInputDevices;
+extern unsigned long nxagentLastInputDevicesDumpTime;
+
+extern void nxagentDumpInputDevicesState(void);
+#endif
+
 /*
  * Used in the handling of the X desktop
  * manager protocol.
@@ -186,6 +193,18 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
 
   now = GetTimeInMillis();
 
+  #ifdef NX_DEBUG_INPUT
+
+  if (nxagentDebugInputDevices == 1 &&
+        now - nxagentLastInputDevicesDumpTime > 5000)
+  {
+    nxagentLastInputDevicesDumpTime = now;
+
+    nxagentDumpInputDevicesState();
+  }
+
+  #endif
+
   if (nxagentNeedConnectionChange() == 1)
   {
     #ifdef TEST
@@ -540,6 +559,8 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
 
   #endif
 
+  nxagentPrintGeometry();
+
   #ifdef BLOCKS
   fprintf(stderr, "[End block]\n");
   #endif
@@ -820,6 +841,8 @@ FIXME: Must queue multiple writes and handle
 
   #endif
 
+  nxagentPrintGeometry();
+
   #ifdef BLOCKS
   fprintf(stderr, "[End block]\n");
   #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index ea06913f8..762ab79dc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -31,6 +31,12 @@
 extern Bool nxagentWMIsRunning;
 extern Bool nxagentIpaq;
 
+#ifdef NX_DEBUG_INPUT
+int nxagentDebugInputDevices = 0;
+unsigned long nxagentLastInputDevicesDumpTime = 0;
+extern void nxagentDeactivateInputDevicesGrabs();
+#endif
+
 /*
  * Set here the required log level.
  */
@@ -209,6 +215,53 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       }
 
       #endif
+
+      #ifdef NX_DEBUG_INPUT
+
+      case XK_X:
+      case XK_x:
+      {
+        /*
+         * Used to test the input devices state.
+         */
+
+        if (X -> type == KeyPress)
+        {
+          if (nxagentDebugInputDevices == 0)
+          {
+            fprintf(stderr, "Info: Turning input devices debug ON.\n");
+    
+            nxagentDebugInputDevices = 1;
+          }
+          else
+          {
+            fprintf(stderr, "Info: Turning input devices debug OFF.\n");
+    
+            nxagentDebugInputDevices = 0;
+    
+            nxagentLastInputDevicesDumpTime = 0;
+          }
+        }
+
+        return 1;
+      }
+
+      case XK_Y:
+      case XK_y:
+      {
+        /*
+         * Used to deactivate input devices grab.
+         */
+
+        if (X -> type == KeyPress)
+        {
+          nxagentDeactivateInputDevicesGrabs();
+        }
+
+        return 1;
+      }
+
+      #endif
     }
   }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index 64dbe3b42..ca8cfc12f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -38,6 +38,11 @@ AgentOptionsRec nxagentOptionsBackup;
 
 AgentOptionsPtr nxagentOptionsPtr = &nxagentOptions;
 
+/*
+ * If this is set, print the geometry in the block handler.
+ */
+
+unsigned int nxagentPrintGeometryFlags = 0;
 /*
  * This must be called at startup to initialize
  * the options repository to the default values.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index aa78489b1..af437cd16 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -29,6 +29,8 @@
 #define UNDEFINED -1
 #define COPY_UNLIMITED -1
 
+extern unsigned int nxagentPrintGeometryFlags;
+
 typedef enum _BackingStoreMode
 {
   BackingStoreUndefined = -1,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index 69b73a942..f73d4692c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -257,7 +257,11 @@ TODO: This should be reset only when
 
       if ((dispatchException & DE_TERMINATE) == 0)
       {
+        #ifdef NX_DEBUG_INPUT
+        fprintf(stderr, "Session: Session suspended at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+        #else
         fprintf(stderr, "Session: Session suspended at '%s'.\n", GetTimeAsString());
+        #endif
       }
 
       nxagentResetDisplayHandlers();
@@ -609,7 +613,11 @@ Bool nxagentReconnectSession(void)
     goto nxagentReconnectError;
   }
 
+  #ifdef NX_DEBUG_INPUT
+  fprintf(stderr, "Session: Session resumed at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+  #else
   fprintf(stderr, "Session: Session resumed at '%s'.\n", GetTimeAsString());
+  #endif
 
   nxagentRemoveSplashWindow(NULL);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 524bafd10..fa08e05b0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -2373,8 +2373,7 @@ FIXME: We should try to restore the previously
   nxagentPrintAgentGeometry("After Resize Screen", "nxagentResizeScreen:");
   #endif
 
-  fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d].\n",
-              pScreen -> myNum, width, height);
+  nxagentSetPrintGeometry(pScreen -> myNum);
 
   return 1;
 
@@ -3903,6 +3902,24 @@ void nxagentShadowAdaptToRatio(void)
   REGION_UNINIT(pScreen, &region);
 }
 
+void nxagentPrintGeometry()
+{
+  int i;
+
+  for (i = 0; i < screenInfo.numScreens; i++)
+  {
+    if (nxagentPrintGeometryFlags && (1 << i))
+    {
+      fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d] "
+                  "fullscreen [%d].\n", i, screenInfo.screens[i] -> width,
+                      screenInfo.screens[i] -> height,
+                          nxagentOption(Fullscreen));
+    }
+  }
+
+  nxagentPrintGeometryFlags = 0;
+}
+
 #ifdef DUMP
 
 void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 3550dd553..73af3cc50 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -36,6 +36,9 @@ is" without express or implied warranty.
 #define MIN_NXAGENT_HEIGHT 60
 #define NXAGENT_FRAME_WIDTH 2000
 
+#define nxagentSetPrintGeometry(screen) \
+    nxagentPrintGeometryFlags = (1 << (screen));
+    
 extern int nxagentClients;
 
 extern int nxagentAutoDisconnectTimeout;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 8da5d8bd1..8c94b24b5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -908,6 +908,8 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 
   XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
                         nxagentOption(Width), nxagentOption(Height));
+
+  nxagentSetPrintGeometry(pScreen -> myNum);
 }
 
 #ifdef VIEWPORT_FRAME
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index f84ca0e03..d267adbc9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -515,7 +515,11 @@ Dispatch(void)
 
     if (serverGeneration > nxagentMaxAllowedResets)
     {
+      #ifdef NX_DEBUG_INPUT
+      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+      #else
       fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+      #endif
 
       nxagentSessionState = SESSION_UP;
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index f84ca0e03..d267adbc9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -515,7 +515,11 @@ Dispatch(void)
 
     if (serverGeneration > nxagentMaxAllowedResets)
     {
+      #ifdef NX_DEBUG_INPUT
+      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+      #else
       fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+      #endif
 
       nxagentSessionState = SESSION_UP;
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index a8a2a68bd..1c141c015 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -191,6 +191,7 @@ xEvent *xeviexE;
 
 #ifdef NX_DEBUG_INPUT
 extern int nxagentDebugInput;
+extern int nxagentDebugInputDevices;
 #endif
  
 extern Display *nxagentDisplay;
@@ -1865,6 +1866,12 @@ DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n");
+        }
+        #endif
 	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
 					   currentTime, TRUE);
     }
@@ -2735,6 +2742,13 @@ CheckPassiveGrabsOnWindow(
 				tempGrab.modifiersDetail.exact&(~0x1f00);
 	    }
 #endif
+            #ifdef NX_DEBUG_INPUT
+            if (nxagentDebugInputDevices == 1)
+            {
+              fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n",
+                          device == inputInfo.keyboard ? "keyboard" : "pointer");
+            }
+            #endif
 	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  
 	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
@@ -3093,7 +3107,17 @@ drawable.id:0;
     else
 	DeliverFocusedEvent(keybd, xE, sprite.win, count);
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n");
+      }
+    #endif
         (*keybd->DeactivateGrab)(keybd);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #ifdef XKB
@@ -3320,7 +3344,17 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 			    mouse, count);
     #endif
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n");
+      }
+    #endif
         (*mouse->DeactivateGrab)(mouse);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #define AtMostOneClient \
@@ -4041,6 +4075,12 @@ ProcGrabPointer(ClientPtr client)
     pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
     if (!pWin)
 	return BadWindow;
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index);
+    }
+    #endif
     if (stuff->confineTo == None)
 	confineTo = NullWindow;
     else 
@@ -4100,6 +4140,12 @@ ProcGrabPointer(ClientPtr client)
 	tempGrab.keyboardMode = stuff->keyboardMode;
 	tempGrab.pointerMode = stuff->pointerMode;
 	tempGrab.device = device;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n");
+        }
+        #endif
 	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
 	if (oldCursor)
 	    FreeCursor (oldCursor, (Cursor)0);
@@ -4163,6 +4209,12 @@ ProcUngrabPointer(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4170,7 +4222,25 @@ ProcUngrabPointer(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	    (grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
@@ -4225,6 +4295,12 @@ GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
 	tempGrab.pointerMode = other_mode;
 	tempGrab.eventMask = mask;
 	tempGrab.device = dev;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n");
+        }
+        #endif
 	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4238,6 +4314,12 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST(xGrabKeyboardReq);
     int result;
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 #ifdef XCSECURITY
     if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
@@ -4268,6 +4350,12 @@ ProcUngrabKeyboard(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4275,7 +4363,25 @@ ProcUngrabKeyboard(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	(grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index a8a2a68bd..1c141c015 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -191,6 +191,7 @@ xEvent *xeviexE;
 
 #ifdef NX_DEBUG_INPUT
 extern int nxagentDebugInput;
+extern int nxagentDebugInputDevices;
 #endif
  
 extern Display *nxagentDisplay;
@@ -1865,6 +1866,12 @@ DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n");
+        }
+        #endif
 	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
 					   currentTime, TRUE);
     }
@@ -2735,6 +2742,13 @@ CheckPassiveGrabsOnWindow(
 				tempGrab.modifiersDetail.exact&(~0x1f00);
 	    }
 #endif
+            #ifdef NX_DEBUG_INPUT
+            if (nxagentDebugInputDevices == 1)
+            {
+              fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n",
+                          device == inputInfo.keyboard ? "keyboard" : "pointer");
+            }
+            #endif
 	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  
 	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
@@ -3093,7 +3107,17 @@ drawable.id:0;
     else
 	DeliverFocusedEvent(keybd, xE, sprite.win, count);
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n");
+      }
+    #endif
         (*keybd->DeactivateGrab)(keybd);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #ifdef XKB
@@ -3320,7 +3344,17 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 			    mouse, count);
     #endif
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n");
+      }
+    #endif
         (*mouse->DeactivateGrab)(mouse);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #define AtMostOneClient \
@@ -4041,6 +4075,12 @@ ProcGrabPointer(ClientPtr client)
     pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
     if (!pWin)
 	return BadWindow;
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index);
+    }
+    #endif
     if (stuff->confineTo == None)
 	confineTo = NullWindow;
     else 
@@ -4100,6 +4140,12 @@ ProcGrabPointer(ClientPtr client)
 	tempGrab.keyboardMode = stuff->keyboardMode;
 	tempGrab.pointerMode = stuff->pointerMode;
 	tempGrab.device = device;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n");
+        }
+        #endif
 	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
 	if (oldCursor)
 	    FreeCursor (oldCursor, (Cursor)0);
@@ -4163,6 +4209,12 @@ ProcUngrabPointer(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4170,7 +4222,25 @@ ProcUngrabPointer(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	    (grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
@@ -4225,6 +4295,12 @@ GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
 	tempGrab.pointerMode = other_mode;
 	tempGrab.eventMask = mask;
 	tempGrab.device = dev;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n");
+        }
+        #endif
 	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4238,6 +4314,12 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST(xGrabKeyboardReq);
     int result;
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 #ifdef XCSECURITY
     if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
@@ -4268,6 +4350,12 @@ ProcUngrabKeyboard(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4275,7 +4363,25 @@ ProcUngrabKeyboard(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	(grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
-- 
cgit v1.2.3


From 22914447019845ba3ba238e5814b59939e744f19 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:56 +0200
Subject: Imported nxagent-3.3.0-18.tar.gz

Summary: Imported nxagent-3.3.0-18.tar.gz
Keywords:

Imported nxagent-3.3.0-18.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG   | 32 ++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c | 24 +++++++
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c  | 17 ++++-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h    |  2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c   | 15 +++++
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c     | 87 ++++++++++++++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c  | 64 ++++++++++++++-----
 nx-X11/programs/Xserver/hw/nxagent/Screen.c    | 19 ++++--
 8 files changed, 237 insertions(+), 23 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 90f4949ee..1adbcb938 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,37 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index a575cabe5..febfe708d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -680,6 +680,30 @@ void nxagentCollectPropertyEvent(int resource)
 
     return;
   }
+ 
+  if (resultFormat != 8 && resultFormat != 16 && resultFormat != 32)
+  {
+
+    #ifdef DEBUG
+    fprintf (stderr, "nxagentCollectPropertyEvent: WARNING! Invalid property "
+                 "value.\n");
+    #endif
+
+    if (lastClientClientPtr != NULL)
+    {
+      nxagentSendSelectionNotify(None);
+    }
+
+    lastClientWindowPtr = NULL;
+    lastClientStage = SelectionStageNone;
+
+    if (pszReturnData != NULL)
+    {
+      XFree(pszReturnData);
+    }
+
+    return;
+  }
 
   switch (lastClientStage)
   {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
index 75758679f..fe0e567f6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -291,9 +291,20 @@ void nxagentSetInstalledColormapWindows(ScreenPtr pScreen)
 	  pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
 					      RT_COLORMAP);
 
-	XSetWindowColormap(nxagentDisplay,
-			   nxagentDefaultWindows[pScreen->myNum],
-			   nxagentColormap(pCmap));
+        if (pCmap != NULL)
+        {
+          XSetWindowColormap(nxagentDisplay,
+	                         nxagentDefaultWindows[pScreen->myNum],
+                                     nxagentColormap(pCmap));
+        }
+        #ifdef WARNING
+        else
+        {
+          fprintf(stderr, "nxagentSetInstalledColormapWindows: WARNING! "
+                      "Window at [%p] has no colormap with class [%d].\n",
+                          pWin, pWin -> drawable.class);
+        }
+        #endif
       }
 #endif /* DUMB_WINDOW_MANAGERS */
   }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
index 135cd2df3..a28329457 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -42,7 +42,7 @@ extern int nxagentKillDialogPid;
 extern int nxagentSuspendDialogPid;
 extern int nxagentRootlessDialogPid;
 extern int nxagentPulldownDialogPid;
-extern int nxagentFontsReplacement;
+extern int nxagentFontsReplacementDialogPid;
 extern int nxagentEnableRandRModeDialogPid;
 extern int nxagentDisableRandRModeDialogPid;
 extern int nxagentEnableDeferModePid;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index 9f257e508..8d72654e6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -453,6 +453,21 @@ static void nxagentSigchldHandler(int signal)
     }
   }
 
+  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);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index 83aa04f11..9afd6e392 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -594,6 +594,8 @@ RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
   unsigned int format;
   unsigned long planeMask = 0xffffffff;
 
+  int oldDstxyValue;
+
   RegionPtr pDstRegion;
 
   int skip = 0;
@@ -605,6 +607,91 @@ RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
                           (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
   #endif
 
+ /*
+  * Here, before using fbDoCopy() called by fbCopyArea(),
+  * it should be provided that the cast in fbDoCopy() from
+  * int to short int would not cut off significative bits.
+  */
+
+  if (dstx + pDstDrawable->x + width > 32767)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: x2 exceeding short int.\n");
+    #endif
+
+    width = 32767 - dstx - pDstDrawable->x;
+
+    if (width <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on x2 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+  if (dstx + pDstDrawable->x < -32768)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: x1 exceeding short int.\n");
+    #endif
+
+    width += pDstDrawable->x + dstx + 32768;
+    srcx  -= pDstDrawable->x + dstx + 32768;
+    dstx = -32768 - pDstDrawable->x;
+
+    if (width <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on x1 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+    oldDstxyValue = dsty;
+
+  if (dsty + pDstDrawable->y + height > 32767)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: y2 exceeding short int.\n");
+    #endif
+
+    height = 32767 - dsty - pDstDrawable->y;
+
+    if (height <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on y2 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+  if (dsty + pDstDrawable->y < -32768)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: y1 exceeding short int.\n");
+    #endif
+
+    height += 32768 + pDstDrawable->y + dsty;
+    srcy   -= 32768 + pDstDrawable->y + dsty;
+    dsty = -32768 - pDstDrawable->y;
+
+    if (height <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on y1 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+
   if (nxagentGCTrap == 1 || nxagentShmTrap == 1)
   {
     if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index 79cb74efa..e192cd2c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -60,6 +60,27 @@ typedef struct
 }
 nxagentWMHints;
 
+/*
+ * This structure is compatible with 32
+ * and 64 bit library interface. It has
+ * been copied from Xatomtype.h and it's
+ * a parameter of XChangeProperty().
+ */
+
+typedef struct
+{
+  unsigned long flags;
+  long          input;
+  long          initialState;
+  unsigned long iconPixmap;
+  unsigned long iconWindow;
+  long          iconX;
+  long          iconY;
+  unsigned long iconMask;
+  unsigned long windowGroup;
+}
+nxagentPropWMHints;
+
 WindowPtr nxagentRootlessWindow = NULL;
 
 #define TOP_LEVEL_TABLE_UNIT 100
@@ -429,6 +450,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
   Atom propertyX, typeX;
   char *output = NULL;
   nxagentWMHints wmHints;
+  nxagentPropWMHints propHints;
   Bool export = False;
   Bool freeMem = False;
 
@@ -489,8 +511,22 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     wmHints.flags |= InputHint;
     wmHints.input = True;
 
-    output = (char*) &wmHints;
-    export  = True;
+    /*
+     * Initialize the structure used in XChangeProperty().
+     */
+
+    propHints.flags = wmHints.flags;
+    propHints.input = (wmHints.input == True ? 1 : 0);
+    propHints.initialState = wmHints.initial_state;
+    propHints.iconPixmap = wmHints.icon_pixmap;
+    propHints.iconWindow = wmHints.icon_window;
+    propHints.iconX = wmHints.icon_x;
+    propHints.iconY = wmHints.icon_y;
+    propHints.iconMask = wmHints.icon_mask;
+    propHints.windowGroup = wmHints.window_group;
+
+    output = (char*) &propHints;
+    export = True;
 
     if ((wmHints.flags & IconPixmapHint) && (wmHints.icon_pixmap != None))
     {
@@ -504,17 +540,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
           nxagentSynchronizeRegion((DrawablePtr) icon, NullRegion, NEVER_BREAK, NULL);
         }
 
-        wmHints.icon_pixmap = nxagentPixmap(icon);
+        propHints.iconPixmap = nxagentPixmap(icon);
       }
       else
       {
-        wmHints.flags &= ~IconPixmapHint;
+        propHints.flags &= ~IconPixmapHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon pixmap %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_pixmap, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
@@ -526,17 +562,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (icon)
       {
-        wmHints.icon_window = nxagentWindow(icon);
+        propHints.iconWindow = nxagentWindow(icon);
       }
       else
       {
-        wmHints.flags &= ~IconWindowHint;
+        propHints.flags &= ~IconWindowHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon window %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_window, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
@@ -548,17 +584,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (icon)
       {
-        wmHints.icon_mask = nxagentPixmap(icon);
+        propHints.iconMask = nxagentPixmap(icon);
       }
       else
       {
-        wmHints.flags &= ~IconMaskHint;
+        propHints.flags &= ~IconMaskHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon mask %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_mask, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
@@ -570,17 +606,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (window)
       {
-        wmHints.window_group = nxagentWindow(window);
+        propHints.windowGroup = nxagentWindow(window);
       }
       else
       {
-        wmHints.flags &= ~WindowGroupHint;
+        propHints.flags &= ~WindowGroupHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window group %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.window_group, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index fa08e05b0..f643cb98c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -3045,7 +3045,7 @@ void nxagentShadowAdaptDepth(unsigned int width, unsigned int height,
     #ifdef WARNING
     fprintf(stderr, "nxagentCorrectDepthShadow: WARNING! Visual not found. Using default visual.\n");
     #endif
-    
+
     pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
   }
 
@@ -3472,10 +3472,10 @@ int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height)
     RRScreenSizePtr oldSizes;
 
     pScrPriv = rrGetScrPriv(pScreen);
-   
+
     oldWidth = pScreen->width;
     oldHeight = pScreen->height;
-    
+
     if (!pScrPriv)
     {
       return 1;
@@ -3555,7 +3555,7 @@ int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height)
     }
 
     RREditConnectionInfo (pScreen);
-    
+
     /*
      * Fix pointer bounds and location
      */
@@ -3693,7 +3693,8 @@ void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg,
   return;
 }
 
-void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int yorg, WindowPtr pWin)
+void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg,
+                             int yorg, WindowPtr pWin)
 {
   PixmapPtr pVirtualPixmap;
   RegionPtr clipRegion;
@@ -3709,6 +3710,14 @@ void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int
   BoxRec extents;
   miBSWindowPtr pBackingStore;
 
+  /*
+   * Limit the area to restore to the
+   * root window size.
+   */
+
+  REGION_INTERSECT(pWin -> pScreen, prgnRestore, prgnRestore,
+                       &WindowTable[pWin -> drawable.pScreen -> myNum] -> winSize);
+
   pBackingStore = (miBSWindowPtr) pWin -> backStorage;
 
   pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
-- 
cgit v1.2.3


From 45b970f25634519dac302a5691a7a2d45f8db49f Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:56 +0200
Subject: Imported nxagent-3.3.0-6.tar.gz

Summary: Imported nxagent-3.3.0-6.tar.gz
Keywords:

Imported nxagent-3.3.0-6.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  91 ----
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |  24 --
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c      |  17 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |  15 -
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |  94 ++---
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 221 +---------
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |  41 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         |  87 ----
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |  23 --
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      | 459 +++++----------------
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   4 -
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  53 ---
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |   5 -
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |   2 -
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |  39 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      |  64 +--
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        |  40 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |   3 -
 nx-X11/programs/Xserver/hw/nxagent/Window.c        |   2 -
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |   4 -
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |   4 -
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    | 225 +---------
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    | 225 +---------
 25 files changed, 214 insertions(+), 1539 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 1adbcb938..17b69c3f2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,96 +1,5 @@
 ChangeLog:
 
-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.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index febfe708d..a575cabe5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -680,30 +680,6 @@ void nxagentCollectPropertyEvent(int resource)
 
     return;
   }
- 
-  if (resultFormat != 8 && resultFormat != 16 && resultFormat != 32)
-  {
-
-    #ifdef DEBUG
-    fprintf (stderr, "nxagentCollectPropertyEvent: WARNING! Invalid property "
-                 "value.\n");
-    #endif
-
-    if (lastClientClientPtr != NULL)
-    {
-      nxagentSendSelectionNotify(None);
-    }
-
-    lastClientWindowPtr = NULL;
-    lastClientStage = SelectionStageNone;
-
-    if (pszReturnData != NULL)
-    {
-      XFree(pszReturnData);
-    }
-
-    return;
-  }
 
   switch (lastClientStage)
   {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
index fe0e567f6..75758679f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -291,20 +291,9 @@ void nxagentSetInstalledColormapWindows(ScreenPtr pScreen)
 	  pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
 					      RT_COLORMAP);
 
-        if (pCmap != NULL)
-        {
-          XSetWindowColormap(nxagentDisplay,
-	                         nxagentDefaultWindows[pScreen->myNum],
-                                     nxagentColormap(pCmap));
-        }
-        #ifdef WARNING
-        else
-        {
-          fprintf(stderr, "nxagentSetInstalledColormapWindows: WARNING! "
-                      "Window at [%p] has no colormap with class [%d].\n",
-                          pWin, pWin -> drawable.class);
-        }
-        #endif
+	XSetWindowColormap(nxagentDisplay,
+			   nxagentDefaultWindows[pScreen->myNum],
+			   nxagentColormap(pCmap));
       }
 #endif /* DUMB_WINDOW_MANAGERS */
   }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
index a28329457..135cd2df3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -42,7 +42,7 @@ extern int nxagentKillDialogPid;
 extern int nxagentSuspendDialogPid;
 extern int nxagentRootlessDialogPid;
 extern int nxagentPulldownDialogPid;
-extern int nxagentFontsReplacementDialogPid;
+extern int nxagentFontsReplacement;
 extern int nxagentEnableRandRModeDialogPid;
 extern int nxagentDisableRandRModeDialogPid;
 extern int nxagentEnableDeferModePid;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index 8d72654e6..9f257e508 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -453,21 +453,6 @@ static void nxagentSigchldHandler(int signal)
     }
   }
 
-  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);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 82723b5a0..2c1b07fa5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -32,7 +32,6 @@
 #include "Handlers.h"
 #include "Pixels.h"
 #include "Reconnect.h"
-#include "GCOps.h"
 
 #include "NXlib.h"
 
@@ -419,14 +418,13 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   if (useStoredBitmap != 0)
   {
     #ifdef TEST
-    fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap at [%p] "
+    fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap "
                 "[%d,%d,%d,%d] with [%ld] rects.\n", nxagentDrawableType(pDrawable),
-                    (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable),
-                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
-                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
-                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
-                                    nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
-                                        REGION_NUM_RECTS(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
+                    (void *) pDrawable, nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
+                                    REGION_NUM_RECTS(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
     #endif
 
     clipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
@@ -583,7 +581,8 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
   #ifdef TEST
   fprintf(stderr, "nxagentSynchronizeRegion: Going to synchronize [%ld] rects of [%s] at [%p].\n",
-              REGION_NUM_RECTS(clipRegion), nxagentDrawableType(pDrawable), (void *) pDrawable);
+              REGION_NUM_RECTS(clipRegion), (pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window"),
+                  (void *) pDrawable);
 
   fprintf(stderr, "nxagentSynchronizeRegion: Extents geometry [%d,%d,%d,%d].\n",
           clipRegion -> extents.x1, clipRegion -> extents.y1, clipRegion -> extents.x2, clipRegion -> extents.y2);
@@ -616,22 +615,7 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   if (data == NULL)
   {
     #ifdef WARNING
-
     fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to allocate memory for synchronization.\n");
-
-    /*
-     * Print detailed informations if the
-     * image length is zero.
-     */
-
-    if (length == 0)
-    {
-      fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] with region geometry [%ld][%d,%d,%d,%d].\n",
-                  nxagentDrawableType(pDrawable), (void *) pDrawable, REGION_NUM_RECTS(clipRegion),
-                      clipRegion -> extents.x1, clipRegion -> extents.y1,
-                          clipRegion -> extents.x2, clipRegion -> extents.y2);
-    }
-
     #endif
 
     goto nxagentSynchronizeRegionFree;
@@ -686,14 +670,10 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
         if (nxagentDrawableStatus(pDrawable) == Synchronized)
         {
           #ifdef WARNING
-
           if (pDrawable -> type == DRAWABLE_WINDOW && pSrcDrawable != pDrawable)
-          {
             fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Trying to synchronize "
                         "the clean drawable type [%d] at [%p] with source at [%p].\n",
                             pDrawable -> type, (void *) pDrawable, (void *) pSrcDrawable);
-          }
-
           #endif
 
           goto nxagentSynchronizeRegionStop;
@@ -768,6 +748,9 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
         nxagentGetImage(pSrcDrawable, x, y, w, h, format, AllPlanes, data);
 
+        nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
+                                x, y, w, h, leftPad, format, data);
+
         /*
          * Going to unmark the synchronized
          * region.
@@ -822,13 +805,6 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
                 nxagentUnmarkCorruptedRegion(pDrawable, &tileRegion);
               }
-              #ifdef TEST
-              else
-              {
-                fprintf(stderr, "nxagentSynchronizeRegion: Tile [%d,%d,%d,%d] on drawable [%p] doesn't match.\n",
-                            x, y, x + w, y + h, (void *) pDrawable);
-              }
-              #endif
             }
             else
             {
@@ -859,14 +835,6 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
           }
         }
 
-        /*
-         * Realize the image after comparing the
-         * source data with the bitmap data.
-         */
-
-        nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
-                                x, y, w, h, leftPad, format, data);
-
         REGION_UNINIT(pDrawable -> pScreen, &tileRegion);
 
         #if !defined(COLLECTED_UPDATES)
@@ -2587,13 +2555,16 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
   GCPtr pGC = NULL;
   RegionPtr pClipRegion = NullRegion;
 
+  char *data = NULL;
+
   int x, y;
   int w, h;
+  int length, format;
   int saveTrap;
 
   #ifdef TEST
-  fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for [%s] at [%p].\n",
-              nxagentDrawableType(pDrawable), (void *) pDrawable);
+  fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for drawable at [%p].\n",
+              (void *) pDrawable);
   #endif
 
   /*
@@ -2681,8 +2652,24 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
   w = pClipRegion -> extents.x2 - pClipRegion -> extents.x1;
   h = pClipRegion -> extents.y2 - pClipRegion -> extents.y1;
 
-  nxagentCopyArea(pDrawable, (DrawablePtr) pBitmap, pGC, x, y, w, h, x, y);
+  data = nxagentAllocateImageData(w, h, pDrawable -> depth, &length, &format);
+
+  if (data == NULL)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCreateDrawableBitmap: Cannot allocate memory for the bitmap data.\n");
+    #endif
+
+    nxagentDestroyPixmap(pBitmap);
 
+    goto nxagentCreateDrawableBitmapEnd;
+  }
+
+  nxagentGetImage(pDrawable, x, y, w, h, format, AllPlanes, data);
+
+  nxagentPutImage((DrawablePtr) pBitmap, pGC, pBitmap -> drawable.depth, x, y, w, h,
+                      0, format, data);
+ 
   REGION_UNION(pDrawable -> pScreen, nxagentCorruptedRegion((DrawablePtr) pBitmap),
                    nxagentCorruptedRegion((DrawablePtr) pBitmap), pClipRegion);
 
@@ -2724,6 +2711,11 @@ nxagentCreateDrawableBitmapEnd:
     nxagentFreeRegion(pDrawable, pClipRegion);
   }
 
+  if (data != NULL)
+  {
+    xfree(data);
+  }
+
   if (pGC != NULL)
   {
     FreeScratchGC(pGC);
@@ -3099,16 +3091,6 @@ void nxagentSendBackgroundExpose(WindowPtr pWin, PixmapPtr pBackground, RegionPt
 
   REGION_INTERSECT(pWin -> pScreen, &expose, &expose, &pWin -> clipList);
 
-  /*
-   * Reduce the overall region to expose.
-   */
-  
-  REGION_TRANSLATE(pWin -> pScreen, &expose, -pWin -> drawable.x, -pWin -> drawable.y);
-  
-  REGION_SUBTRACT(pWin -> pScreen, pExpose, pExpose, &expose);
-  
-  REGION_TRANSLATE(pWin -> pScreen, &expose, pWin -> drawable.x, pWin -> drawable.y);
-
   miWindowExposures(pWin, &expose, &expose);
 
 nxagentSendBackgroundExposeEnd:
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index e456989cd..ab8c13cae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -63,13 +63,7 @@
 #include "NXproto.h"
 
 #include "xfixesproto.h"
-#define Window     XlibWindow
-#define Atom   XlibAtom
-#define Time XlibXID
 #include <X11/extensions/Xfixes.h>
-#undef Window
-#undef Atom
-#undef Time
 
 #ifdef NXAGENT_FIXKEYS
 #include "inputstr.h"
@@ -795,19 +789,13 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         }
 
         x.u.u.type = KeyRelease;
-        x.u.u.detail = nxagentConvertKeycode(X.xkey.keycode);
-        x.u.keyButtonPointer.time = nxagentLastKeyPressTime +
-            (X.xkey.time - nxagentLastServerTime);
+        x.u.u.detail = X.xkey.keycode;
+        x.u.keyButtonPointer.time = nxagentLastKeyPressTime + (X.xkey.time - nxagentLastServerTime);
 
         nxagentLastServerTime = X.xkey.time;
 
         nxagentLastEventTime = GetTimeInMillis();
 
-        if (x.u.keyButtonPointer.time > nxagentLastEventTime)
-        {
-          x.u.keyButtonPointer.time = nxagentLastEventTime;
-        }
-
         if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)))
         {
           mieqEnqueue(&x);
@@ -930,7 +918,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         #ifdef NX_DEBUG_INPUT
         if (nxagentDebugInput == 1)
         {
-          fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonRelease event.\n");
+          fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonPress event.\n");
         }
         #endif
 
@@ -1028,17 +1016,18 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
             nxagentLastEnteredWindow = pWin;
           }
 
-          if (nxagentPulldownDialogPid == 0 && nxagentLastEnteredTopLevelWindow &&
-                  (X.xmotion.y_root < nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
+          if (nxagentPulldownDialogPid == 0 && (X.xmotion.y_root <
+                  nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
           {
-            if (pWin && nxagentClientIsDialog(wClient(pWin)) == 0 &&
-                    nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
-                        nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
-                            X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
-                                (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
-                                    X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
-                                        (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
-                                            nxagentOption(Menu) == 1)
+            if (pWin && nxagentLastEnteredTopLevelWindow &&
+                    nxagentClientIsDialog(wClient(pWin)) == 0 &&
+                        nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
+                            nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
+                                X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                    (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
+                                        X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                            (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
+                                                nxagentOption(Menu) == 1)
             {
               nxagentPulldownDialog(nxagentLastEnteredTopLevelWindow -> drawable.id);
             }
@@ -1063,8 +1052,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           #ifdef NX_DEBUG_INPUT
           if (nxagentDebugInput == 1)
           {
-            fprintf(stderr, "nxagentDispatchEvents: Adding motion event [%d, %d] to the queue.\n",
-                        x.u.keyButtonPointer.rootX, x.u.keyButtonPointer.rootY);
+            fprintf(stderr, "nxagentDispatchEvents: Adding motion event [%d, %d] to the queue.\n", x.u.keyButtonPointer.rootX, x.u.keyButtonPointer.rootY);
           }
           #endif
 
@@ -1923,9 +1911,8 @@ int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
 
   nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
 
-  
   x.u.u.type = KeyPress;
-  x.u.u.detail = nxagentConvertKeycode(X -> xkey.keycode);
+  x.u.u.detail = X -> xkey.keycode;
   x.u.keyButtonPointer.time = nxagentLastKeyPressTime;
 
   nxagentLastServerTime = X -> xkey.time;
@@ -4027,180 +4014,4 @@ void nxagentGuessDumpInputInfo(ClientPtr client, Atom property, char *data)
   }
 }
 
-void nxagentDeactivateInputDevicesGrabs()
-{
-  fprintf(stderr, "Info: Deactivating input devices grabs.\n");
-
-  if (inputInfo.pointer -> grab)
-  {
-    (*inputInfo.pointer -> DeactivateGrab)(inputInfo.pointer);
-  }
-
-  if (inputInfo.keyboard -> grab)
-  {
-    (*inputInfo.keyboard -> DeactivateGrab)(inputInfo.keyboard);
-  }
-}
-
-static const char *nxagentGrabStateToString(int state)
-{
-  switch (state)
-  {
-    case 0:
-      return "NOT_GRABBED";
-    case 1:
-      return "THAWED";
-    case 2:
-      return "THAWED_BOTH";
-    case 3:
-      return "FREEZE_NEXT_EVENT";
-    case 4:
-      return "FREEZE_BOTH_NEXT_EVENT";
-    case 5:
-      return "FROZEN_NO_EVENT";
-    case 6:
-      return "FROZEN_WITH_EVENT";
-    case 7:
-      return "THAW_OTHERS";
-    default:
-      return "unknown state";
-  }
-}
-
-void nxagentDumpInputDevicesState(void)
-{
-  int i, k;
-  int mask = 1;
-  CARD8 val;
-  DeviceIntPtr dev;
-  GrabPtr grab;
-  WindowPtr pWin = NULL;
-
-  fprintf(stderr, "\n*** Dump input devices state: BEGIN ***"
-              "\nKeys down:");
-
-  dev = inputInfo.keyboard;
-
-  for (i = 0; i < DOWN_LENGTH; i++)
-  {
-    val = dev -> key -> down[i];
-
-    if (val != 0)
-    {
-      for (k = 0; k < 8; k++)
-      {
-        if (val & (mask << k))
-        {
-          fprintf(stderr, "\n\t[%d] [%s]", i * 8 + k,
-                      XKeysymToString(XKeycodeToKeysym(nxagentDisplay, i * 8 + k, 0)));
-        }
-      }
-    }
-  }
-
-  fprintf(stderr, "\nKeyboard device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
-              "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
-                  "\n\tfrom passive grab [%s]\n\tactivating key [%d]", dev,
-                      dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes": "No",
-                          nxagentGrabStateToString(dev -> sync.state),
-                              dev -> sync.other, dev -> sync.evcount,
-                                  dev -> fromPassiveGrab ? "Yes" : "No",
-                                      dev -> activatingKey);
-
-  grab = dev -> grab;
-
-  if (grab)
-  {
-    fprintf(stderr, "\nKeyboard grab state: \n\twindow pointer [%p]"
-                "\n\towner events flag [%s]\n\tgrab mode [%s]",
-                    grab -> window, grab -> ownerEvents ? "True" : "False",
-                        grab -> keyboardMode ? "asynchronous" : "synchronous");
-
-   /*
-    * Passive grabs.
-    */
-
-    pWin = grab -> window;
-    grab = wPassiveGrabs(pWin);
-
-    while (grab)
-    {
-      fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
-                  "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
-                      "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
-                          grab -> device, grab -> ownerEvents ? "True" : "False",
-                              grab -> pointerMode ? "asynchronous" : "synchronous",
-                                  grab -> keyboardMode ? "asynchronous" : "synchronous",
-                                      grab -> type, grab -> modifiersDetail.exact,
-                                          grab -> detail.exact, grab -> eventMask);
-
-      grab = grab -> next;
-    }
-  }
-
-  fprintf(stderr, "\nButtons down:");
-
-  dev = inputInfo.pointer;
-
-  for (i = 0; i < DOWN_LENGTH; i++)
-  {
-    val = dev -> button -> down[i];
-
-    if (val != 0)
-    {
-      for (k = 0; k < 8; k++)
-      {
-        if (val & (mask << k))
-        {
-          fprintf(stderr, "\n\t[%d]", i * 8 + k);
-        }
-      }
-    }
-  }
-
-  fprintf(stderr, "\nPointer device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
-              "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
-                  "\n\tfrom passive grab [%s]\n\tactivating button [%d]", dev,
-                      dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes" : "No",
-                          nxagentGrabStateToString(dev -> sync.state),
-                              dev -> sync.other, dev -> sync.evcount,
-                                  dev -> fromPassiveGrab ? "Yes" : "No",
-                                      dev -> activatingKey);
-
-  grab = dev -> grab;
-
-  if (grab)
-  {
-    fprintf(stderr, "\nPointer grab state: \n\twindow pointer [%p]"
-                "\n\towner events flag [%s]\n\tgrab mode [%s]",
-                    grab -> window, grab -> ownerEvents ? "True" : "False",
-                        grab -> pointerMode ? "asynchronous" : "synchronous");
-
-    if (grab -> window != pWin)
-    {
-      /*
-       * Passive grabs.
-       */
-
-      grab = wPassiveGrabs(grab -> window);
-
-      while (grab)
-      {
-        fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
-                    "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
-                        "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
-                            grab -> device, grab -> ownerEvents ? "True" : "False",
-                                grab -> pointerMode ? "asynchronous" : "synchronous",
-                                    grab -> keyboardMode ? "asynchronous" : "synchronous",
-                                        grab -> type, grab -> modifiersDetail.exact,
-                                            grab -> detail.exact, grab -> eventMask);
-
-        grab = grab -> next;
-      }
-    }
-  }
-
-  fprintf(stderr, "\n*** Dump input devices state: FINISH ***\n");
-}
-
 #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index 87f9f0201..3f1fd0b43 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -65,34 +65,26 @@ is" without express or implied warranty.
 #define NXAGENT_ALTERNATE_FONT_DIR    "/usr/share/X11/fonts"
 #define NXAGENT_ALTERNATE_FONT_DIR_2  "/usr/share/fonts/X11"
 #define NXAGENT_ALTERNATE_FONT_DIR_3  "/usr/share/fonts"
-#define NXAGENT_ALTERNATE_FONT_DIR_4  "/usr/NX/share/fonts"
 
 #define NXAGENT_DEFAULT_FONT_PATH  \
 "/usr/X11R6/lib/X11/fonts/misc/,/usr/X11R6/lib/X11/fonts/Speedo/,\
 /usr/X11R6/lib/X11/fonts/Type1/,/usr/X11R6/lib/X11/fonts/75dpi/,\
-/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/,\
-/usr/NX/share/fonts/base"
+/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/"
 
 #define NXAGENT_ALTERNATE_FONT_PATH  \
 "/usr/share/X11/fonts/misc/,/usr/share/X11/fonts/Speedo/,\
 /usr/share/X11/fonts/Type1/,/usr/share/X11/fonts/75dpi/,\
-/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/,\
-/usr/NX/share/fonts/base"
+/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/"
 
 #define NXAGENT_ALTERNATE_FONT_PATH_2  \
 "/usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Speedo/,\
 /usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,\
-/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/,\
-/usr/NX/share/fonts/base"
+/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/"
 
 #define NXAGENT_ALTERNATE_FONT_PATH_3  \
 "/usr/share/fonts/misc/,/usr/share/fonts/Speedo/,\
 /usr/share/fonts/Type1/,/usr/share/fonts/75dpi/,\
-/usr/share/fonts/100dpi/,/usr/share/fonts/TTF/,\
-/usr/NX/share/fonts/base"
-
-#define NXAGENT_ALTERNATE_FONT_PATH_4  \
-"/usr/NX/share/fonts/base"
+/usr/share/fonts/100dpi/,/usr/share/fonts/TTF/"
 
 #undef NXAGENT_FONTCACHE_DEBUG
 #undef NXAGENT_RECONNECT_FONT_DEBUG
@@ -1561,31 +1553,6 @@ void nxagentVerifyDefaultFontPath(void)
     strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_3);
   }
 
-  if (stat(NXAGENT_ALTERNATE_FONT_DIR_4, &dirStat) == 0 &&
-          S_ISDIR(dirStat.st_mode) != 0)
-  {
-    /*
-     * Let's use the "/usr/NX/share/fonts" path.
-     */
-
-    #ifdef TEST
-    fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
-                validateString(NXAGENT_ALTERNATE_FONT_DIR_4));
-    #endif
-
-    if (*fontPath != '\0')
-    {
-      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_4) + 2);
-      strcat(fontPath, ",");
-    }
-    else
-    {
-      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_4) + 1);
-    }
-
-    strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_4);
-  }
-
   if (*fontPath == '\0') 
   {
     #ifdef WARNING
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index 9afd6e392..83aa04f11 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -594,8 +594,6 @@ RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
   unsigned int format;
   unsigned long planeMask = 0xffffffff;
 
-  int oldDstxyValue;
-
   RegionPtr pDstRegion;
 
   int skip = 0;
@@ -607,91 +605,6 @@ RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
                           (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
   #endif
 
- /*
-  * Here, before using fbDoCopy() called by fbCopyArea(),
-  * it should be provided that the cast in fbDoCopy() from
-  * int to short int would not cut off significative bits.
-  */
-
-  if (dstx + pDstDrawable->x + width > 32767)
-  {
-    #ifdef WARNING
-    fprintf(stderr, "nxagentCopyArea: x2 exceeding short int.\n");
-    #endif
-
-    width = 32767 - dstx - pDstDrawable->x;
-
-    if (width <= 0)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentCopyArea: Returning null on x2 check.\n");
-      #endif
-
-      return NullRegion;
-    }
-  }
-
-  if (dstx + pDstDrawable->x < -32768)
-  {
-    #ifdef WARNING
-    fprintf(stderr, "nxagentCopyArea: x1 exceeding short int.\n");
-    #endif
-
-    width += pDstDrawable->x + dstx + 32768;
-    srcx  -= pDstDrawable->x + dstx + 32768;
-    dstx = -32768 - pDstDrawable->x;
-
-    if (width <= 0)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentCopyArea: Returning null on x1 check.\n");
-      #endif
-
-      return NullRegion;
-    }
-  }
-
-    oldDstxyValue = dsty;
-
-  if (dsty + pDstDrawable->y + height > 32767)
-  {
-    #ifdef WARNING
-    fprintf(stderr, "nxagentCopyArea: y2 exceeding short int.\n");
-    #endif
-
-    height = 32767 - dsty - pDstDrawable->y;
-
-    if (height <= 0)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentCopyArea: Returning null on y2 check.\n");
-      #endif
-
-      return NullRegion;
-    }
-  }
-
-  if (dsty + pDstDrawable->y < -32768)
-  {
-    #ifdef WARNING
-    fprintf(stderr, "nxagentCopyArea: y1 exceeding short int.\n");
-    #endif
-
-    height += 32768 + pDstDrawable->y + dsty;
-    srcy   -= 32768 + pDstDrawable->y + dsty;
-    dsty = -32768 - pDstDrawable->y;
-
-    if (height <= 0)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentCopyArea: Returning null on y1 check.\n");
-      #endif
-
-      return NullRegion;
-    }
-  }
-
-
   if (nxagentGCTrap == 1 || nxagentShmTrap == 1)
   {
     if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index 3d94e63af..3abc3575f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -105,13 +105,6 @@
 
 #define MINIMUM_DISPLAY_BUFFER   512
 
-#ifdef NX_DEBUG_INPUT
-extern int nxagentDebugInputDevices;
-extern unsigned long nxagentLastInputDevicesDumpTime;
-
-extern void nxagentDumpInputDevicesState(void);
-#endif
-
 /*
  * Used in the handling of the X desktop
  * manager protocol.
@@ -193,18 +186,6 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
 
   now = GetTimeInMillis();
 
-  #ifdef NX_DEBUG_INPUT
-
-  if (nxagentDebugInputDevices == 1 &&
-        now - nxagentLastInputDevicesDumpTime > 5000)
-  {
-    nxagentLastInputDevicesDumpTime = now;
-
-    nxagentDumpInputDevicesState();
-  }
-
-  #endif
-
   if (nxagentNeedConnectionChange() == 1)
   {
     #ifdef TEST
@@ -559,8 +540,6 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
 
   #endif
 
-  nxagentPrintGeometry();
-
   #ifdef BLOCKS
   fprintf(stderr, "[End block]\n");
   #endif
@@ -841,8 +820,6 @@ FIXME: Must queue multiple writes and handle
 
   #endif
 
-  nxagentPrintGeometry();
-
   #ifdef BLOCKS
   fprintf(stderr, "[End block]\n");
   #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 6c14e20bf..37e49eaeb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -75,8 +75,6 @@ is" without express or implied warranty.
 static int nxagentXkbGetNames(char **rules, char **model, char **layout,
                                   char **variant, char **options);
 
-static void nxagentKeycodeConversionSetup(void);
-
 #endif /* XKB */
 
 /*
@@ -191,281 +189,6 @@ unsigned int nxagentAltMetaMask;
 
 void nxagentCheckAltMetaKeys(CARD8, int);
 
-static CARD8 nxagentConvertedKeycodes[] =
-{
-  /* evdev  pc105*/
-  /*   0 */   0,
-  /*   1 */   1,
-  /*   2 */   2,
-  /*   3 */   3,
-  /*   4 */   4,
-  /*   5 */   5,
-  /*   6 */   6,
-  /*   7 */   7,
-  /*   8 */   8,
-  /*   9 */   9,
-  /*  10 */   10,
-  /*  11 */   11,
-  /*  12 */   12,
-  /*  13 */   13,
-  /*  14 */   14,
-  /*  15 */   15,
-  /*  16 */   16,
-  /*  17 */   17,
-  /*  18 */   18,
-  /*  19 */   19,
-  /*  20 */   20,
-  /*  21 */   21,
-  /*  22 */   22,
-  /*  23 */   23,
-  /*  24 */   24,
-  /*  25 */   25,
-  /*  26 */   26,
-  /*  27 */   27,
-  /*  28 */   28,
-  /*  29 */   29,
-  /*  30 */   30,
-  /*  31 */   31,
-  /*  32 */   32,
-  /*  33 */   33,
-  /*  34 */   34,
-  /*  35 */   35,
-  /*  36 */   36,
-  /*  37 */   37,
-  /*  38 */   38,
-  /*  39 */   39,
-  /*  40 */   40,
-  /*  41 */   41,
-  /*  42 */   42,
-  /*  43 */   43,
-  /*  44 */   44,
-  /*  45 */   45,
-  /*  46 */   46,
-  /*  47 */   47,
-  /*  48 */   48,
-  /*  49 */   49,
-  /*  50 */   50,
-  /*  51 */   51,
-  /*  52 */   52,
-  /*  53 */   53,
-  /*  54 */   54,
-  /*  55 */   55,
-  /*  56 */   56,
-  /*  57 */   57,
-  /*  58 */   58,
-  /*  59 */   59,
-  /*  60 */   60,
-  /*  61 */   61,
-  /*  62 */   62,
-  /*  63 */   63,
-  /*  64 */   64,
-  /*  65 */   65,
-  /*  66 */   66,
-  /*  67 */   67,
-  /*  68 */   68,
-  /*  69 */   69,
-  /*  70 */   70,
-  /*  71 */   71,
-  /*  72 */   72,
-  /*  73 */   73,
-  /*  74 */   74,
-  /*  75 */   75,
-  /*  76 */   76,
-  /*  77 */   77,
-  /*  78 */   78,
-  /*  79 */   79,
-  /*  80 */   80,
-  /*  81 */   81,
-  /*  82 */   82,
-  /*  83 */   83,
-  /*  84 */   84,
-  /*  85 */   85,
-  /*  86 */   86,
-  /*  87 */   87,
-  /*  88 */   88,
-  /*  89 */   89,
-  /*  90 */   90,
-  /*  91 */   91,
-  /*  92 */  124,
-  /*  93 */   93,
-  /*  94 */   94,
-  /*  95 */   95,
-  /*  96 */   96,
-  /*  97 */  211,
-  /*  98 */   98,
-  /*  99 */   99,
-  /* 100 */  100,
-  /* 101 */  208,
-  /* 102 */  102,
-  /* 103 */  103,
-  /* 104 */  108,
-  /* 105 */  109,
-  /* 106 */  112,
-  /* 107 */  111,
-  /* 108 */  113,
-  /* 109 */  109,
-  /* 110 */   97,
-  /* 111 */   98,
-  /* 112 */   99,
-  /* 113 */  100,
-  /* 114 */  102,
-  /* 115 */  103,
-  /* 116 */  104,
-  /* 117 */  105,
-  /* 118 */  106,
-  /* 119 */  107,
-  /* 120 */  120,
-  /* 121 */  121,
-  /* 122 */  122,
-  /* 123 */  123,
-  /* 124 */  124,
-  /* 125 */  126,
-  /* 126 */  126,
-  /* 127 */  110,
-  /* 128 */  128,
-  /* 129 */  129,
-  /* 130 */  130,
-  /* 131 */  131,
-  /* 132 */  133,
-  /* 133 */  115,
-  /* 134 */  116,
-  /* 135 */  117,
-  /* 136 */  136,
-  /* 137 */  137,
-  /* 138 */  138,
-  /* 139 */  139,
-  /* 140 */  140,
-  /* 141 */  141,
-  /* 142 */  142,
-  /* 143 */  143,
-  /* 144 */  144,
-  /* 145 */  145,
-  /* 146 */  146,
-  /* 147 */  147,
-  /* 148 */  148,
-  /* 149 */  149,
-  /* 150 */  150,
-  /* 151 */  151,
-  /* 152 */  152,
-  /* 153 */  153,
-  /* 154 */  154,
-  /* 155 */  155,
-  /* 156 */  156,
-  /* 157 */  157,
-  /* 158 */  158,
-  /* 159 */  159,
-  /* 160 */  160,
-  /* 161 */  161,
-  /* 162 */  162,
-  /* 163 */  163,
-  /* 164 */  164,
-  /* 165 */  165,
-  /* 166 */  166,
-  /* 167 */  167,
-  /* 168 */  168,
-  /* 169 */  169,
-  /* 170 */  170,
-  /* 171 */  171,
-  /* 172 */  172,
-  /* 173 */  173,
-  /* 174 */  174,
-  /* 175 */  175,
-  /* 176 */  176,
-  /* 177 */  177,
-  /* 178 */  178,
-  /* 179 */  179,
-  /* 180 */  180,
-  /* 181 */  181,
-  /* 182 */  182,
-  /* 183 */  183,
-  /* 184 */  184,
-  /* 185 */  185,
-  /* 186 */  186,
-  /* 187 */  187,
-  /* 188 */  188,
-  /* 189 */  189,
-  /* 190 */  190,
-  /* 191 */  118,
-  /* 192 */  119,
-  /* 193 */  120,
-  /* 194 */  121,
-  /* 195 */  122,
-  /* 196 */  196,
-  /* 197 */  197,
-  /* 198 */  198,
-  /* 199 */  199,
-  /* 200 */  200,
-  /* 201 */  201,
-  /* 202 */  202,
-  /* 203 */   93,
-  /* 204 */  125,
-  /* 205 */  156,
-  /* 206 */  127,
-  /* 207 */  128,
-  /* 208 */  208,
-  /* 209 */  209,
-  /* 210 */  210,
-  /* 211 */  211,
-  /* 212 */  212,
-  /* 213 */  213,
-  /* 214 */  214,
-  /* 215 */  215,
-  /* 216 */  216,
-  /* 217 */  217,
-  /* 218 */  218,
-  /* 219 */  219,
-  /* 220 */  220,
-  /* 221 */  221,
-  /* 222 */  222,
-  /* 223 */  223,
-  /* 224 */  224,
-  /* 225 */  225,
-  /* 226 */  226,
-  /* 227 */  227,
-  /* 228 */  228,
-  /* 229 */  229,
-  /* 230 */  230,
-  /* 231 */  231,
-  /* 232 */  232,
-  /* 233 */  233,
-  /* 234 */  234,
-  /* 235 */  235,
-  /* 236 */  236,
-  /* 237 */  237,
-  /* 238 */  238,
-  /* 239 */  239,
-  /* 240 */  240,
-  /* 241 */  241,
-  /* 242 */  242,
-  /* 243 */  243,
-  /* 244 */  244,
-  /* 245 */  245,
-  /* 246 */  246,
-  /* 247 */  247,
-  /* 248 */  248,
-  /* 249 */  249,
-  /* 250 */  250,
-  /* 251 */  251,
-  /* 252 */  252,
-  /* 253 */  253,
-  /* 254 */  254,
-  /* 255 */  255
-};
-
-static int nxagentKeycodeConversion = 0;
-
-CARD8 nxagentConvertKeycode(CARD8 k)
-{
- if (nxagentKeycodeConversion != 0)
- {
-   return nxagentConvertedKeycodes[k];
- }
- else
- {
-   return k;
- }
-}
-
 static int nxagentSaveKeyboardDeviceData(DeviceIntPtr dev, DeviceIntPtr devBackup);
 
 static int nxagentRestoreKeyboardDeviceData(DeviceIntPtr devBackup, DeviceIntPtr dev);
@@ -675,6 +398,13 @@ int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff)
 
   int ret;
 
+  char *remoteRules = NULL;
+  char *remoteModel = NULL;
+
+  unsigned int remoteRulesLen;
+
+  XkbRF_VarDefsRec remoteDefs;
+
   switch (onoff)
   {
     case DEVICE_INIT:
@@ -946,21 +676,14 @@ XkbError:
 
         xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
 
-        nxagentKeycodeConversionSetup();
-
         if (xkb == NULL || xkb->geom == NULL)
         {
           #ifdef TEST
           fprintf(stderr, "nxagentKeyboardProc: No current keyboard.\n");
-          if (xkb == NULL)
-          {
-            fprintf(stderr, "nxagentKeyboardProc: xkb is null.\n");
-          }
-          else
-          {
-            fprintf(stderr, "nxagentKeyboardProc: xkb->geom is null.\n");
-          }
-          fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device.\n");
+          #endif
+
+          #ifdef TEST
+          fprintf(stderr, "nxagentKeyboardProc: No keyboard, going to set rules and init device.\n");
           #endif
 
           XkbSetRulesDflts(rules, model, layout, variants, options);
@@ -976,6 +699,40 @@ XkbError:
           goto XkbEnd;
         }
 
+        if (xkb != NULL)
+        {
+          char *drules = 0;
+          char *dmodel = 0;
+          char *dlayout = 0;
+          char *dvariant = 0;
+          char *doptions = 0;
+
+          remoteRulesLen = nxagentXkbGetNames(&drules, &dmodel, &dlayout,
+                                                  &dvariant, &doptions);
+
+          if (remoteRulesLen != 0 && drules != NULL && dmodel != NULL)
+          {
+            #ifdef DEBUG
+            fprintf(stderr, "nxagentKeyboardProc: Remote: [%s,%s,%s,%s,%s].\n",
+                        drules, dmodel, dlayout, dvariant, doptions);
+            #endif
+
+            remoteRules = drules;
+            remoteModel = dmodel;
+            remoteDefs.model = dmodel;
+            remoteDefs.layout = dlayout;
+            remoteDefs.variant = dvariant;
+            remoteDefs.options = doptions;
+          }
+          #ifdef DEBUG
+          else
+          {
+            fprintf(stderr, "nxagentKeyboardProc: Failed to retrieve remote "
+                        "rules");
+          }
+          #endif
+        }
+
         XkbGetControls(nxagentDisplay, XkbAllControlsMask, xkb);
 
         nxagentXkbConfigFilePathSize = strlen(XkbBaseDirectory) +
@@ -1056,6 +813,66 @@ XkbError:
 
           free(nxagentXkbConfigFilePath);
 
+          if (xkb != NULL && nxagentOption(ClientOs) == ClientOsLinux &&
+                  remoteRules != NULL && remoteModel != NULL &&
+                      (strcmp(remoteRules, "evdev") == 0 ||
+                          strcmp(remoteModel, "evdev") == 0) &&
+                              pDev->key->xkbInfo != NULL &&
+                                  pDev->key->xkbInfo->desc != NULL)
+          {
+            XkbDescPtr xkbt;
+            void *tmp;
+            #ifdef _XSERVER64
+            int i;
+            #endif
+
+            xkbt = pDev->key->xkbInfo->desc;
+
+            xkbt->min_key_code = xkb->min_key_code;
+            xkbt->max_key_code = xkb->max_key_code;
+
+            if (xkbt->map != NULL && xkb->map != NULL)
+            {
+              tmp = (void *)xkbt->map;
+              xkbt->map = xkb->map;
+              xkb->map = (XkbClientMapPtr)tmp;
+
+              #ifdef _XSERVER64
+
+              tmp = (void *) xkbt->map->syms;
+              xkbt->map->syms = xalloc(xkbt->map->size_syms * sizeof(KeySym));
+
+              for (i = 0; i < xkbt->map->size_syms; i++)
+              {
+                xkbt->map->syms[i] = ((KeySym64 *)tmp)[i];
+              }
+
+              #endif
+            }
+
+            if (xkbt->server != NULL && xkb->server != NULL)
+            {
+              tmp = (void *)xkbt->server;
+              xkbt->server = xkb->server;
+              xkb->server = (XkbServerMapPtr)tmp;
+            }
+
+            if (xkbt->compat != NULL && xkb->compat != NULL)
+            {
+              tmp = (void *)xkbt->compat;
+              xkbt->compat = xkb->compat;
+              xkb->compat = (XkbCompatMapPtr)tmp;
+            }
+
+            XkbSetRulesDflts(remoteRules, remoteDefs.model, remoteDefs.layout,
+                                 remoteDefs.variant, remoteDefs.options);
+            XkbSetRulesUsed(&remoteDefs);
+
+            free(remoteRules);
+
+            goto XkbEnd;
+          }
+
           if (!nxagentKeyboard ||
                  (nxagentKeyboard && (strcmp(nxagentKeyboard, "query") == 0)))
           {
@@ -1745,70 +1562,4 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
   return n;
 }
 
-void nxagentKeycodeConversionSetup(void)
-{
-  char *drules = 0;
-  char *dmodel = 0;
-  char *dlayout = 0;
-  char *dvariant = 0;
-  char *doptions = 0;
-  unsigned int drulesLen;
-
-  nxagentKeycodeConversion = 0;
-
-  drulesLen = nxagentXkbGetNames(&drules, &dmodel, &dlayout,
-                                     &dvariant, &doptions);
-
-  #ifdef DEBUG
-  if (drulesLen != 0 && drules != NULL && dmodel != NULL)
-  {
-    fprintf(stderr, "nxagentKeycodeConversionSetup: "
-                "Remote: [%s,%s,%s,%s,%s].\n", drules, dmodel, dlayout,
-                    dvariant, doptions);
-  }
-  else
-  {
-    fprintf(stderr, "nxagentKeycodeConversionSetup: "
-                "Failed to retrieve remote rules.\n");
-  }
-  #endif
-
-  if (nxagentOption(ClientOs) == ClientOsLinux &&
-            drules != NULL && dmodel != NULL &&
-                (strcmp(drules, "evdev") == 0 ||
-                    strcmp(dmodel, "evdev") == 0))
-  {
-    nxagentKeycodeConversion = 1;
-  }
-
-  if (drules != NULL)
-  {
-    XFree(drules);
-  }
-}
-
-void nxagentResetKeycodeConversion(void)
-{
-  int result;
-  XkbAgentInfoRec info;
-
-  result = XkbQueryExtension(nxagentDisplay, &info.Opcode, &info.EventBase,
-                                 &info.ErrorBase, &info.MajorVersion,
-                                     &info.MinorVersion);
-
-  if (result != 0)
-  {
-    nxagentKeycodeConversionSetup();
-  }
-  else
-  {
-    #ifdef WARNING
-    fprintf(stderr, "nxagentResetKeycodeConversion: "
-                "WARNING! Failed to query XKB extension.\n");
-    #endif
-
-    nxagentKeycodeConversion = 0;
-  }
-}
-
 #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index 50dd2be78..f292402d2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -109,10 +109,6 @@ void nxagentEnableXkbExtension(void);
 
 void nxagentTuneXkbWrapper(void);
 
-void nxagentResetKeycodeConversion(void);
-
 #endif
 
-CARD8 nxagentConvertKeycode(CARD8 k);
-
 #endif /* __Keyboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index 762ab79dc..ea06913f8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -31,12 +31,6 @@
 extern Bool nxagentWMIsRunning;
 extern Bool nxagentIpaq;
 
-#ifdef NX_DEBUG_INPUT
-int nxagentDebugInputDevices = 0;
-unsigned long nxagentLastInputDevicesDumpTime = 0;
-extern void nxagentDeactivateInputDevicesGrabs();
-#endif
-
 /*
  * Set here the required log level.
  */
@@ -215,53 +209,6 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       }
 
       #endif
-
-      #ifdef NX_DEBUG_INPUT
-
-      case XK_X:
-      case XK_x:
-      {
-        /*
-         * Used to test the input devices state.
-         */
-
-        if (X -> type == KeyPress)
-        {
-          if (nxagentDebugInputDevices == 0)
-          {
-            fprintf(stderr, "Info: Turning input devices debug ON.\n");
-    
-            nxagentDebugInputDevices = 1;
-          }
-          else
-          {
-            fprintf(stderr, "Info: Turning input devices debug OFF.\n");
-    
-            nxagentDebugInputDevices = 0;
-    
-            nxagentLastInputDevicesDumpTime = 0;
-          }
-        }
-
-        return 1;
-      }
-
-      case XK_Y:
-      case XK_y:
-      {
-        /*
-         * Used to deactivate input devices grab.
-         */
-
-        if (X -> type == KeyPress)
-        {
-          nxagentDeactivateInputDevicesGrabs();
-        }
-
-        return 1;
-      }
-
-      #endif
     }
   }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index ca8cfc12f..64dbe3b42 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -38,11 +38,6 @@ AgentOptionsRec nxagentOptionsBackup;
 
 AgentOptionsPtr nxagentOptionsPtr = &nxagentOptions;
 
-/*
- * If this is set, print the geometry in the block handler.
- */
-
-unsigned int nxagentPrintGeometryFlags = 0;
 /*
  * This must be called at startup to initialize
  * the options repository to the default values.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index af437cd16..aa78489b1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -29,8 +29,6 @@
 #define UNDEFINED -1
 #define COPY_UNLIMITED -1
 
-extern unsigned int nxagentPrintGeometryFlags;
-
 typedef enum _BackingStoreMode
 {
   BackingStoreUndefined = -1,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index f73d4692c..ce3e6ee05 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -257,11 +257,7 @@ TODO: This should be reset only when
 
       if ((dispatchException & DE_TERMINATE) == 0)
       {
-        #ifdef NX_DEBUG_INPUT
-        fprintf(stderr, "Session: Session suspended at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
-        #else
         fprintf(stderr, "Session: Session suspended at '%s'.\n", GetTimeAsString());
-        #endif
       }
 
       nxagentResetDisplayHandlers();
@@ -551,29 +547,28 @@ Bool nxagentReconnectSession(void)
     goto nxagentReconnectError;
   }
 
-  if (nxagentOption(ResetKeyboardAtResume) == 1 &&
-         (nxagentKeyboard  == NULL || nxagentOldKeyboard == NULL ||
-             strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
-                 strcmp(nxagentKeyboard, "query") == 0))
+  if (nxagentOption(ResetKeyboardAtResume))
   {
-    if (nxagentResetKeyboard() == 0)
+    if (nxagentKeyboard  == NULL || nxagentOldKeyboard == NULL ||
+           strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
+               strcmp(nxagentKeyboard, "query") == 0)
     {
-      #ifdef WARNING
-      if (nxagentVerbose == 1)
+
+      if (nxagentResetKeyboard() == 0)
       {
-        fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
-      }
-      #endif
+        #ifdef WARNING
+        if (nxagentVerbose == 1)
+        {
+          fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
+        }
+        #endif
 
-      failedStep = WINDOW_STEP;
+        failedStep = WINDOW_STEP;
 
-      goto nxagentReconnectError;
+        goto nxagentReconnectError;
+      }
     }
   }
-  else
-  {
-    nxagentResetKeycodeConversion();
-  }
 
   nxagentXkbState.Initialized = 0;
 
@@ -613,11 +608,7 @@ Bool nxagentReconnectSession(void)
     goto nxagentReconnectError;
   }
 
-  #ifdef NX_DEBUG_INPUT
-  fprintf(stderr, "Session: Session resumed at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
-  #else
   fprintf(stderr, "Session: Session resumed at '%s'.\n", GetTimeAsString());
-  #endif
 
   nxagentRemoveSplashWindow(NULL);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index f2d7b15f9..b1ff219e7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -2270,7 +2270,8 @@ void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
 
   normalizedImages = NULL;
 
-  if (sizeImages > 0)
+  if (glyphDepths[glyphSet -> fdepth] == 1 &&
+          nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
   {
     normalizedImages = xalloc(sizeImages);
 
@@ -2278,11 +2279,7 @@ void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
     {
       memcpy(normalizedImages, images, sizeImages);
 
-      if (glyphDepths[glyphSet -> fdepth] == 1 &&
-              nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
-      {
-        BitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
-      }
+      BitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
     }
     else
     {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index e192cd2c4..79cb74efa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -60,27 +60,6 @@ typedef struct
 }
 nxagentWMHints;
 
-/*
- * This structure is compatible with 32
- * and 64 bit library interface. It has
- * been copied from Xatomtype.h and it's
- * a parameter of XChangeProperty().
- */
-
-typedef struct
-{
-  unsigned long flags;
-  long          input;
-  long          initialState;
-  unsigned long iconPixmap;
-  unsigned long iconWindow;
-  long          iconX;
-  long          iconY;
-  unsigned long iconMask;
-  unsigned long windowGroup;
-}
-nxagentPropWMHints;
-
 WindowPtr nxagentRootlessWindow = NULL;
 
 #define TOP_LEVEL_TABLE_UNIT 100
@@ -450,7 +429,6 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
   Atom propertyX, typeX;
   char *output = NULL;
   nxagentWMHints wmHints;
-  nxagentPropWMHints propHints;
   Bool export = False;
   Bool freeMem = False;
 
@@ -511,22 +489,8 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     wmHints.flags |= InputHint;
     wmHints.input = True;
 
-    /*
-     * Initialize the structure used in XChangeProperty().
-     */
-
-    propHints.flags = wmHints.flags;
-    propHints.input = (wmHints.input == True ? 1 : 0);
-    propHints.initialState = wmHints.initial_state;
-    propHints.iconPixmap = wmHints.icon_pixmap;
-    propHints.iconWindow = wmHints.icon_window;
-    propHints.iconX = wmHints.icon_x;
-    propHints.iconY = wmHints.icon_y;
-    propHints.iconMask = wmHints.icon_mask;
-    propHints.windowGroup = wmHints.window_group;
-
-    output = (char*) &propHints;
-    export = True;
+    output = (char*) &wmHints;
+    export  = True;
 
     if ((wmHints.flags & IconPixmapHint) && (wmHints.icon_pixmap != None))
     {
@@ -540,17 +504,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
           nxagentSynchronizeRegion((DrawablePtr) icon, NullRegion, NEVER_BREAK, NULL);
         }
 
-        propHints.iconPixmap = nxagentPixmap(icon);
+        wmHints.icon_pixmap = nxagentPixmap(icon);
       }
       else
       {
-        propHints.flags &= ~IconPixmapHint;
+        wmHints.flags &= ~IconPixmapHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon pixmap %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_pixmap, propertyS, typeS,
-                            (void *) pWin);
+                            (void*)pWin);
         #endif
       }
     }
@@ -562,17 +526,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (icon)
       {
-        propHints.iconWindow = nxagentWindow(icon);
+        wmHints.icon_window = nxagentWindow(icon);
       }
       else
       {
-        propHints.flags &= ~IconWindowHint;
+        wmHints.flags &= ~IconWindowHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon window %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_window, propertyS, typeS,
-                            (void *) pWin);
+                            (void*)pWin);
         #endif
       }
     }
@@ -584,17 +548,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (icon)
       {
-        propHints.iconMask = nxagentPixmap(icon);
+        wmHints.icon_mask = nxagentPixmap(icon);
       }
       else
       {
-        propHints.flags &= ~IconMaskHint;
+        wmHints.flags &= ~IconMaskHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon mask %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_mask, propertyS, typeS,
-                            (void *) pWin);
+                            (void*)pWin);
         #endif
       }
     }
@@ -606,17 +570,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (window)
       {
-        propHints.windowGroup = nxagentWindow(window);
+        wmHints.window_group = nxagentWindow(window);
       }
       else
       {
-        propHints.flags &= ~WindowGroupHint;
+        wmHints.flags &= ~WindowGroupHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window group %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.window_group, propertyS, typeS,
-                            (void *) pWin);
+                            (void*)pWin);
         #endif
       }
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index f643cb98c..524bafd10 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -2373,7 +2373,8 @@ FIXME: We should try to restore the previously
   nxagentPrintAgentGeometry("After Resize Screen", "nxagentResizeScreen:");
   #endif
 
-  nxagentSetPrintGeometry(pScreen -> myNum);
+  fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d].\n",
+              pScreen -> myNum, width, height);
 
   return 1;
 
@@ -3045,7 +3046,7 @@ void nxagentShadowAdaptDepth(unsigned int width, unsigned int height,
     #ifdef WARNING
     fprintf(stderr, "nxagentCorrectDepthShadow: WARNING! Visual not found. Using default visual.\n");
     #endif
-
+    
     pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
   }
 
@@ -3472,10 +3473,10 @@ int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height)
     RRScreenSizePtr oldSizes;
 
     pScrPriv = rrGetScrPriv(pScreen);
-
+   
     oldWidth = pScreen->width;
     oldHeight = pScreen->height;
-
+    
     if (!pScrPriv)
     {
       return 1;
@@ -3555,7 +3556,7 @@ int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height)
     }
 
     RREditConnectionInfo (pScreen);
-
+    
     /*
      * Fix pointer bounds and location
      */
@@ -3693,8 +3694,7 @@ void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg,
   return;
 }
 
-void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg,
-                             int yorg, WindowPtr pWin)
+void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int yorg, WindowPtr pWin)
 {
   PixmapPtr pVirtualPixmap;
   RegionPtr clipRegion;
@@ -3710,14 +3710,6 @@ void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg,
   BoxRec extents;
   miBSWindowPtr pBackingStore;
 
-  /*
-   * Limit the area to restore to the
-   * root window size.
-   */
-
-  REGION_INTERSECT(pWin -> pScreen, prgnRestore, prgnRestore,
-                       &WindowTable[pWin -> drawable.pScreen -> myNum] -> winSize);
-
   pBackingStore = (miBSWindowPtr) pWin -> backStorage;
 
   pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
@@ -3911,24 +3903,6 @@ void nxagentShadowAdaptToRatio(void)
   REGION_UNINIT(pScreen, &region);
 }
 
-void nxagentPrintGeometry()
-{
-  int i;
-
-  for (i = 0; i < screenInfo.numScreens; i++)
-  {
-    if (nxagentPrintGeometryFlags && (1 << i))
-    {
-      fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d] "
-                  "fullscreen [%d].\n", i, screenInfo.screens[i] -> width,
-                      screenInfo.screens[i] -> height,
-                          nxagentOption(Fullscreen));
-    }
-  }
-
-  nxagentPrintGeometryFlags = 0;
-}
-
 #ifdef DUMP
 
 void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 73af3cc50..3550dd553 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -36,9 +36,6 @@ is" without express or implied warranty.
 #define MIN_NXAGENT_HEIGHT 60
 #define NXAGENT_FRAME_WIDTH 2000
 
-#define nxagentSetPrintGeometry(screen) \
-    nxagentPrintGeometryFlags = (1 << (screen));
-    
 extern int nxagentClients;
 
 extern int nxagentAutoDisconnectTimeout;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 8c94b24b5..8da5d8bd1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -908,8 +908,6 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 
   XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
                         nxagentOption(Width), nxagentOption(Height));
-
-  nxagentSetPrintGeometry(pScreen -> myNum);
 }
 
 #ifdef VIEWPORT_FRAME
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index d267adbc9..f84ca0e03 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -515,11 +515,7 @@ Dispatch(void)
 
     if (serverGeneration > nxagentMaxAllowedResets)
     {
-      #ifdef NX_DEBUG_INPUT
-      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
-      #else
       fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
-      #endif
 
       nxagentSessionState = SESSION_UP;
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index d267adbc9..f84ca0e03 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -515,11 +515,7 @@ Dispatch(void)
 
     if (serverGeneration > nxagentMaxAllowedResets)
     {
-      #ifdef NX_DEBUG_INPUT
-      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
-      #else
       fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
-      #endif
 
       nxagentSessionState = SESSION_UP;
     }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index 1c141c015..91e290996 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -189,11 +189,6 @@ xEvent *xeviexE;
 #include "Windows.h"
 #include "Args.h"
 
-#ifdef NX_DEBUG_INPUT
-extern int nxagentDebugInput;
-extern int nxagentDebugInputDevices;
-#endif
- 
 extern Display *nxagentDisplay;
 
 extern WindowPtr nxagentLastEnteredWindow;
@@ -1687,27 +1682,10 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
     int i;
     int type;
 
-#ifdef NX_DEBUG_INPUT
-    if (grab && nxagentDebugInput && grab->window)
-    {
-	fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n",
-		(unsigned int)grab->window->drawable.id);
-	if (!SameClient(grab, client))
-		fprintf(stderr, "TryClientEvents: Events are going to be "
-			    "discarded.\n");
-    }
-#endif
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-	fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d",
-	pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask,
-	client->index);
-#else
+#ifdef DEBUG
     if (debug_events) ErrorF(
 	"Event([%d, %d], mask=0x%x), client=%d",
 	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
-#endif
 #endif
     if ((client) && (client != serverClient) && (!client->clientGone) &&
 	((filter == CantBeFiltered) || (mask & filter)))
@@ -1722,16 +1700,9 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
 		    pEvents->u.keyButtonPointer.event)
 		{
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-    {
-	fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n");
-    }
-#else
+#ifdef DEBUG
 		    if (debug_events) ErrorF("\n");
 	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
-#endif
 #endif
 		    return 1; /* don't send, but pretend we did */
 		}
@@ -1769,25 +1740,15 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 	}
 
 	WriteEventsToClient(client, count, pEvents);
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-	fprintf(stderr, " delivered\n");
-#else
+#ifdef DEBUG
 	if (debug_events) ErrorF(  " delivered\n");
-#endif
 #endif
 	return 1;
     }
     else
     {
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-	fprintf(stderr, "\n");
-#else
+#ifdef DEBUG
 	if (debug_events) ErrorF("\n");
-#endif
 #endif
 	return 0;
     }
@@ -1866,12 +1827,6 @@ DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInputDevices == 1)
-        {
-          fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n");
-        }
-        #endif
 	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
 					   currentTime, TRUE);
     }
@@ -2742,13 +2697,6 @@ CheckPassiveGrabsOnWindow(
 				tempGrab.modifiersDetail.exact&(~0x1f00);
 	    }
 #endif
-            #ifdef NX_DEBUG_INPUT
-            if (nxagentDebugInputDevices == 1)
-            {
-              fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n",
-                          device == inputInfo.keyboard ? "keyboard" : "pointer");
-            }
-            #endif
 	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  
 	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
@@ -3107,17 +3055,7 @@ drawable.id:0;
     else
 	DeliverFocusedEvent(keybd, xE, sprite.win, count);
     if (deactivateGrab)
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n");
-      }
-    #endif
         (*keybd->DeactivateGrab)(keybd);
-    #ifdef NX_DEBUG_INPUT
-    }
-    #endif
 }
 
 #ifdef XKB
@@ -3178,12 +3116,6 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
         xevieEventSent = 0;
       else {
         xeviemouse = mouse;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInput == 1)
-        {
-          fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n");
-        }
-        #endif
         WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
         return;
       }
@@ -3238,38 +3170,14 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
-	    #ifdef NX_DEBUG_INPUT
-	    if (xE->u.u.detail == 0)
-	    {
-		if (nxagentDebugInput == 1)
-		{
-		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
-			    " for ButtonPress.\n");
-		}
-		return;
-	    }
-	    #else
 	    if (xE->u.u.detail == 0)
 		return;
-	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!grab)
-	    #ifdef NX_DEBUG_INPUT
 		if (CheckDeviceGrabs(mouse, xE, 0, count))
-		{
-		    if (nxagentDebugInput == 1)
-		    {
-			fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs"
-				" returned True for ButtonPress.\n");
-		    }
 		    return;
-		}
-	    #else
-		if (CheckDeviceGrabs(mouse, xE, 0, count))
-		    return;
-	    #endif
 	    break;
 	case ButtonRelease: 
 	    mouse->valuator->motionHintWindow = NullWindow;
@@ -3281,20 +3189,8 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
-	    #ifdef NX_DEBUG_INPUT
-	    if (xE->u.u.detail == 0)
-	    {
-		if (nxagentDebugInput == 1)
-		{
-		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
-			    " for ButtonRelease.\n");
-		}
-		return;
-	    }
-	    #else
 	    if (xE->u.u.detail == 0)
 		return;
-	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 	    filters[MotionNotify] = Motion_Filter(butc);
@@ -3305,36 +3201,6 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 	    FatalError("bogus pointer event from ddx");
 	}
     }
-    #ifdef NX_DEBUG_INPUT
-    else if (!CheckMotion(xE))
-    {
-	if (nxagentDebugInput == 1)
-	{
-	    fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False"
-		    " for MotionNotify.\n");
-	}
-	return;
-    }
-    if (grab)
-    {
-	if (nxagentDebugInput == 1)
-	{
-	    fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed "
-		    "events (count = %d).\n", count);
-	}
-	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
-    }
-    else
-    {
-	if (nxagentDebugInput == 1)
-	{
-	    fprintf(stderr, "ProcessPointerEvent: Going to deliver device "
-		    "events (count = %d).\n", count);
-	}
-	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
-			    mouse, count);
-    }
-    #else
     else if (!CheckMotion(xE))
 	return;
     if (grab)
@@ -3342,19 +3208,8 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     else
 	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
 			    mouse, count);
-    #endif
     if (deactivateGrab)
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n");
-      }
-    #endif
         (*mouse->DeactivateGrab)(mouse);
-    #ifdef NX_DEBUG_INPUT
-    }
-    #endif
 }
 
 #define AtMostOneClient \
@@ -4075,12 +3930,6 @@ ProcGrabPointer(ClientPtr client)
     pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
     if (!pWin)
 	return BadWindow;
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index);
-    }
-    #endif
     if (stuff->confineTo == None)
 	confineTo = NullWindow;
     else 
@@ -4140,12 +3989,6 @@ ProcGrabPointer(ClientPtr client)
 	tempGrab.keyboardMode = stuff->keyboardMode;
 	tempGrab.pointerMode = stuff->pointerMode;
 	tempGrab.device = device;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInputDevices == 1)
-        {
-          fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n");
-        }
-        #endif
 	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
 	if (oldCursor)
 	    FreeCursor (oldCursor, (Cursor)0);
@@ -4209,12 +4052,6 @@ ProcUngrabPointer(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index);
-    }
-    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4222,25 +4059,7 @@ ProcUngrabPointer(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	    (grab) && SameClient(grab, client))
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n");
-      }
-    #endif
 	(*device->DeactivateGrab)(device);
-    #ifdef NX_DEBUG_INPUT
-    }
-    else
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n",
-                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
-      }
-    }
-    #endif
     return Success;
 }
 
@@ -4295,12 +4114,6 @@ GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
 	tempGrab.pointerMode = other_mode;
 	tempGrab.eventMask = mask;
 	tempGrab.device = dev;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInputDevices == 1)
-        {
-          fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n");
-        }
-        #endif
 	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4314,12 +4127,6 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST(xGrabKeyboardReq);
     int result;
 
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index);
-    }
-    #endif
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 #ifdef XCSECURITY
     if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
@@ -4350,12 +4157,6 @@ ProcUngrabKeyboard(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index);
-    }
-    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4363,25 +4164,7 @@ ProcUngrabKeyboard(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	(grab) && SameClient(grab, client))
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n");
-      }
-    #endif
 	(*device->DeactivateGrab)(device);
-    #ifdef NX_DEBUG_INPUT
-    }
-    else
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n",
-                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
-      }
-    }
-    #endif
     return Success;
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index 1c141c015..91e290996 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -189,11 +189,6 @@ xEvent *xeviexE;
 #include "Windows.h"
 #include "Args.h"
 
-#ifdef NX_DEBUG_INPUT
-extern int nxagentDebugInput;
-extern int nxagentDebugInputDevices;
-#endif
- 
 extern Display *nxagentDisplay;
 
 extern WindowPtr nxagentLastEnteredWindow;
@@ -1687,27 +1682,10 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
     int i;
     int type;
 
-#ifdef NX_DEBUG_INPUT
-    if (grab && nxagentDebugInput && grab->window)
-    {
-	fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n",
-		(unsigned int)grab->window->drawable.id);
-	if (!SameClient(grab, client))
-		fprintf(stderr, "TryClientEvents: Events are going to be "
-			    "discarded.\n");
-    }
-#endif
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-	fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d",
-	pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask,
-	client->index);
-#else
+#ifdef DEBUG
     if (debug_events) ErrorF(
 	"Event([%d, %d], mask=0x%x), client=%d",
 	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
-#endif
 #endif
     if ((client) && (client != serverClient) && (!client->clientGone) &&
 	((filter == CantBeFiltered) || (mask & filter)))
@@ -1722,16 +1700,9 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
 		    pEvents->u.keyButtonPointer.event)
 		{
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-    {
-	fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n");
-    }
-#else
+#ifdef DEBUG
 		    if (debug_events) ErrorF("\n");
 	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
-#endif
 #endif
 		    return 1; /* don't send, but pretend we did */
 		}
@@ -1769,25 +1740,15 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 	}
 
 	WriteEventsToClient(client, count, pEvents);
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-	fprintf(stderr, " delivered\n");
-#else
+#ifdef DEBUG
 	if (debug_events) ErrorF(  " delivered\n");
-#endif
 #endif
 	return 1;
     }
     else
     {
-#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
-#ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInput == 1)
-	fprintf(stderr, "\n");
-#else
+#ifdef DEBUG
 	if (debug_events) ErrorF("\n");
-#endif
 #endif
 	return 0;
     }
@@ -1866,12 +1827,6 @@ DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInputDevices == 1)
-        {
-          fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n");
-        }
-        #endif
 	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
 					   currentTime, TRUE);
     }
@@ -2742,13 +2697,6 @@ CheckPassiveGrabsOnWindow(
 				tempGrab.modifiersDetail.exact&(~0x1f00);
 	    }
 #endif
-            #ifdef NX_DEBUG_INPUT
-            if (nxagentDebugInputDevices == 1)
-            {
-              fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n",
-                          device == inputInfo.keyboard ? "keyboard" : "pointer");
-            }
-            #endif
 	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  
 	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
@@ -3107,17 +3055,7 @@ drawable.id:0;
     else
 	DeliverFocusedEvent(keybd, xE, sprite.win, count);
     if (deactivateGrab)
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n");
-      }
-    #endif
         (*keybd->DeactivateGrab)(keybd);
-    #ifdef NX_DEBUG_INPUT
-    }
-    #endif
 }
 
 #ifdef XKB
@@ -3178,12 +3116,6 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
         xevieEventSent = 0;
       else {
         xeviemouse = mouse;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInput == 1)
-        {
-          fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n");
-        }
-        #endif
         WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
         return;
       }
@@ -3238,38 +3170,14 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
-	    #ifdef NX_DEBUG_INPUT
-	    if (xE->u.u.detail == 0)
-	    {
-		if (nxagentDebugInput == 1)
-		{
-		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
-			    " for ButtonPress.\n");
-		}
-		return;
-	    }
-	    #else
 	    if (xE->u.u.detail == 0)
 		return;
-	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!grab)
-	    #ifdef NX_DEBUG_INPUT
 		if (CheckDeviceGrabs(mouse, xE, 0, count))
-		{
-		    if (nxagentDebugInput == 1)
-		    {
-			fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs"
-				" returned True for ButtonPress.\n");
-		    }
 		    return;
-		}
-	    #else
-		if (CheckDeviceGrabs(mouse, xE, 0, count))
-		    return;
-	    #endif
 	    break;
 	case ButtonRelease: 
 	    mouse->valuator->motionHintWindow = NullWindow;
@@ -3281,20 +3189,8 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
-	    #ifdef NX_DEBUG_INPUT
-	    if (xE->u.u.detail == 0)
-	    {
-		if (nxagentDebugInput == 1)
-		{
-		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
-			    " for ButtonRelease.\n");
-		}
-		return;
-	    }
-	    #else
 	    if (xE->u.u.detail == 0)
 		return;
-	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 	    filters[MotionNotify] = Motion_Filter(butc);
@@ -3305,36 +3201,6 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 	    FatalError("bogus pointer event from ddx");
 	}
     }
-    #ifdef NX_DEBUG_INPUT
-    else if (!CheckMotion(xE))
-    {
-	if (nxagentDebugInput == 1)
-	{
-	    fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False"
-		    " for MotionNotify.\n");
-	}
-	return;
-    }
-    if (grab)
-    {
-	if (nxagentDebugInput == 1)
-	{
-	    fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed "
-		    "events (count = %d).\n", count);
-	}
-	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
-    }
-    else
-    {
-	if (nxagentDebugInput == 1)
-	{
-	    fprintf(stderr, "ProcessPointerEvent: Going to deliver device "
-		    "events (count = %d).\n", count);
-	}
-	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
-			    mouse, count);
-    }
-    #else
     else if (!CheckMotion(xE))
 	return;
     if (grab)
@@ -3342,19 +3208,8 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     else
 	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
 			    mouse, count);
-    #endif
     if (deactivateGrab)
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n");
-      }
-    #endif
         (*mouse->DeactivateGrab)(mouse);
-    #ifdef NX_DEBUG_INPUT
-    }
-    #endif
 }
 
 #define AtMostOneClient \
@@ -4075,12 +3930,6 @@ ProcGrabPointer(ClientPtr client)
     pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
     if (!pWin)
 	return BadWindow;
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index);
-    }
-    #endif
     if (stuff->confineTo == None)
 	confineTo = NullWindow;
     else 
@@ -4140,12 +3989,6 @@ ProcGrabPointer(ClientPtr client)
 	tempGrab.keyboardMode = stuff->keyboardMode;
 	tempGrab.pointerMode = stuff->pointerMode;
 	tempGrab.device = device;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInputDevices == 1)
-        {
-          fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n");
-        }
-        #endif
 	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
 	if (oldCursor)
 	    FreeCursor (oldCursor, (Cursor)0);
@@ -4209,12 +4052,6 @@ ProcUngrabPointer(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index);
-    }
-    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4222,25 +4059,7 @@ ProcUngrabPointer(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	    (grab) && SameClient(grab, client))
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n");
-      }
-    #endif
 	(*device->DeactivateGrab)(device);
-    #ifdef NX_DEBUG_INPUT
-    }
-    else
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n",
-                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
-      }
-    }
-    #endif
     return Success;
 }
 
@@ -4295,12 +4114,6 @@ GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
 	tempGrab.pointerMode = other_mode;
 	tempGrab.eventMask = mask;
 	tempGrab.device = dev;
-        #ifdef NX_DEBUG_INPUT
-        if (nxagentDebugInputDevices == 1)
-        {
-          fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n");
-        }
-        #endif
 	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4314,12 +4127,6 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST(xGrabKeyboardReq);
     int result;
 
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index);
-    }
-    #endif
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 #ifdef XCSECURITY
     if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
@@ -4350,12 +4157,6 @@ ProcUngrabKeyboard(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
-    #ifdef NX_DEBUG_INPUT
-    if (nxagentDebugInputDevices == 1)
-    {
-      fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index);
-    }
-    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4363,25 +4164,7 @@ ProcUngrabKeyboard(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	(grab) && SameClient(grab, client))
-    #ifdef NX_DEBUG_INPUT
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n");
-      }
-    #endif
 	(*device->DeactivateGrab)(device);
-    #ifdef NX_DEBUG_INPUT
-    }
-    else
-    {
-      if (nxagentDebugInputDevices == 1)
-      {
-        fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n",
-                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
-      }
-    }
-    #endif
     return Success;
 }
 
-- 
cgit v1.2.3


From 6f5e20bc49695159bd3b313333591c4eb27ad422 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:56 +0200
Subject: Imported nxagent-3.3.0-9.tar.gz

Summary: Imported nxagent-3.3.0-9.tar.gz
Keywords:

Imported nxagent-3.3.0-9.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  21 +
 nx-X11/programs/Xserver/hw/nxagent/Events.c        |  40 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |  41 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      | 460 ++++++++++++++++-----
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   4 +
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |  31 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    | 119 +++++-
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    | 119 +++++-
 9 files changed, 693 insertions(+), 151 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 17b69c3f2..1f7f0df55 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,26 @@
 ChangeLog:
 
+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.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index ab8c13cae..3c1458cb7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -63,7 +63,13 @@
 #include "NXproto.h"
 
 #include "xfixesproto.h"
+#define Window     XlibWindow
+#define Atom   XlibAtom
+#define Time XlibXID
 #include <X11/extensions/Xfixes.h>
+#undef Window
+#undef Atom
+#undef Time
 
 #ifdef NXAGENT_FIXKEYS
 #include "inputstr.h"
@@ -789,8 +795,9 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         }
 
         x.u.u.type = KeyRelease;
-        x.u.u.detail = X.xkey.keycode;
-        x.u.keyButtonPointer.time = nxagentLastKeyPressTime + (X.xkey.time - nxagentLastServerTime);
+        x.u.u.detail = nxagentConvertKeycode(X.xkey.keycode);
+        x.u.keyButtonPointer.time = nxagentLastKeyPressTime +
+            (X.xkey.time - nxagentLastServerTime);
 
         nxagentLastServerTime = X.xkey.time;
 
@@ -918,7 +925,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         #ifdef NX_DEBUG_INPUT
         if (nxagentDebugInput == 1)
         {
-          fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonPress event.\n");
+          fprintf(stderr, "nxagentDispatchEvents: Going to handle new ButtonRelease event.\n");
         }
         #endif
 
@@ -1016,18 +1023,17 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
             nxagentLastEnteredWindow = pWin;
           }
 
-          if (nxagentPulldownDialogPid == 0 && (X.xmotion.y_root <
-                  nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
+          if (nxagentPulldownDialogPid == 0 && nxagentLastEnteredTopLevelWindow &&
+                  (X.xmotion.y_root < nxagentLastEnteredTopLevelWindow -> drawable.y + 4))
           {
-            if (pWin && nxagentLastEnteredTopLevelWindow &&
-                    nxagentClientIsDialog(wClient(pWin)) == 0 &&
-                        nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
-                            nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
-                                X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
-                                    (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
-                                        X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
-                                            (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
-                                                nxagentOption(Menu) == 1)
+            if (pWin && nxagentClientIsDialog(wClient(pWin)) == 0 &&
+                    nxagentLastEnteredTopLevelWindow -> parent == WindowTable[0] &&
+                        nxagentLastEnteredTopLevelWindow -> overrideRedirect == False &&
+                            X.xmotion.x_root > (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) - 50) &&
+                                    X.xmotion.x_root < (nxagentLastEnteredTopLevelWindow -> drawable.x +
+                                        (nxagentLastEnteredTopLevelWindow -> drawable.width >> 1) + 50) &&
+                                            nxagentOption(Menu) == 1)
             {
               nxagentPulldownDialog(nxagentLastEnteredTopLevelWindow -> drawable.id);
             }
@@ -1052,7 +1058,8 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           #ifdef NX_DEBUG_INPUT
           if (nxagentDebugInput == 1)
           {
-            fprintf(stderr, "nxagentDispatchEvents: Adding motion event [%d, %d] to the queue.\n", x.u.keyButtonPointer.rootX, x.u.keyButtonPointer.rootY);
+            fprintf(stderr, "nxagentDispatchEvents: Adding motion event [%d, %d] to the queue.\n",
+                        x.u.keyButtonPointer.rootX, x.u.keyButtonPointer.rootY);
           }
           #endif
 
@@ -1911,8 +1918,9 @@ int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
 
   nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
 
+  
   x.u.u.type = KeyPress;
-  x.u.u.detail = X -> xkey.keycode;
+  x.u.u.detail = nxagentConvertKeycode(X -> xkey.keycode);
   x.u.keyButtonPointer.time = nxagentLastKeyPressTime;
 
   nxagentLastServerTime = X -> xkey.time;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index 3f1fd0b43..87f9f0201 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -65,26 +65,34 @@ is" without express or implied warranty.
 #define NXAGENT_ALTERNATE_FONT_DIR    "/usr/share/X11/fonts"
 #define NXAGENT_ALTERNATE_FONT_DIR_2  "/usr/share/fonts/X11"
 #define NXAGENT_ALTERNATE_FONT_DIR_3  "/usr/share/fonts"
+#define NXAGENT_ALTERNATE_FONT_DIR_4  "/usr/NX/share/fonts"
 
 #define NXAGENT_DEFAULT_FONT_PATH  \
 "/usr/X11R6/lib/X11/fonts/misc/,/usr/X11R6/lib/X11/fonts/Speedo/,\
 /usr/X11R6/lib/X11/fonts/Type1/,/usr/X11R6/lib/X11/fonts/75dpi/,\
-/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/"
+/usr/X11R6/lib/X11/fonts/100dpi/,/usr/X11R6/lib/X11/fonts/TTF/,\
+/usr/NX/share/fonts/base"
 
 #define NXAGENT_ALTERNATE_FONT_PATH  \
 "/usr/share/X11/fonts/misc/,/usr/share/X11/fonts/Speedo/,\
 /usr/share/X11/fonts/Type1/,/usr/share/X11/fonts/75dpi/,\
-/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/"
+/usr/share/X11/fonts/100dpi/,/usr/share/X11/fonts/TTF/,\
+/usr/NX/share/fonts/base"
 
 #define NXAGENT_ALTERNATE_FONT_PATH_2  \
 "/usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Speedo/,\
 /usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,\
-/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/"
+/usr/share/fonts/X11/100dpi/,/usr/share/fonts/X11/TTF/,\
+/usr/NX/share/fonts/base"
 
 #define NXAGENT_ALTERNATE_FONT_PATH_3  \
 "/usr/share/fonts/misc/,/usr/share/fonts/Speedo/,\
 /usr/share/fonts/Type1/,/usr/share/fonts/75dpi/,\
-/usr/share/fonts/100dpi/,/usr/share/fonts/TTF/"
+/usr/share/fonts/100dpi/,/usr/share/fonts/TTF/,\
+/usr/NX/share/fonts/base"
+
+#define NXAGENT_ALTERNATE_FONT_PATH_4  \
+"/usr/NX/share/fonts/base"
 
 #undef NXAGENT_FONTCACHE_DEBUG
 #undef NXAGENT_RECONNECT_FONT_DEBUG
@@ -1553,6 +1561,31 @@ void nxagentVerifyDefaultFontPath(void)
     strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_3);
   }
 
+  if (stat(NXAGENT_ALTERNATE_FONT_DIR_4, &dirStat) == 0 &&
+          S_ISDIR(dirStat.st_mode) != 0)
+  {
+    /*
+     * Let's use the "/usr/NX/share/fonts" path.
+     */
+
+    #ifdef TEST
+    fprintf(stderr, "nxagentVerifyDefaultFontPath: Assuming fonts in directory [%s].\n",
+                validateString(NXAGENT_ALTERNATE_FONT_DIR_4));
+    #endif
+
+    if (*fontPath != '\0')
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_4) + 2);
+      strcat(fontPath, ",");
+    }
+    else
+    {
+      fontPath = realloc(fontPath, strlen(fontPath) + strlen(NXAGENT_ALTERNATE_FONT_PATH_4) + 1);
+    }
+
+    strcat(fontPath, NXAGENT_ALTERNATE_FONT_PATH_4);
+  }
+
   if (*fontPath == '\0') 
   {
     #ifdef WARNING
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 37e49eaeb..73b4c706a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -75,6 +75,8 @@ is" without express or implied warranty.
 static int nxagentXkbGetNames(char **rules, char **model, char **layout,
                                   char **variant, char **options);
 
+static void nxagentKeycodeConversionSetup(void);
+
 #endif /* XKB */
 
 /*
@@ -189,6 +191,281 @@ unsigned int nxagentAltMetaMask;
 
 void nxagentCheckAltMetaKeys(CARD8, int);
 
+static CARD8 nxagentConvertedKeycodes[] =
+{
+  /* evdev  pc105*/
+  /*   0 */   0,
+  /*   1 */   1,
+  /*   2 */   2,
+  /*   3 */   3,
+  /*   4 */   4,
+  /*   5 */   5,
+  /*   6 */   6,
+  /*   7 */   7,
+  /*   8 */   8,
+  /*   9 */   9,
+  /*  10 */   10,
+  /*  11 */   11,
+  /*  12 */   12,
+  /*  13 */   13,
+  /*  14 */   14,
+  /*  15 */   15,
+  /*  16 */   16,
+  /*  17 */   17,
+  /*  18 */   18,
+  /*  19 */   19,
+  /*  20 */   20,
+  /*  21 */   21,
+  /*  22 */   22,
+  /*  23 */   23,
+  /*  24 */   24,
+  /*  25 */   25,
+  /*  26 */   26,
+  /*  27 */   27,
+  /*  28 */   28,
+  /*  29 */   29,
+  /*  30 */   30,
+  /*  31 */   31,
+  /*  32 */   32,
+  /*  33 */   33,
+  /*  34 */   34,
+  /*  35 */   35,
+  /*  36 */   36,
+  /*  37 */   37,
+  /*  38 */   38,
+  /*  39 */   39,
+  /*  40 */   40,
+  /*  41 */   41,
+  /*  42 */   42,
+  /*  43 */   43,
+  /*  44 */   44,
+  /*  45 */   45,
+  /*  46 */   46,
+  /*  47 */   47,
+  /*  48 */   48,
+  /*  49 */   49,
+  /*  50 */   50,
+  /*  51 */   51,
+  /*  52 */   52,
+  /*  53 */   53,
+  /*  54 */   54,
+  /*  55 */   55,
+  /*  56 */   56,
+  /*  57 */   57,
+  /*  58 */   58,
+  /*  59 */   59,
+  /*  60 */   60,
+  /*  61 */   61,
+  /*  62 */   62,
+  /*  63 */   63,
+  /*  64 */   64,
+  /*  65 */   65,
+  /*  66 */   66,
+  /*  67 */   67,
+  /*  68 */   68,
+  /*  69 */   69,
+  /*  70 */   70,
+  /*  71 */   71,
+  /*  72 */   72,
+  /*  73 */   73,
+  /*  74 */   74,
+  /*  75 */   75,
+  /*  76 */   76,
+  /*  77 */   77,
+  /*  78 */   78,
+  /*  79 */   79,
+  /*  80 */   80,
+  /*  81 */   81,
+  /*  82 */   82,
+  /*  83 */   83,
+  /*  84 */   84,
+  /*  85 */   85,
+  /*  86 */   86,
+  /*  87 */   87,
+  /*  88 */   88,
+  /*  89 */   89,
+  /*  90 */   90,
+  /*  91 */   91,
+  /*  92 */  124,
+  /*  93 */   93,
+  /*  94 */   94,
+  /*  95 */   95,
+  /*  96 */   96,
+  /*  97 */  211,
+  /*  98 */   98,
+  /*  99 */   99,
+  /* 100 */  100,
+  /* 101 */  208,
+  /* 102 */  102,
+  /* 103 */  103,
+  /* 104 */  108,
+  /* 105 */  109,
+  /* 106 */  112,
+  /* 107 */  111,
+  /* 108 */  113,
+  /* 109 */  109,
+  /* 110 */   97,
+  /* 111 */   98,
+  /* 112 */   99,
+  /* 113 */  100,
+  /* 114 */  102,
+  /* 115 */  103,
+  /* 116 */  104,
+  /* 117 */  105,
+  /* 118 */  106,
+  /* 119 */  107,
+  /* 120 */  120,
+  /* 121 */  121,
+  /* 122 */  122,
+  /* 123 */  123,
+  /* 124 */  124,
+  /* 125 */  126,
+  /* 126 */  126,
+  /* 127 */  110,
+  /* 128 */  128,
+  /* 129 */  129,
+  /* 130 */  130,
+  /* 131 */  131,
+  /* 132 */  133,
+  /* 133 */  115,
+  /* 134 */  116,
+  /* 135 */  117,
+  /* 136 */  136,
+  /* 137 */  137,
+  /* 138 */  138,
+  /* 139 */  139,
+  /* 140 */  140,
+  /* 141 */  141,
+  /* 142 */  142,
+  /* 143 */  143,
+  /* 144 */  144,
+  /* 145 */  145,
+  /* 146 */  146,
+  /* 147 */  147,
+  /* 148 */  148,
+  /* 149 */  149,
+  /* 150 */  150,
+  /* 151 */  151,
+  /* 152 */  152,
+  /* 153 */  153,
+  /* 154 */  154,
+  /* 155 */  155,
+  /* 156 */  156,
+  /* 157 */  157,
+  /* 158 */  158,
+  /* 159 */  159,
+  /* 160 */  160,
+  /* 161 */  161,
+  /* 162 */  162,
+  /* 163 */  163,
+  /* 164 */  164,
+  /* 165 */  165,
+  /* 166 */  166,
+  /* 167 */  167,
+  /* 168 */  168,
+  /* 169 */  169,
+  /* 170 */  170,
+  /* 171 */  171,
+  /* 172 */  172,
+  /* 173 */  173,
+  /* 174 */  174,
+  /* 175 */  175,
+  /* 176 */  176,
+  /* 177 */  177,
+  /* 178 */  178,
+  /* 179 */  179,
+  /* 180 */  180,
+  /* 181 */  181,
+  /* 182 */  182,
+  /* 183 */  183,
+  /* 184 */  184,
+  /* 185 */  185,
+  /* 186 */  186,
+  /* 187 */  187,
+  /* 188 */  188,
+  /* 189 */  189,
+  /* 190 */  190,
+  /* 191 */  118,
+  /* 192 */  119,
+  /* 193 */  120,
+  /* 194 */  121,
+  /* 195 */  122,
+  /* 196 */  196,
+  /* 197 */  197,
+  /* 198 */  198,
+  /* 199 */  199,
+  /* 200 */  200,
+  /* 201 */  201,
+  /* 202 */  202,
+  /* 203 */   93,
+  /* 204 */  125,
+  /* 205 */  156,
+  /* 206 */  127,
+  /* 207 */  128,
+  /* 208 */  208,
+  /* 209 */  209,
+  /* 210 */  210,
+  /* 211 */  211,
+  /* 212 */  212,
+  /* 213 */  213,
+  /* 214 */  214,
+  /* 215 */  215,
+  /* 216 */  216,
+  /* 217 */  217,
+  /* 218 */  218,
+  /* 219 */  219,
+  /* 220 */  220,
+  /* 221 */  221,
+  /* 222 */  222,
+  /* 223 */  223,
+  /* 224 */  224,
+  /* 225 */  225,
+  /* 226 */  226,
+  /* 227 */  227,
+  /* 228 */  228,
+  /* 229 */  229,
+  /* 230 */  230,
+  /* 231 */  231,
+  /* 232 */  232,
+  /* 233 */  233,
+  /* 234 */  234,
+  /* 235 */  235,
+  /* 236 */  236,
+  /* 237 */  237,
+  /* 238 */  238,
+  /* 239 */  239,
+  /* 240 */  240,
+  /* 241 */  241,
+  /* 242 */  242,
+  /* 243 */  243,
+  /* 244 */  244,
+  /* 245 */  245,
+  /* 246 */  246,
+  /* 247 */  247,
+  /* 248 */  248,
+  /* 249 */  249,
+  /* 250 */  250,
+  /* 251 */  251,
+  /* 252 */  252,
+  /* 253 */  253,
+  /* 254 */  254,
+  /* 255 */  255
+};
+
+static int nxagentKeycodeConversion = 0;
+
+CARD8 nxagentConvertKeycode(CARD8 k)
+{
+ if (nxagentKeycodeConversion != 0)
+ {
+   return nxagentConvertedKeycodes[k];
+ }
+ else
+ {
+   return k;
+ }
+}
+
 static int nxagentSaveKeyboardDeviceData(DeviceIntPtr dev, DeviceIntPtr devBackup);
 
 static int nxagentRestoreKeyboardDeviceData(DeviceIntPtr devBackup, DeviceIntPtr dev);
@@ -398,13 +675,6 @@ int nxagentKeyboardProc(DeviceIntPtr pDev, int onoff)
 
   int ret;
 
-  char *remoteRules = NULL;
-  char *remoteModel = NULL;
-
-  unsigned int remoteRulesLen;
-
-  XkbRF_VarDefsRec remoteDefs;
-
   switch (onoff)
   {
     case DEVICE_INIT:
@@ -676,14 +946,21 @@ XkbError:
 
         xkb = XkbGetKeyboard(nxagentDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
 
+        nxagentKeycodeConversionSetup();
+
         if (xkb == NULL || xkb->geom == NULL)
         {
           #ifdef TEST
           fprintf(stderr, "nxagentKeyboardProc: No current keyboard.\n");
-          #endif
-
-          #ifdef TEST
-          fprintf(stderr, "nxagentKeyboardProc: No keyboard, going to set rules and init device.\n");
+          if (xkb == NULL)
+          {
+            fprintf(stderr, "nxagentKeyboardProc: xkb is null.\n");
+          }
+          else
+          {
+            fprintf(stderr, "nxagentKeyboardProc: xkb->geom is null.\n");
+          }
+          fprintf(stderr, "nxagentKeyboardProc: Going to set rules and init device.\n");
           #endif
 
           XkbSetRulesDflts(rules, model, layout, variants, options);
@@ -699,40 +976,6 @@ XkbError:
           goto XkbEnd;
         }
 
-        if (xkb != NULL)
-        {
-          char *drules = 0;
-          char *dmodel = 0;
-          char *dlayout = 0;
-          char *dvariant = 0;
-          char *doptions = 0;
-
-          remoteRulesLen = nxagentXkbGetNames(&drules, &dmodel, &dlayout,
-                                                  &dvariant, &doptions);
-
-          if (remoteRulesLen != 0 && drules != NULL && dmodel != NULL)
-          {
-            #ifdef DEBUG
-            fprintf(stderr, "nxagentKeyboardProc: Remote: [%s,%s,%s,%s,%s].\n",
-                        drules, dmodel, dlayout, dvariant, doptions);
-            #endif
-
-            remoteRules = drules;
-            remoteModel = dmodel;
-            remoteDefs.model = dmodel;
-            remoteDefs.layout = dlayout;
-            remoteDefs.variant = dvariant;
-            remoteDefs.options = doptions;
-          }
-          #ifdef DEBUG
-          else
-          {
-            fprintf(stderr, "nxagentKeyboardProc: Failed to retrieve remote "
-                        "rules");
-          }
-          #endif
-        }
-
         XkbGetControls(nxagentDisplay, XkbAllControlsMask, xkb);
 
         nxagentXkbConfigFilePathSize = strlen(XkbBaseDirectory) +
@@ -813,66 +1056,6 @@ XkbError:
 
           free(nxagentXkbConfigFilePath);
 
-          if (xkb != NULL && nxagentOption(ClientOs) == ClientOsLinux &&
-                  remoteRules != NULL && remoteModel != NULL &&
-                      (strcmp(remoteRules, "evdev") == 0 ||
-                          strcmp(remoteModel, "evdev") == 0) &&
-                              pDev->key->xkbInfo != NULL &&
-                                  pDev->key->xkbInfo->desc != NULL)
-          {
-            XkbDescPtr xkbt;
-            void *tmp;
-            #ifdef _XSERVER64
-            int i;
-            #endif
-
-            xkbt = pDev->key->xkbInfo->desc;
-
-            xkbt->min_key_code = xkb->min_key_code;
-            xkbt->max_key_code = xkb->max_key_code;
-
-            if (xkbt->map != NULL && xkb->map != NULL)
-            {
-              tmp = (void *)xkbt->map;
-              xkbt->map = xkb->map;
-              xkb->map = (XkbClientMapPtr)tmp;
-
-              #ifdef _XSERVER64
-
-              tmp = (void *) xkbt->map->syms;
-              xkbt->map->syms = xalloc(xkbt->map->size_syms * sizeof(KeySym));
-
-              for (i = 0; i < xkbt->map->size_syms; i++)
-              {
-                xkbt->map->syms[i] = ((KeySym64 *)tmp)[i];
-              }
-
-              #endif
-            }
-
-            if (xkbt->server != NULL && xkb->server != NULL)
-            {
-              tmp = (void *)xkbt->server;
-              xkbt->server = xkb->server;
-              xkb->server = (XkbServerMapPtr)tmp;
-            }
-
-            if (xkbt->compat != NULL && xkb->compat != NULL)
-            {
-              tmp = (void *)xkbt->compat;
-              xkbt->compat = xkb->compat;
-              xkb->compat = (XkbCompatMapPtr)tmp;
-            }
-
-            XkbSetRulesDflts(remoteRules, remoteDefs.model, remoteDefs.layout,
-                                 remoteDefs.variant, remoteDefs.options);
-            XkbSetRulesUsed(&remoteDefs);
-
-            free(remoteRules);
-
-            goto XkbEnd;
-          }
-
           if (!nxagentKeyboard ||
                  (nxagentKeyboard && (strcmp(nxagentKeyboard, "query") == 0)))
           {
@@ -1562,4 +1745,71 @@ static int nxagentXkbGetNames(char **rules, char **model, char **layout,
   return n;
 }
 
+void nxagentKeycodeConversionSetup(void)
+{
+  char *drules = 0;
+  char *dmodel = 0;
+  char *dlayout = 0;
+  char *dvariant = 0;
+  char *doptions = 0;
+  unsigned int drulesLen;
+
+  nxagentKeycodeConversion = 0;
+
+  drulesLen = nxagentXkbGetNames(&drules, &dmodel, &dlayout,
+                                     &dvariant, &doptions);
+
+  #ifdef DEBUG
+  if (drulesLen != 0 && drules != NULL && dmodel != NULL)
+  {
+    fprintf(stderr, "nxagentKeycodeConversionSetup: "
+                "Remote: [%s,%s,%s,%s,%s].\n", drules, dmodel, dlayout,
+                    dvariant, doptions);
+  }
+  else
+  {
+    fprintf(stderr, "nxagentKeycodeConversionSetup: "
+                "Failed to retrieve remote rules.\n");
+  }
+  #endif
+
+  if (nxagentOption(ClientOs) == ClientOsLinux &&
+            drules != NULL && dmodel != NULL &&
+                (strcmp(drules, "evdev") == 0 ||
+                    strcmp(dmodel, "evdev") == 0))
+  {
+    nxagentKeycodeConversion = 1;
+  }
+
+  if (drules != NULL)
+  {
+    XFree(drules);
+  }
+}
+
+void nxagentResetKeycodeConversion(void)
+{
+  int result;
+  XkbAgentInfoRec info;
+  XkbDescPtr xkb;
+
+  result = XkbQueryExtension(nxagentDisplay, &info.Opcode, &info.EventBase,
+                                 &info.ErrorBase, &info.MajorVersion,
+                                     &info.MinorVersion);
+
+  if (result != 0)
+  {
+    nxagentKeycodeConversionSetup();
+  }
+  else
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentResetKeycodeConversion: "
+                "WARNING! Failed to query XKB extension.\n");
+    #endif
+
+    nxagentKeycodeConversion = 0;
+  }
+}
+
 #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index f292402d2..50dd2be78 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -109,6 +109,10 @@ void nxagentEnableXkbExtension(void);
 
 void nxagentTuneXkbWrapper(void);
 
+void nxagentResetKeycodeConversion(void);
+
 #endif
 
+CARD8 nxagentConvertKeycode(CARD8 k);
+
 #endif /* __Keyboard_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index ce3e6ee05..69b73a942 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -547,28 +547,29 @@ Bool nxagentReconnectSession(void)
     goto nxagentReconnectError;
   }
 
-  if (nxagentOption(ResetKeyboardAtResume))
+  if (nxagentOption(ResetKeyboardAtResume) == 1 &&
+         (nxagentKeyboard  == NULL || nxagentOldKeyboard == NULL ||
+             strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
+                 strcmp(nxagentKeyboard, "query") == 0))
   {
-    if (nxagentKeyboard  == NULL || nxagentOldKeyboard == NULL ||
-           strcmp(nxagentKeyboard, nxagentOldKeyboard) != 0 ||
-               strcmp(nxagentKeyboard, "query") == 0)
+    if (nxagentResetKeyboard() == 0)
     {
-
-      if (nxagentResetKeyboard() == 0)
+      #ifdef WARNING
+      if (nxagentVerbose == 1)
       {
-        #ifdef WARNING
-        if (nxagentVerbose == 1)
-        {
-          fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
-        }
-        #endif
+        fprintf(stderr, "nxagentReconnect: Failed to reset keyboard device.\n");
+      }
+      #endif
 
-        failedStep = WINDOW_STEP;
+      failedStep = WINDOW_STEP;
 
-        goto nxagentReconnectError;
-      }
+      goto nxagentReconnectError;
     }
   }
+  else
+  {
+    nxagentResetKeycodeConversion();
+  }
 
   nxagentXkbState.Initialized = 0;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index b1ff219e7..f2d7b15f9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -2270,8 +2270,7 @@ void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
 
   normalizedImages = NULL;
 
-  if (glyphDepths[glyphSet -> fdepth] == 1 &&
-          nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
+  if (sizeImages > 0)
   {
     normalizedImages = xalloc(sizeImages);
 
@@ -2279,7 +2278,11 @@ void nxagentAddGlyphs(GlyphSetPtr glyphSet, Glyph *gids, xGlyphInfo *gi,
     {
       memcpy(normalizedImages, images, sizeImages);
 
-      BitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
+      if (glyphDepths[glyphSet -> fdepth] == 1 &&
+              nxagentServerOrder() != BitmapBitOrder(nxagentDisplay))
+      {
+        BitOrderInvert ((unsigned char *) normalizedImages, sizeImages);
+      }
     }
     else
     {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index 91e290996..a8a2a68bd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -189,6 +189,10 @@ xEvent *xeviexE;
 #include "Windows.h"
 #include "Args.h"
 
+#ifdef NX_DEBUG_INPUT
+extern int nxagentDebugInput;
+#endif
+ 
 extern Display *nxagentDisplay;
 
 extern WindowPtr nxagentLastEnteredWindow;
@@ -1682,10 +1686,27 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
     int i;
     int type;
 
-#ifdef DEBUG
+#ifdef NX_DEBUG_INPUT
+    if (grab && nxagentDebugInput && grab->window)
+    {
+	fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n",
+		(unsigned int)grab->window->drawable.id);
+	if (!SameClient(grab, client))
+		fprintf(stderr, "TryClientEvents: Events are going to be "
+			    "discarded.\n");
+    }
+#endif
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask,
+	client->index);
+#else
     if (debug_events) ErrorF(
 	"Event([%d, %d], mask=0x%x), client=%d",
 	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
 #endif
     if ((client) && (client != serverClient) && (!client->clientGone) &&
 	((filter == CantBeFiltered) || (mask & filter)))
@@ -1700,9 +1721,16 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
 		    pEvents->u.keyButtonPointer.event)
 		{
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+    {
+	fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n");
+    }
+#else
 		    if (debug_events) ErrorF("\n");
 	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
 #endif
 		    return 1; /* don't send, but pretend we did */
 		}
@@ -1740,15 +1768,25 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 	}
 
 	WriteEventsToClient(client, count, pEvents);
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, " delivered\n");
+#else
 	if (debug_events) ErrorF(  " delivered\n");
+#endif
 #endif
 	return 1;
     }
     else
     {
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "\n");
+#else
 	if (debug_events) ErrorF("\n");
+#endif
 #endif
 	return 0;
     }
@@ -3116,6 +3154,12 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
         xevieEventSent = 0;
       else {
         xeviemouse = mouse;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInput == 1)
+        {
+          fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n");
+        }
+        #endif
         WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
         return;
       }
@@ -3170,14 +3214,38 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
+	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonPress.\n");
+		}
+		return;
+	    }
+	    #else
 	    if (xE->u.u.detail == 0)
 		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!grab)
+	    #ifdef NX_DEBUG_INPUT
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		{
+		    if (nxagentDebugInput == 1)
+		    {
+			fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs"
+				" returned True for ButtonPress.\n");
+		    }
+		    return;
+		}
+	    #else
 		if (CheckDeviceGrabs(mouse, xE, 0, count))
 		    return;
+	    #endif
 	    break;
 	case ButtonRelease: 
 	    mouse->valuator->motionHintWindow = NullWindow;
@@ -3189,8 +3257,20 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
 	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonRelease.\n");
+		}
 		return;
+	    }
+	    #else
+	    if (xE->u.u.detail == 0)
+		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 	    filters[MotionNotify] = Motion_Filter(butc);
@@ -3201,6 +3281,36 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 	    FatalError("bogus pointer event from ddx");
 	}
     }
+    #ifdef NX_DEBUG_INPUT
+    else if (!CheckMotion(xE))
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False"
+		    " for MotionNotify.\n");
+	}
+	return;
+    }
+    if (grab)
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed "
+		    "events (count = %d).\n", count);
+	}
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    }
+    else
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver device "
+		    "events (count = %d).\n", count);
+	}
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    }
+    #else
     else if (!CheckMotion(xE))
 	return;
     if (grab)
@@ -3208,6 +3318,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     else
 	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
 			    mouse, count);
+    #endif
     if (deactivateGrab)
         (*mouse->DeactivateGrab)(mouse);
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index 91e290996..a8a2a68bd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -189,6 +189,10 @@ xEvent *xeviexE;
 #include "Windows.h"
 #include "Args.h"
 
+#ifdef NX_DEBUG_INPUT
+extern int nxagentDebugInput;
+#endif
+ 
 extern Display *nxagentDisplay;
 
 extern WindowPtr nxagentLastEnteredWindow;
@@ -1682,10 +1686,27 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
     int i;
     int type;
 
-#ifdef DEBUG
+#ifdef NX_DEBUG_INPUT
+    if (grab && nxagentDebugInput && grab->window)
+    {
+	fprintf(stderr, "TryClientEvents: Grab window is [0x%x].\n",
+		(unsigned int)grab->window->drawable.id);
+	if (!SameClient(grab, client))
+		fprintf(stderr, "TryClientEvents: Events are going to be "
+			    "discarded.\n");
+    }
+#endif
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "Event([%d, %d], mask=0x%x), client=%d",
+	pEvents->u.u.type, pEvents->u.u.detail, (unsigned int)mask,
+	client->index);
+#else
     if (debug_events) ErrorF(
 	"Event([%d, %d], mask=0x%x), client=%d",
 	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+#endif
 #endif
     if ((client) && (client != serverClient) && (!client->clientGone) &&
 	((filter == CantBeFiltered) || (mask & filter)))
@@ -1700,9 +1721,16 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 		if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
 		    pEvents->u.keyButtonPointer.event)
 		{
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+    {
+	fprintf(stderr,"\nmotionHintWindow == keyButtonPointer.event\n");
+    }
+#else
 		    if (debug_events) ErrorF("\n");
 	    fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
+#endif
 #endif
 		    return 1; /* don't send, but pretend we did */
 		}
@@ -1740,15 +1768,25 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
 	}
 
 	WriteEventsToClient(client, count, pEvents);
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, " delivered\n");
+#else
 	if (debug_events) ErrorF(  " delivered\n");
+#endif
 #endif
 	return 1;
     }
     else
     {
-#ifdef DEBUG
+#if defined(DEBUG) || defined(NX_DEBUG_INPUT)
+#ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInput == 1)
+	fprintf(stderr, "\n");
+#else
 	if (debug_events) ErrorF("\n");
+#endif
 #endif
 	return 0;
     }
@@ -3116,6 +3154,12 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
         xevieEventSent = 0;
       else {
         xeviemouse = mouse;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInput == 1)
+        {
+          fprintf(stderr, "ProcessPointerEvent: Going to send XEVIE event.\n");
+        }
+        #endif
         WriteToClient(clients[xevieClientIndex], sizeof(xEvent), (char *)xE);
         return;
       }
@@ -3170,14 +3214,38 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
+	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonPress.\n");
+		}
+		return;
+	    }
+	    #else
 	    if (xE->u.u.detail == 0)
 		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!grab)
+	    #ifdef NX_DEBUG_INPUT
+		if (CheckDeviceGrabs(mouse, xE, 0, count))
+		{
+		    if (nxagentDebugInput == 1)
+		    {
+			fprintf(stderr, "ProcessPointerEvent: CheckDeviceGrabs"
+				" returned True for ButtonPress.\n");
+		    }
+		    return;
+		}
+	    #else
 		if (CheckDeviceGrabs(mouse, xE, 0, count))
 		    return;
+	    #endif
 	    break;
 	case ButtonRelease: 
 	    mouse->valuator->motionHintWindow = NullWindow;
@@ -3189,8 +3257,20 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 #if !defined(XFree86Server) || !defined(XINPUT)
 	    xE->u.u.detail = butc->map[key];
 #endif
+	    #ifdef NX_DEBUG_INPUT
 	    if (xE->u.u.detail == 0)
+	    {
+		if (nxagentDebugInput == 1)
+		{
+		    fprintf(stderr, "ProcessPointerEvent: WARNING! detail == 0"
+			    " for ButtonRelease.\n");
+		}
 		return;
+	    }
+	    #else
+	    if (xE->u.u.detail == 0)
+		return;
+	    #endif
 	    if (xE->u.u.detail <= 5)
 		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 	    filters[MotionNotify] = Motion_Filter(butc);
@@ -3201,6 +3281,36 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 	    FatalError("bogus pointer event from ddx");
 	}
     }
+    #ifdef NX_DEBUG_INPUT
+    else if (!CheckMotion(xE))
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: CheckMotion returned False"
+		    " for MotionNotify.\n");
+	}
+	return;
+    }
+    if (grab)
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver grabbed "
+		    "events (count = %d).\n", count);
+	}
+	DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
+    }
+    else
+    {
+	if (nxagentDebugInput == 1)
+	{
+	    fprintf(stderr, "ProcessPointerEvent: Going to deliver device "
+		    "events (count = %d).\n", count);
+	}
+	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
+			    mouse, count);
+    }
+    #else
     else if (!CheckMotion(xE))
 	return;
     if (grab)
@@ -3208,6 +3318,7 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
     else
 	DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
 			    mouse, count);
+    #endif
     if (deactivateGrab)
         (*mouse->DeactivateGrab)(mouse);
 }
-- 
cgit v1.2.3


From e9132da09462b3d2607a97e2f580cbd3144819eb Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:57 +0200
Subject: Imported nxagent-3.4.0-11.tar.gz

Summary: Imported nxagent-3.4.0-11.tar.gz
Keywords:

Imported nxagent-3.4.0-11.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Agent.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |   8 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.h          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |  32 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       | 200 +++++
 nx-X11/programs/Xserver/hw/nxagent/Client.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Client.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |  28 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c      |  21 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.h      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.c     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.h     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h        |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |  40 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.h       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |  98 ++-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.h      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.c         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 924 ++++++++++++++++++---
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.c    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.h    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |  18 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.h          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/GC.c            |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         |  91 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/GCs.h           |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |  30 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.h      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Icons.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.c         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Imakefile       |   3 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |   8 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.h          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      |   5 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     | 121 ++-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.h     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/LICENSE         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Literals.h      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c    |   4 +-
 .../Xserver/hw/nxagent/NXdispatch.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c    |   4 +-
 .../Xserver/hw/nxagent/NXdixfonts.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXevents.c      |   4 +-
 .../Xserver/hw/nxagent/NXevents.c.NX.original      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXextension.c   |   4 +-
 .../Xserver/hw/nxagent/NXextension.c.NX.original   |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c       |   4 +-
 .../Xserver/hw/nxagent/NXglyph.c.NX.original       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c   |   4 +-
 .../Xserver/hw/nxagent/NXglyphcurs.c.NX.original   |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h    |   4 +-
 .../Xserver/hw/nxagent/NXglyphstr.h.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c     |   4 +-
 .../Xserver/hw/nxagent/NXmiglyph.c.NX.original     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c     |   4 +-
 .../Xserver/hw/nxagent/NXpicture.c.NX.original     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h  |   4 +-
 .../Xserver/hw/nxagent/NXpicturestr.h.NX.original  |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c    |   4 +-
 .../Xserver/hw/nxagent/NXproperty.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c       |   4 +-
 .../Xserver/hw/nxagent/NXrandr.c.NX.original       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrender.c      |   4 +-
 .../Xserver/hw/nxagent/NXrender.c.NX.original      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c      |   4 +-
 .../Xserver/hw/nxagent/NXwindow.c.NX.original      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h   |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |  15 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.h        |  22 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmap.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.c       |  38 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.h       |  13 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |  16 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.h     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        | 285 ++++++-
 nx-X11/programs/Xserver/hw/nxagent/Render.h        |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      | 111 ++-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.h      |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        | 424 +++-------
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |  15 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.c         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/TestExt.c       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.c          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.h          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Utils.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.c        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Window.c        | 313 +++----
 nx-X11/programs/Xserver/hw/nxagent/Windows.h       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c    |   4 +-
 .../Xserver/hw/nxagent/X/NXdamage.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |  26 +-
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |  26 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  |   4 +-
 .../Xserver/hw/nxagent/X/NXdixfonts.c.NX.original  |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    | 110 ++-
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    | 110 ++-
 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c |   4 +-
 .../Xserver/hw/nxagent/X/NXextension.c.NX.original |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c    |   4 +-
 .../Xserver/hw/nxagent/X/NXglxext.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   4 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c |   4 +-
 .../Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h  |   4 +-
 .../Xserver/hw/nxagent/X/NXglyphstr.h.NX.original  |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c  |   4 +-
 .../Xserver/hw/nxagent/X/NXmiexpose.c.NX.original  |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c   |   4 +-
 .../Xserver/hw/nxagent/X/NXmiglyph.c.NX.original   |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c    |   4 +-
 .../Xserver/hw/nxagent/X/NXmitrap.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c  |   4 +-
 .../Xserver/hw/nxagent/X/NXmiwindow.c.NX.original  |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c   |  51 +-
 .../Xserver/hw/nxagent/X/NXpicture.c.NX.original   |  51 +-
 .../programs/Xserver/hw/nxagent/X/NXpicturestr.h   |   4 +-
 .../hw/nxagent/X/NXpicturestr.h.NX.original        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |   4 +-
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c     |   4 +-
 .../Xserver/hw/nxagent/X/NXrandr.c.NX.original     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |  62 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |  62 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c  |   4 +-
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   4 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c    |   4 +-
 .../Xserver/hw/nxagent/X/NXwindow.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c    |   4 +-
 .../Xserver/hw/nxagent/X/NXxvdisp.c.NX.original    |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm     |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm   |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/os2Stub.c       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/screensaver     |   4 +-
 161 files changed, 2837 insertions(+), 1066 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Agent.h b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
index f976fd768..3f2c93fdb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Agent.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 5d344729c..c2e58bd58 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -1208,7 +1208,7 @@ static void nxagentParseOptions(char *name, char *value)
     {
       nxagentChangeOption(ClientOs, ClientOsSolaris);
     }
-    else if (strcmp(value, "mac") == 0)
+    else if (strcmp(value, "macosx") == 0)
     {
       nxagentChangeOption(ClientOs, ClientOsMac);
     }
@@ -1512,7 +1512,7 @@ N/A
       int splitMode = 0;
       int splitSize = 0;
 
-      unsigned int packMethod  = PACK_NONE;
+      unsigned int packMethod = PACK_NONE;
       unsigned int packQuality = 9;
 
       int dataLevel   = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
index 43d7ec779..92650a4a0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
index ac26646ae..171df95a9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -66,19 +66,21 @@ Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
 static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
 {
-  "NX_IDENTITY",          /* 0  */
-  "WM_PROTOCOLS",         /* 1  */
-  "WM_DELETE_WINDOW",     /* 2  */
-  "WM_NX_READY",          /* 3  */
-  "MCOPGLOBALS",          /* 4  */
-  "NX_CUT_BUFFER_SERVER", /* 5  */
-  "TARGETS",              /* 6  */
-  "TEXT",                 /* 7  */
-  "NX_AGENT_SIGNATURE",   /* 8  */
-  "NXDARWIN",             /* 9  */
-  "CLIPBOARD",            /* 10 */
-  "TIMESTAMP",            /* 11 */
-  "UTF8_STRING",          /* 12 */
+  "NX_IDENTITY",              /* 0  */
+  "WM_PROTOCOLS",             /* 1  */
+  "WM_DELETE_WINDOW",         /* 2  */
+  "WM_NX_READY",              /* 3  */
+  "MCOPGLOBALS",              /* 4  */
+  "NX_CUT_BUFFER_SERVER",     /* 5  */
+  "TARGETS",                  /* 6  */
+  "TEXT",                     /* 7  */
+  "NX_AGENT_SIGNATURE",       /* 8  */
+  "NXDARWIN",                 /* 9  */
+  "CLIPBOARD",                /* 10 */
+  "TIMESTAMP",                /* 11 */
+  "UTF8_STRING",              /* 12 */
+  "_NET_WM_STATE",            /* 13 */
+  "_NET_WM_STATE_FULLSCREEN", /* 14 */
   NULL,
   NULL
 };
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
index 17b2d8f57..f49f2751e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -22,7 +22,7 @@
 #include "../../include/window.h"
 #include "screenint.h"
 
-#define NXAGENT_NUMBER_OF_ATOMS  14
+#define NXAGENT_NUMBER_OF_ATOMS  16
 
 extern Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.c b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
index cfea2cc77..34433bd2b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.h b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
index 928db74fb..e0da3e357 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 1f7f0df55..3f0a6abcd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,205 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
index 7e86a03d2..acfaab7c0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
index 5f9fa1ebb..45f87fc66 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index a575cabe5..eb830234d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -680,6 +680,30 @@ void nxagentCollectPropertyEvent(int resource)
 
     return;
   }
+ 
+  if (resultFormat != 8 && resultFormat != 16 && resultFormat != 32)
+  {
+
+    #ifdef DEBUG
+    fprintf (stderr, "nxagentCollectPropertyEvent: WARNING! Invalid property "
+                 "value.\n");
+    #endif
+
+    if (lastClientClientPtr != NULL)
+    {
+      nxagentSendSelectionNotify(None);
+    }
+
+    lastClientWindowPtr = NULL;
+    lastClientStage = SelectionStageNone;
+
+    if (pszReturnData != NULL)
+    {
+      XFree(pszReturnData);
+    }
+
+    return;
+  }
 
   switch (lastClientStage)
   {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
index 912260b8b..2750ddfd2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
index 75758679f..259aa3b24 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -291,9 +291,20 @@ void nxagentSetInstalledColormapWindows(ScreenPtr pScreen)
 	  pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
 					      RT_COLORMAP);
 
-	XSetWindowColormap(nxagentDisplay,
-			   nxagentDefaultWindows[pScreen->myNum],
-			   nxagentColormap(pCmap));
+        if (pCmap != NULL)
+        {
+          XSetWindowColormap(nxagentDisplay,
+	                         nxagentDefaultWindows[pScreen->myNum],
+                                     nxagentColormap(pCmap));
+        }
+        #ifdef WARNING
+        else
+        {
+          fprintf(stderr, "nxagentSetInstalledColormapWindows: WARNING! "
+                      "Window at [%p] has no colormap with class [%d].\n",
+                          pWin, pWin -> drawable.class);
+        }
+        #endif
       }
 #endif /* DUMB_WINDOW_MANAGERS */
   }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
index b0cb2dc5e..8321e8038 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
index 9bdbac1b1..b0640ff11 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.h b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
index 5ec1e9888..fb1d6d8e9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
index 3ca29fa5e..141ba3a64 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
index ea1bb30f3..11e407efd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
index c1db78344..2f807b1dc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
index 135cd2df3..aa845c7c2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -42,7 +42,7 @@ extern int nxagentKillDialogPid;
 extern int nxagentSuspendDialogPid;
 extern int nxagentRootlessDialogPid;
 extern int nxagentPulldownDialogPid;
-extern int nxagentFontsReplacement;
+extern int nxagentFontsReplacementDialogPid;
 extern int nxagentEnableRandRModeDialogPid;
 extern int nxagentDisableRandRModeDialogPid;
 extern int nxagentEnableDeferModePid;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index 9f257e508..1a57788e6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -453,6 +453,21 @@ static void nxagentSigchldHandler(int signal)
     }
   }
 
+  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);
@@ -1609,19 +1624,30 @@ void nxagentInitPixmapFormats()
 
   nxagentNumPixmapFormats = 0;
 
-  nxagentPixmapFormats = xalloc(nxagentNumDepths * sizeof(XPixmapFormatValues));
+/*
+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;
 
-    for (j = 0; j < nxagentNumDepths; j++)
+    if (i == 1)
+    {
+      depth = 1;
+    }
+    else
     {
-      if (nxagentDepths[j] == i)
+      for (j = 0; j < nxagentNumDepths; j++)
       {
-        depth = i;
+        if (nxagentDepths[j] == i)
+        {
+          depth = i;
 
-        break;
+          break;
+        }
       }
     }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h
index d18785b60..35b7857ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 2c1b07fa5..75057097a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -32,6 +32,7 @@
 #include "Handlers.h"
 #include "Pixels.h"
 #include "Reconnect.h"
+#include "GCOps.h"
 
 #include "NXlib.h"
 
@@ -418,13 +419,14 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   if (useStoredBitmap != 0)
   {
     #ifdef TEST
-    fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap "
+    fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] has a synchronization bitmap at [%p] "
                 "[%d,%d,%d,%d] with [%ld] rects.\n", nxagentDrawableType(pDrawable),
-                    (void *) pDrawable, nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
-                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
-                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
-                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
-                                    REGION_NUM_RECTS(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
+                    (void *) pDrawable, (void *) nxagentDrawableBitmap(pDrawable),
+                        nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x1,
+                            nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y1,
+                                nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.x2,
+                                    nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable)) -> extents.y2,
+                                        REGION_NUM_RECTS(nxagentCorruptedRegion((DrawablePtr) nxagentDrawableBitmap(pDrawable))));
     #endif
 
     clipRegion = nxagentCreateRegion(pDrawable, NULL, 0, 0, pDrawable -> width, pDrawable -> height);
@@ -581,8 +583,7 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
   #ifdef TEST
   fprintf(stderr, "nxagentSynchronizeRegion: Going to synchronize [%ld] rects of [%s] at [%p].\n",
-              REGION_NUM_RECTS(clipRegion), (pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window"),
-                  (void *) pDrawable);
+              REGION_NUM_RECTS(clipRegion), nxagentDrawableType(pDrawable), (void *) pDrawable);
 
   fprintf(stderr, "nxagentSynchronizeRegion: Extents geometry [%d,%d,%d,%d].\n",
           clipRegion -> extents.x1, clipRegion -> extents.y1, clipRegion -> extents.x2, clipRegion -> extents.y2);
@@ -615,7 +616,22 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
   if (data == NULL)
   {
     #ifdef WARNING
+
     fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Failed to allocate memory for synchronization.\n");
+
+    /*
+     * Print detailed informations if the
+     * image length is zero.
+     */
+
+    if (length == 0)
+    {
+      fprintf(stderr, "nxagentSynchronizeRegion: Drawable [%s] at [%p] with region geometry [%ld][%d,%d,%d,%d].\n",
+                  nxagentDrawableType(pDrawable), (void *) pDrawable, REGION_NUM_RECTS(clipRegion),
+                      clipRegion -> extents.x1, clipRegion -> extents.y1,
+                          clipRegion -> extents.x2, clipRegion -> extents.y2);
+    }
+
     #endif
 
     goto nxagentSynchronizeRegionFree;
@@ -670,10 +686,14 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
         if (nxagentDrawableStatus(pDrawable) == Synchronized)
         {
           #ifdef WARNING
+
           if (pDrawable -> type == DRAWABLE_WINDOW && pSrcDrawable != pDrawable)
+          {
             fprintf(stderr, "nxagentSynchronizeRegion: WARNING! Trying to synchronize "
                         "the clean drawable type [%d] at [%p] with source at [%p].\n",
                             pDrawable -> type, (void *) pDrawable, (void *) pSrcDrawable);
+          }
+
           #endif
 
           goto nxagentSynchronizeRegionStop;
@@ -748,9 +768,6 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
         nxagentGetImage(pSrcDrawable, x, y, w, h, format, AllPlanes, data);
 
-        nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
-                                x, y, w, h, leftPad, format, data);
-
         /*
          * Going to unmark the synchronized
          * region.
@@ -805,6 +822,13 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
 
                 nxagentUnmarkCorruptedRegion(pDrawable, &tileRegion);
               }
+              #ifdef TEST
+              else
+              {
+                fprintf(stderr, "nxagentSynchronizeRegion: Tile [%d,%d,%d,%d] on drawable [%p] doesn't match.\n",
+                            x, y, x + w, y + h, (void *) pDrawable);
+              }
+              #endif
             }
             else
             {
@@ -835,6 +859,14 @@ int nxagentSynchronizeRegion(DrawablePtr pDrawable, RegionPtr pRegion, unsigned
           }
         }
 
+        /*
+         * Realize the image after comparing the
+         * source data with the bitmap data.
+         */
+
+        nxagentRealizeImage(pDrawable, pGC, pDrawable -> depth,
+                                x, y, w, h, leftPad, format, data);
+
         REGION_UNINIT(pDrawable -> pScreen, &tileRegion);
 
         #if !defined(COLLECTED_UPDATES)
@@ -2555,16 +2587,13 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
   GCPtr pGC = NULL;
   RegionPtr pClipRegion = NullRegion;
 
-  char *data = NULL;
-
   int x, y;
   int w, h;
-  int length, format;
   int saveTrap;
 
   #ifdef TEST
-  fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for drawable at [%p].\n",
-              (void *) pDrawable);
+  fprintf(stderr, "nxagentCreateDrawableBitmap: Creating synchronization bitmap for [%s] at [%p].\n",
+              nxagentDrawableType(pDrawable), (void *) pDrawable);
   #endif
 
   /*
@@ -2652,24 +2681,8 @@ void nxagentCreateDrawableBitmap(DrawablePtr pDrawable)
   w = pClipRegion -> extents.x2 - pClipRegion -> extents.x1;
   h = pClipRegion -> extents.y2 - pClipRegion -> extents.y1;
 
-  data = nxagentAllocateImageData(w, h, pDrawable -> depth, &length, &format);
-
-  if (data == NULL)
-  {
-    #ifdef WARNING
-    fprintf(stderr, "nxagentCreateDrawableBitmap: Cannot allocate memory for the bitmap data.\n");
-    #endif
-
-    nxagentDestroyPixmap(pBitmap);
+  nxagentCopyArea(pDrawable, (DrawablePtr) pBitmap, pGC, x, y, w, h, x, y);
 
-    goto nxagentCreateDrawableBitmapEnd;
-  }
-
-  nxagentGetImage(pDrawable, x, y, w, h, format, AllPlanes, data);
-
-  nxagentPutImage((DrawablePtr) pBitmap, pGC, pBitmap -> drawable.depth, x, y, w, h,
-                      0, format, data);
- 
   REGION_UNION(pDrawable -> pScreen, nxagentCorruptedRegion((DrawablePtr) pBitmap),
                    nxagentCorruptedRegion((DrawablePtr) pBitmap), pClipRegion);
 
@@ -2711,11 +2724,6 @@ nxagentCreateDrawableBitmapEnd:
     nxagentFreeRegion(pDrawable, pClipRegion);
   }
 
-  if (data != NULL)
-  {
-    xfree(data);
-  }
-
   if (pGC != NULL)
   {
     FreeScratchGC(pGC);
@@ -3091,6 +3099,16 @@ void nxagentSendBackgroundExpose(WindowPtr pWin, PixmapPtr pBackground, RegionPt
 
   REGION_INTERSECT(pWin -> pScreen, &expose, &expose, &pWin -> clipList);
 
+  /*
+   * Reduce the overall region to expose.
+   */
+  
+  REGION_TRANSLATE(pWin -> pScreen, &expose, -pWin -> drawable.x, -pWin -> drawable.y);
+  
+  REGION_SUBTRACT(pWin -> pScreen, pExpose, pExpose, &expose);
+  
+  REGION_TRANSLATE(pWin -> pScreen, &expose, pWin -> drawable.x, pWin -> drawable.y);
+
   miWindowExposures(pWin, &expose, &expose);
 
 nxagentSendBackgroundExposeEnd:
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
index 62af0685d..146610efb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.c b/nx-X11/programs/Xserver/hw/nxagent/Error.c
index e60845dd3..963cfa287 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.h b/nx-X11/programs/Xserver/hw/nxagent/Error.h
index 78e15592b..2d6083d4e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 3c1458cb7..1576962fb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -76,7 +76,9 @@
 #include "input.h"
 #endif
 
+#define Time XlibXID
 #include "XKBlib.h"
+#undef Time
 
 #define GC     XlibGC
 #define Font   XlibFont
@@ -203,6 +205,8 @@ CARD32 nxagentLastEventTime     = 0;
 CARD32 nxagentLastKeyPressTime  = 0;
 Time   nxagentLastServerTime    = 0;
 
+int nxagentPointerAndKeyboardGrabbed = 0;
+
 /*
  * Used for storing windows that need to
  * receive expose events from the agent.
@@ -218,6 +222,16 @@ static void nxagentForwardRemoteExpose(void);
 
 static int nxagentClipAndSendExpose(WindowPtr pWin, pointer ptr);
 
+/*
+ * This is from NXproperty.c.
+ */
+
+int GetWindowProperty(WindowPtr pWin, Atom property, long longOffset,
+                          long longLength, Bool delete, Atom type,
+                              Atom *actualType, int *format, unsigned
+                                  long *nItems, unsigned long *bytesAfter,
+                                      unsigned char **propData);
+
 /*
  * Associate a resource to a drawable and
  * store the region affected by the split
@@ -274,6 +288,280 @@ void ProcessInputEvents()
   mieqProcessInputEvents();
 }
 
+#ifdef DEBUG_TREE
+
+/*
+ * Print ID and name of window.
+ */
+
+void nxagentRemoteWindowID(Window window, Bool newline)
+{
+#ifdef NO_I18N
+    char *winName;
+#else
+    XTextProperty tp;
+#endif
+
+  fprintf(stderr, "0x%lx", window);
+
+  if (!window)
+  {
+    fprintf(stderr, " (none) ");
+  }
+  else
+  {
+    if (window == DefaultRootWindow(nxagentDisplay))
+    {
+      fprintf(stderr, " (the root window) ");
+    }
+
+#ifdef NO_I18N
+
+    if (!XFetchName(nxagentDisplay, window, &winName))
+    {
+      fprintf(stderr, " (has no name) ");
+    }
+    else if (winName)
+    {
+      fprintf(stderr, " \"%s\" ", winName);
+      XFree(winName);
+    }
+
+#else
+
+    if (XGetWMName(nxagentDisplay, window, &tp) != 0)
+    {
+      fprintf(stderr, " (has no name) ");
+    }
+    else if (tp.nitems > 0)
+    {
+      int count = 0;
+      int i, ret;
+      char **list = NULL;
+
+      fprintf(stderr, " \"");
+
+      ret = XmbTextPropertyToTextList(nxagentDisplay, &tp, &list, &count);
+
+      if ((ret == Success || ret > 0) && list != NULL)
+      {
+        for (i = 0; i < count; i++)
+        {
+          fprintf(stderr, "%s", list[i]);
+        }
+
+        XFreeStringList(list);
+      }
+      else
+      {
+        fprintf(stderr, "%s", tp.value);
+      }
+
+      fprintf(stderr, "\" ");
+    }
+
+#endif
+
+    else
+    {
+      fprintf(stderr, " (has no name) ");
+    }
+  }
+
+  if (newline == TRUE)
+  {
+    fprintf(stderr, "\n");
+  }
+
+  return;
+}
+
+/*
+ * Print info about remote window.
+ */
+
+void nxagentRemoteWindowInfo(Window win, int indent, Bool newLine)
+{
+  XWindowAttributes attributes;
+  int i;
+
+  if (XGetWindowAttributes(nxagentDisplay, win, &attributes) == 0)
+  {
+    return;
+  }
+
+  for (i = 0; i < indent; i++)
+  {
+    fprintf(stderr, " ");
+  }
+
+  fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
+             "override_redirect=%s\n", attributes.x, attributes.y,
+                 attributes.width, attributes.height, (attributes.class == 0) ?
+                     "InputOutput" : "InputOnly", (attributes.map_state == 0) ?
+                         "IsUnmapped" : (attributes.map_state == 1 ?
+                             "IsUnviewable" : "IsViewable"),
+                                 (attributes.override_redirect == 0) ?
+                                     "No" : "Yes" );
+
+  if (newLine == TRUE)
+  {
+    fprintf(stderr, "\n");
+  }
+}
+
+/*
+ * Walk remote windows tree.
+ */
+
+void nxagentRemoteWindowsTree(Window window, int level)
+{
+  int i, j;
+  Window rootWin, parentWin;
+  unsigned int numChildren;
+  Window *childList;
+
+  if (!XQueryTree(nxagentDisplay, window, &rootWin, &parentWin, &childList,
+                      &numChildren))
+  {
+    fprintf(stderr, "nxagentRemoteWindowsTree - XQueryTree failed.\n");
+
+    return;
+  }
+
+  if (level == 0)
+  {
+    fprintf(stderr, "\n");
+
+    fprintf(stderr, "  Root Window ID: ");
+    nxagentRemoteWindowID(rootWin, TRUE);
+
+    fprintf(stderr, "  Parent window ID: ");
+    nxagentRemoteWindowID(parentWin, TRUE);
+  }
+
+  if (level == 0 || numChildren > 0)
+  {
+    fprintf(stderr, "     ");
+
+    for (j = 0; j < level; j++)
+    {
+      fprintf(stderr, "    ");
+    }
+
+    fprintf(stderr, "%d child%s%s\n", numChildren, (numChildren == 1) ? "" :
+               "ren", (numChildren == 1) ? ":" : ".");
+  }
+
+  for (i = (int) numChildren - 1; i >= 0; i--)
+  {
+    fprintf(stderr, "      ");
+
+    for (j = 0; j < level; j++)
+    {
+      fprintf(stderr, "     ");
+    }
+
+    nxagentRemoteWindowID(childList[i], TRUE);
+
+    nxagentRemoteWindowInfo(childList[i], (level * 5) + 6, TRUE);
+
+    nxagentRemoteWindowsTree(childList[i], level + 1);
+  }
+
+  if (childList)
+  {
+    XFree((char *) childList);
+  }
+}
+
+/*
+ * Print info about internal window.
+ */
+
+void nxagentInternalWindowInfo(WindowPtr pWin, int indent, Bool newLine)
+{
+  int i;
+  int result;
+  unsigned long ulReturnItems;
+  unsigned long ulReturnBytesLeft;
+  Atom          atomReturnType;
+  int           iReturnFormat;
+  unsigned char *pszReturnData = NULL;
+
+  fprintf(stderr, "Window ID=[0x%lx] Remote ID=[0x%lx] ", pWin -> drawable.id,
+             nxagentWindow(pWin));
+
+  result = GetWindowProperty(pWin, MakeAtom("WM_NAME", 7, False) , 0,
+                                sizeof(CARD32), False, AnyPropertyType,
+                                    &atomReturnType, &iReturnFormat,
+                                        &ulReturnItems, &ulReturnBytesLeft,
+                                            &pszReturnData);
+
+  fprintf(stderr, "Name: ");
+
+  if (result == Success && pszReturnData != NULL)
+  {
+    pszReturnData[ulReturnItems] = '\0';
+
+    fprintf(stderr, "\"%s\"\n", (char *) pszReturnData);
+  }
+  else
+  {
+    fprintf(stderr, "%s\n", "( has no name )");
+  }
+
+  for (i = 0; i < indent; i++)
+  {
+    fprintf(stderr, " ");
+  }
+
+  fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
+             "override_redirect=%s", pWin -> drawable.x, pWin -> drawable.y,
+                 pWin -> drawable.width, pWin -> drawable.height,
+                     (pWin -> drawable.class == 0) ? "InputOutput" :
+                         "InputOnly", (pWin -> mapped == 0) ?
+                             "IsUnmapped" : (pWin -> mapped == 1 ?
+                                 "IsUnviewable" : "IsViewable"),
+                                     (pWin -> overrideRedirect == 0) ?
+                                         "No" : "Yes");
+
+  if (newLine == TRUE)
+  {
+    fprintf(stderr, "\n");
+  }
+}
+
+/*
+ * Walk internal windows tree.
+ */
+
+void nxagentInternalWindowsTree(WindowPtr pWin, int indent)
+{
+  WindowPtr pChild;
+  int i;
+
+  while (pWin)
+  {
+    pChild = pWin -> firstChild;
+
+    for (i = 0; i < indent; i++)
+    {
+      fprintf(stderr, " ");
+    }
+
+    nxagentInternalWindowInfo(pWin, indent, TRUE);
+
+    fprintf(stderr, "\n");
+
+    nxagentInternalWindowsTree(pChild, indent + 4);
+
+    pWin = pWin -> nextSib;
+  }
+}
+
+#endif /* DEBUG_TREE */
+
 void nxagentSwitchResizeMode(ScreenPtr pScreen)
 {
   XSizeHints sizeHints;
@@ -290,8 +578,14 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentLaunchDialog(DIALOG_DISABLE_DESKTOP_RESIZE_MODE);
 
-    sizeHints.max_width = nxagentOption(RootWidth);
-    sizeHints.max_height = nxagentOption(RootHeight);
+    if (nxagentOption(Fullscreen) == 0)
+    {
+      sizeHints.max_width = nxagentOption(RootWidth);
+      sizeHints.max_height = nxagentOption(RootHeight);
+
+      XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                            &sizeHints);
+    }
   }
   else
   {
@@ -299,7 +593,8 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentLaunchDialog(DIALOG_ENABLE_DESKTOP_RESIZE_MODE);
 
-    nxagentRRSetScreenConfig(pScreen, nxagentOption(Width), nxagentOption(Height));
+    nxagentRRSetScreenConfig(pScreen, nxagentOption(Width),
+                                 nxagentOption(Height));
 
     if (nxagentOption(ClientOs) == ClientOsWinnt)
     {
@@ -308,10 +603,10 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
     sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
-  }
 
-  XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
-                       &sizeHints);
+    XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                          &sizeHints);
+  }
 }
 
 void nxagentShadowSwitchResizeMode(ScreenPtr pScreen)
@@ -655,6 +950,22 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           {
             break;
           }
+
+          #ifdef DEBUG_TREE
+
+          case doDebugTree:
+          {
+            fprintf(stderr, "\n ========== nxagentRemoteWindowsTree ==========\n");
+            nxagentRemoteWindowsTree(nxagentWindow(WindowTable[0]), 0);
+
+            fprintf(stderr, "\n========== nxagentInternalWindowsTree ==========\n");
+            nxagentInternalWindowsTree(WindowTable[0], 0);
+
+            break;
+          }
+
+          #endif /* DEBUG_TREE */
+
           case doCloseSession:
           {
             closeSession = TRUE;
@@ -679,6 +990,30 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
             break;
           }
+          case doViewportMoveUp:
+          {
+            nxagentMoveViewport(pScreen, 0, -nxagentOption(Height));
+
+            break;
+          }
+          case doViewportMoveDown:
+          {
+            nxagentMoveViewport(pScreen, 0, nxagentOption(Height));
+
+            break;
+          }
+          case doViewportMoveLeft:
+          {
+            nxagentMoveViewport(pScreen, -nxagentOption(Width), 0);
+
+            break;
+          }
+          case doViewportMoveRight:
+          {
+            nxagentMoveViewport(pScreen, nxagentOption(Width), 0);
+
+            break;
+          }
           case doViewportUp:
           {
             nxagentMoveViewport(pScreen, 0, -nextinc(viewportInc));
@@ -755,6 +1090,8 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow) == 1 && result == doNothing)
         {
+          X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
+
           NXShadowEvent(nxagentDisplay, X);
         }
 
@@ -763,6 +1100,27 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
       case KeyRelease:
       {
         enum HandleEventResult result;
+        int sendKey = 0;
+
+/*
+FIXME: If we don't flush the queue here, it could happen
+       that the inputInfo structure will not be up to date
+       when we perform the following check on down keys.
+*/
+        ProcessInputEvents();
+
+/*
+FIXME: Don't enqueue the KeyRelease event if the key was
+       not already pressed. This workaround avoids a fake
+       KeyPress is enqueued by the XKEYBOARD extension.
+       Another solution would be to let the events are
+       enqueued and to remove the KeyPress afterwards.
+*/
+        if (BitIsOn(inputInfo.keyboard -> key -> down,
+                       nxagentConvertKeycode(X.xkey.keycode)))
+        {
+          sendKey = 1;
+        }
 
         #ifdef TEST
         fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeyRelease event.\n");
@@ -803,7 +1161,12 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         nxagentLastEventTime = GetTimeInMillis();
 
-        if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)))
+        if (x.u.keyButtonPointer.time > nxagentLastEventTime)
+        {
+          x.u.keyButtonPointer.time = nxagentLastEventTime;
+        }
+
+        if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)) && sendKey == 1)
         {
           mieqEnqueue(&x);
 
@@ -811,6 +1174,8 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
           if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
           {
+            X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
+
             NXShadowEvent(nxagentDisplay, X);
           }
         }
@@ -828,6 +1193,23 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         nxagentInputEvent = 1;
 
+        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
+        {
+          x.u.u.type = ButtonPress;
+          x.u.u.detail = inputInfo.pointer -> button -> map[3];
+          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+          mieqEnqueue(&x);
+
+          x.u.u.type = ButtonRelease;
+          x.u.u.detail = inputInfo.pointer -> button -> map[3];
+          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+          mieqEnqueue(&x);
+
+          break;
+        }
+
         if (nxagentOption(Fullscreen))
         {
           if (nxagentMagicPixelZone(X.xbutton.x, X.xbutton.y))
@@ -874,7 +1256,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
                     X.xbutton.subwindow == None))
         {
           x.u.u.type = ButtonPress;
-          x.u.u.detail = X.xbutton.button;
+          x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]];
           x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
 
           if (nxagentOption(Rootless))
@@ -931,6 +1313,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         nxagentInputEvent = 1;
 
+        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
+        {
+          break;
+        }
+
         if (viewportCursor)
         {
           /*
@@ -947,7 +1334,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         if (minimize != True)
         {
           x.u.u.type = ButtonRelease;
-          x.u.u.detail = X.xbutton.button;
+          x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]];
           x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
 
           if (nxagentOption(Rootless))
@@ -1301,10 +1688,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           nxagentScreenTrap = 0;
         }
 
-        if (nxagentOption(Fullscreen))
+        if (nxagentOption(Fullscreen) == 1)
         {
-          if (X.xcrossing.window == nxagentFullscreenWindow &&
-                  X.xcrossing.detail != NotifyInferior)
+          if (X.xcrossing.window == nxagentDefaultWindows[0] &&
+                  X.xcrossing.detail != NotifyInferior &&
+                      X.xcrossing.mode == NotifyNormal)
           {
             nxagentGrabPointerAndKeyboard(&X);
           }
@@ -1356,14 +1744,11 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           nxagentLastEnteredWindow = NULL;
         }
 
-        if (nxagentOption(Fullscreen))
+        if (X.xcrossing.window == nxagentDefaultWindows[0] &&
+                X.xcrossing.detail != NotifyInferior &&
+                    X.xcrossing.mode == NotifyNormal)
         {
-          if (X.xcrossing.window == nxagentFullscreenWindow &&
-                  X.xcrossing.detail != NotifyInferior &&
-                      X.xcrossing.mode == NotifyNormal)
-          {
-            nxagentUngrabPointerAndKeyboard(&X);
-          }
+          nxagentUngrabPointerAndKeyboard(&X);
         }
 
         if (X.xcrossing.detail != NotifyInferior)
@@ -1617,7 +2002,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         }
 
         if (nxagentUseNXTrans == 1 && nxagentOption(Rootless) == 0 &&
-                nxagentOption(Nested) == 0 && X.xmap.window != nxagentIconWindow)
+                nxagentOption(Nested) == 0)
         {
           nxagentVisibility = VisibilityFullyObscured;
         }
@@ -1658,12 +2043,6 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         if (nxagentOption(Fullscreen) == 1)
         {
-          if (X.xmap.window == nxagentIconWindow)
-          {
-            pScreen = nxagentScreen(X.xmap.window);
-            nxagentMaximizeToFullScreen(pScreen);
-          }
-
           nxagentVisibility = VisibilityUnobscured;
           nxagentVisibilityStop = False;
           nxagentVisibilityTimeout = GetTimeInMillis() + 2000;
@@ -1673,10 +2052,17 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
       }
       case MappingNotify:
       {
+        XMappingEvent *mappingEvent = (XMappingEvent *) &X;
+
         #ifdef DEBUG
         fprintf(stderr, "nxagentDispatchEvents: WARNING! Going to handle new MappingNotify event.\n");
         #endif
 
+        if (mappingEvent -> request == MappingPointer)
+        {
+            nxagentInitPointerMap();
+        }
+
         break;
       }
       default:
@@ -1750,14 +2136,8 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
     if (nxagentWMIsRunning)
     {
-      if (nxagentOption(Fullscreen))
-      {
-        nxagentMinimizeFromFullScreen(pScreen);
-      }
-      else
-      {
-        XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0], DefaultScreen(nxagentDisplay));
-      }
+      XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
+                         DefaultScreen(nxagentDisplay));
     }
   }
 
@@ -1916,8 +2296,16 @@ int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
     return 1;
   }
 
-  nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
+  if (X -> xkey.keycode == 66)
+  {
+    nxagentXkbState.Caps = (~nxagentXkbState.Caps & 1);
+  }
+  else if (X -> xkey.keycode == 77)
+  {
+    nxagentXkbState.Num = (~nxagentXkbState.Num & 1);
+  }
 
+  nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
   
   x.u.u.type = KeyPress;
   x.u.u.detail = nxagentConvertKeycode(X -> xkey.keycode);
@@ -2227,7 +2615,6 @@ int nxagentHandleGraphicsExposeEvent(XEvent *X)
 
 int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
 {
-  ScreenPtr pScreen;
   WindowPtr pWin;
   xEvent x;
 
@@ -2343,19 +2730,8 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         fprintf(stderr, "Events: WM_DELETE_WINDOW arrived Atom = %ld.\n", wmAtom);
         #endif
 
-        if (X -> xclient.window == nxagentIconWindow)
-        {
-          pScreen = nxagentScreen(X -> xmap.window);
-
-          XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
-
-          XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                             DefaultScreen(nxagentDisplay));
-
-        }
-
-        if (X -> xclient.window == (nxagentOption(Fullscreen) ?
-              nxagentIconWindow : nxagentDefaultWindows[0]))
+        if (X -> xclient.window == nxagentDefaultWindows[0] ||
+                nxagentWMIsRunning == 0)
         {
           *result = doCloseSession;
         }
@@ -2952,85 +3328,110 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
     if (X -> xconfigure.window == nxagentDefaultWindows[pScreen -> myNum])
     {
-      if (nxagentOption(Fullscreen) == 0)
+      if (nxagentOption(DesktopResize) == 1)
       {
-        if (nxagentOption(DesktopResize) == 1)
+        if (nxagentOption(Width) != X -> xconfigure.width ||
+              nxagentOption(Height) != X -> xconfigure.height)
         {
-          if (nxagentOption(Width) != X -> xconfigure.width ||
-                nxagentOption(Height) != X -> xconfigure.height)
-          {
-            Bool newEvents = False;
+          Bool newEvents = False;
 
-            doRandR = True;
+          doRandR = True;
 
-            NXFlushDisplay(nxagentDisplay, NXFlushLink);
+          NXFlushDisplay(nxagentDisplay, NXFlushLink);
 
-            do
-            {
-              newEvents = False;
+          do
+          {
+            newEvents = False;
 
-              timeout.tv_sec  = 0;
-              timeout.tv_usec = 500 * 1000;
+            timeout.tv_sec  = 0;
+            timeout.tv_usec = 500 * 1000;
 
-              nxagentWaitEvents(nxagentDisplay, &timeout);
+            nxagentWaitEvents(nxagentDisplay, &timeout);
 
-              /*
-               * This should also flush
-               * the NX link for us.
-               */
+            /*
+             * This should also flush
+             * the NX link for us.
+             */
 
-              XSync(nxagentDisplay, 0);
+            XSync(nxagentDisplay, 0);
 
-              while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
-                                              ConfigureNotify, X))
-              {
-                newEvents = True;
-              }
+            while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+                                            ConfigureNotify, X))
+            {
+              newEvents = True;
+            }
 
-            } while (newEvents);
-          }
+          } while (newEvents);
         }
+      }
 
-        if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
-        {
-          nxagentChangeOption(X, X -> xconfigure.x);
-          nxagentChangeOption(Y, X -> xconfigure.y);
-        }
+      if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
+      {
+        nxagentChangeOption(X, X -> xconfigure.x);
+        nxagentChangeOption(Y, X -> xconfigure.y);
+      }
 
-        if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
-                (nxagentOption(Width) != X -> xconfigure.width ||
-                    nxagentOption(Height) != X -> xconfigure.height))
-        {
-          nxagentShadowResize = 1;
-        }
+      if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
+              (nxagentOption(Width) != X -> xconfigure.width ||
+                  nxagentOption(Height) != X -> xconfigure.height))
+      {
+        nxagentShadowResize = 1;
+      }
 
-        nxagentChangeOption(Width, X -> xconfigure.width);
-        nxagentChangeOption(Height, X -> xconfigure.height);
+      nxagentChangeOption(Width, X -> xconfigure.width);
+      nxagentChangeOption(Height, X -> xconfigure.height);
 
-        nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
-                                (int) nxagentOption(RootWidth));
-        nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
-                                (int) nxagentOption(RootHeight));
+      nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
+                              (int) nxagentOption(RootWidth));
+      nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
+                              (int) nxagentOption(RootHeight));
 
-        nxagentMoveViewport(pScreen, 0, 0);
+      nxagentMoveViewport(pScreen, 0, 0);
 
-        if (nxagentOption(Shadow) == 1 ||
-                (nxagentOption(Width) == nxagentOption(RootWidth) &&
-                    nxagentOption(Height) == nxagentOption(RootHeight)))
-        {
-          doRandR = 0;
-        }
+      if (nxagentOption(Shadow) == 1 ||
+              (nxagentOption(Width) == nxagentOption(RootWidth) &&
+                  nxagentOption(Height) == nxagentOption(RootHeight)))
+      {
+        doRandR = 0;
+      }
 
-        if (doRandR)
-        {
-          #ifdef TEST
-          fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
-                      nxagentOption(Width), nxagentOption(Height));
-          #endif
+      nxagentChangeOption(Width, X -> xconfigure.width);
+      nxagentChangeOption(Height, X -> xconfigure.height);
 
-          nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
-                                     nxagentOption(Width), nxagentOption(Height));
-        }
+      XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+                            X -> xconfigure.width, X -> xconfigure.height);
+
+      if (nxagentOption(Fullscreen) == 0)
+      {
+        nxagentMoveViewport(pScreen, 0, 0);
+      }
+      else
+      {
+        nxagentChangeOption(RootX, (nxagentOption(Width) -
+                                nxagentOption(RootWidth)) / 2);
+        nxagentChangeOption(RootY, (nxagentOption(Height) -
+                                nxagentOption(RootHeight)) / 2);
+        nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
+                                nxagentOption(RootWidth));
+        nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
+                                nxagentOption(RootHeight));
+
+        nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
+                                       nxagentOption(RootHeight));
+
+        XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                        nxagentOption(RootX), nxagentOption(RootY));
+      }
+
+      if (doRandR)
+      {
+        #ifdef TEST
+        fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
+                    nxagentOption(Width), nxagentOption(Height));
+        #endif
+
+        nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
+                                   nxagentOption(Width), nxagentOption(Height));
       }
 
       return 1;
@@ -3042,8 +3443,6 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
 int nxagentHandleReparentNotify(XEvent* X)
 {
-  ScreenPtr pScreen = nxagentScreen(X -> xreparent.window);
-
   #ifdef TEST
   fprintf(stderr, "nxagentHandleReparentNotify: Going to handle a new reparent event.\n");
   #endif
@@ -3096,6 +3495,8 @@ int nxagentHandleReparentNotify(XEvent* X)
           #ifdef WARNING
           fprintf(stderr, "nxagentHandleReparentNotify: WARNING! Failed QueryTree request.\n");
           #endif
+
+          break;
         }
 
         if (result && children_return)
@@ -3148,6 +3549,95 @@ int nxagentHandleReparentNotify(XEvent* X)
 
     return 1;
   }
+  else if (nxagentWMIsRunning == 1 && nxagentOption(Fullscreen) == 0 &&
+               nxagentOption(WMBorderWidth) == -1)
+  {
+    XlibWindow w;
+    XlibWindow rootReturn = 0;
+    XlibWindow parentReturn = 0;
+    XlibWindow junk;
+    XlibWindow *childrenReturn = NULL;
+    unsigned int nchildrenReturn = 0;
+    Status result;
+    XWindowAttributes attributes;
+    int x, y;
+    int xParent, yParent;
+
+    /*
+     * Calculate the absolute upper-left X e Y 
+     */
+
+    if ((XGetWindowAttributes(nxagentDisplay, X -> xreparent.window,
+                                  &attributes) == 0))
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
+                  "XGetWindowAttributes failed.\n");
+      #endif
+
+      return 1;
+    }
+
+    x = attributes.x;
+    y = attributes.y;
+
+    XTranslateCoordinates(nxagentDisplay, X -> xreparent.window,
+                              attributes.root, -attributes.border_width,
+                                  -attributes.border_width, &x, &y, &junk);
+
+   /*
+    * Calculate the parent X and parent Y.
+    */
+
+    w = X -> xreparent.parent;
+
+    if (w != DefaultRootWindow(nxagentDisplay))
+    {
+      do
+      {
+        result = XQueryTree(nxagentDisplay, w, &rootReturn, &parentReturn,
+                                &childrenReturn, &nchildrenReturn);
+    
+        if (parentReturn == rootReturn || parentReturn == 0 || result == 0)
+        {
+          break;
+        }
+
+        if (result == 1 && childrenReturn != NULL)
+        {
+          XFree(childrenReturn);
+        }
+    
+        w = parentReturn;
+      }
+      while (True);
+
+      /*
+       * WM reparented. Find edge of the frame.
+       */
+
+      if (XGetWindowAttributes(nxagentDisplay, w, &attributes) == 0)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
+                    "XGetWindowAttributes failed for parent window.\n");
+        #endif
+
+        return 1;
+      }
+
+      xParent = attributes.x;
+      yParent = attributes.y;
+
+      /*
+       * Difference between Absolute X and Parent X gives thickness of side frame.
+       * Difference between Absolute Y and Parent Y gives thickness of title bar. 
+       */
+
+      nxagentChangeOption(WMBorderWidth, (x - xParent));
+      nxagentChangeOption(WMTitleHeight, (y - yParent));
+    }
+  }
 
   return 1;
 }
@@ -3308,6 +3798,13 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
 
   int resource;
 
+  int result;
+
+  if (nxagentPointerAndKeyboardGrabbed == 1)
+  {
+    return;
+  }
+
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Grabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
@@ -3326,8 +3823,22 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n");
   #endif
 
-  XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
-                    True, GrabModeAsync, GrabModeAsync, now);
+  result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
+                             True, GrabModeAsync, GrabModeAsync, now);
+
+  if (result != GrabSuccess)
+  {
+    return;
+  }
+
+  /*
+   * The smart scheduler could be stopped while
+   * waiting for the reply. In this case we need
+   * to yield explicitly to avoid to be stuck in
+   * the dispatch loop forever.
+   */
+
+  isItTimeToYield = 1;
 
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the pointer in context [B2].\n");
@@ -3356,12 +3867,19 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
     XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
                        RevertToParent, now);
   }
+
+  nxagentPointerAndKeyboardGrabbed = 1;
 }
 
 void nxagentUngrabPointerAndKeyboard(XEvent *X)
 {
   unsigned long now;
 
+  if (nxagentPointerAndKeyboardGrabbed == 0)
+  {
+    return;
+  }
+
   #ifdef TEST
   fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Ungrabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
@@ -3387,6 +3905,8 @@ void nxagentUngrabPointerAndKeyboard(XEvent *X)
   #endif
 
   XUngrabPointer(nxagentDisplay, now);
+
+  nxagentPointerAndKeyboardGrabbed = 0;
 }
 
 void nxagentDeactivatePointerGrab()
@@ -4022,4 +4542,180 @@ void nxagentGuessDumpInputInfo(ClientPtr client, Atom property, char *data)
   }
 }
 
+void nxagentDeactivateInputDevicesGrabs()
+{
+  fprintf(stderr, "Info: Deactivating input devices grabs.\n");
+
+  if (inputInfo.pointer -> grab)
+  {
+    (*inputInfo.pointer -> DeactivateGrab)(inputInfo.pointer);
+  }
+
+  if (inputInfo.keyboard -> grab)
+  {
+    (*inputInfo.keyboard -> DeactivateGrab)(inputInfo.keyboard);
+  }
+}
+
+static const char *nxagentGrabStateToString(int state)
+{
+  switch (state)
+  {
+    case 0:
+      return "NOT_GRABBED";
+    case 1:
+      return "THAWED";
+    case 2:
+      return "THAWED_BOTH";
+    case 3:
+      return "FREEZE_NEXT_EVENT";
+    case 4:
+      return "FREEZE_BOTH_NEXT_EVENT";
+    case 5:
+      return "FROZEN_NO_EVENT";
+    case 6:
+      return "FROZEN_WITH_EVENT";
+    case 7:
+      return "THAW_OTHERS";
+    default:
+      return "unknown state";
+  }
+}
+
+void nxagentDumpInputDevicesState(void)
+{
+  int i, k;
+  int mask = 1;
+  CARD8 val;
+  DeviceIntPtr dev;
+  GrabPtr grab;
+  WindowPtr pWin = NULL;
+
+  fprintf(stderr, "\n*** Dump input devices state: BEGIN ***"
+              "\nKeys down:");
+
+  dev = inputInfo.keyboard;
+
+  for (i = 0; i < DOWN_LENGTH; i++)
+  {
+    val = dev -> key -> down[i];
+
+    if (val != 0)
+    {
+      for (k = 0; k < 8; k++)
+      {
+        if (val & (mask << k))
+        {
+          fprintf(stderr, "\n\t[%d] [%s]", i * 8 + k,
+                      XKeysymToString(XKeycodeToKeysym(nxagentDisplay, i * 8 + k, 0)));
+        }
+      }
+    }
+  }
+
+  fprintf(stderr, "\nKeyboard device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
+              "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
+                  "\n\tfrom passive grab [%s]\n\tactivating key [%d]", dev,
+                      dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes": "No",
+                          nxagentGrabStateToString(dev -> sync.state),
+                              dev -> sync.other, dev -> sync.evcount,
+                                  dev -> fromPassiveGrab ? "Yes" : "No",
+                                      dev -> activatingKey);
+
+  grab = dev -> grab;
+
+  if (grab)
+  {
+    fprintf(stderr, "\nKeyboard grab state: \n\twindow pointer [%p]"
+                "\n\towner events flag [%s]\n\tgrab mode [%s]",
+                    grab -> window, grab -> ownerEvents ? "True" : "False",
+                        grab -> keyboardMode ? "asynchronous" : "synchronous");
+
+   /*
+    * Passive grabs.
+    */
+
+    pWin = grab -> window;
+    grab = wPassiveGrabs(pWin);
+
+    while (grab)
+    {
+      fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
+                  "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
+                      "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
+                          grab -> device, grab -> ownerEvents ? "True" : "False",
+                              grab -> pointerMode ? "asynchronous" : "synchronous",
+                                  grab -> keyboardMode ? "asynchronous" : "synchronous",
+                                      grab -> type, grab -> modifiersDetail.exact,
+                                          grab -> detail.exact, grab -> eventMask);
+
+      grab = grab -> next;
+    }
+  }
+
+  fprintf(stderr, "\nButtons down:");
+
+  dev = inputInfo.pointer;
+
+  for (i = 0; i < DOWN_LENGTH; i++)
+  {
+    val = dev -> button -> down[i];
+
+    if (val != 0)
+    {
+      for (k = 0; k < 8; k++)
+      {
+        if (val & (mask << k))
+        {
+          fprintf(stderr, "\n\t[%d]", i * 8 + k);
+        }
+      }
+    }
+  }
+
+  fprintf(stderr, "\nPointer device state: \n\tdevice [%p]\n\tlast grab time [%lu]"
+              "\n\tfrozen [%s]\n\tstate [%s]\n\tother [%p]\n\tevent count [%d]"
+                  "\n\tfrom passive grab [%s]\n\tactivating button [%d]", dev,
+                      dev -> grabTime.milliseconds, dev -> sync.frozen ? "Yes" : "No",
+                          nxagentGrabStateToString(dev -> sync.state),
+                              dev -> sync.other, dev -> sync.evcount,
+                                  dev -> fromPassiveGrab ? "Yes" : "No",
+                                      dev -> activatingKey);
+
+  grab = dev -> grab;
+
+  if (grab)
+  {
+    fprintf(stderr, "\nPointer grab state: \n\twindow pointer [%p]"
+                "\n\towner events flag [%s]\n\tgrab mode [%s]",
+                    grab -> window, grab -> ownerEvents ? "True" : "False",
+                        grab -> pointerMode ? "asynchronous" : "synchronous");
+
+    if (grab -> window != pWin)
+    {
+      /*
+       * Passive grabs.
+       */
+
+      grab = wPassiveGrabs(grab -> window);
+
+      while (grab)
+      {
+        fprintf(stderr, "\nPassive grab state: \n\tdevice [%p]\n\towner events flag [%s]"
+                    "\n\tpointer grab mode [%s]\n\tkeyboard grab mode [%s]\n\tevent type [%d]"
+                        "\n\tmodifiers [%x]\n\tbutton/key [%u]\n\tevent mask [%lx]",
+                            grab -> device, grab -> ownerEvents ? "True" : "False",
+                                grab -> pointerMode ? "asynchronous" : "synchronous",
+                                    grab -> keyboardMode ? "asynchronous" : "synchronous",
+                                        grab -> type, grab -> modifiersDetail.exact,
+                                            grab -> detail.exact, grab -> eventMask);
+
+        grab = grab -> next;
+      }
+    }
+  }
+
+  fprintf(stderr, "\n*** Dump input devices state: FINISH ***\n");
+}
+
 #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index ab0d25764..109475c16 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -29,9 +29,14 @@ enum HandleEventResult
 {
   doNothing = 0,
   doMinimize,
+  doDebugTree,
   doCloseSession,
   doStartKbd,
   doSwitchFullscreen,
+  doViewportMoveUp,
+  doViewportMoveLeft,
+  doViewportMoveRight,
+  doViewportMoveDown,
   doViewportLeft,
   doViewportUp,
   doViewportRight,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
index f2954a3e9..e76cbb4ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
index f76229867..620645d00 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index 87f9f0201..13b819322 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -827,7 +827,10 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
 
       for (j = 0; j < numSearchFields; j++)
       {
-        free (searchFields[j]);
+        if (searchFields[j] != NULL)
+        {
+          free(searchFields[j]);
+        }
       }
     }
   }
@@ -846,7 +849,10 @@ static XFontStruct *nxagentLoadBestQueryFont(Display* dpy, char *fontName, FontP
 
   for (j = 0; j < numFontFields; j++)
   {
-    free (fontNameFields[j]);
+    if (fontNameFields[j] != NULL)
+    {
+      free(fontNameFields[j]);
+    }
   }
 
   return fontStruct;
@@ -1765,6 +1771,10 @@ int nxagentSplitString(char *string, char *fields[], int nfields, char *sep)
       strncpy(fields[i], current, fieldlen);
       *(fields[i] + fieldlen) = 0;
     }
+    else
+    {
+      fields[i] = NULL;
+    }
 
     current = next + seplen;
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.h b/nx-X11/programs/Xserver/hw/nxagent/Font.h
index 3ae086b44..75ae3f6f5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GC.c b/nx-X11/programs/Xserver/hw/nxagent/GC.c
index 4ca069790..c53e3b9f7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GC.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GC.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index 83aa04f11..85730797e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -594,6 +594,8 @@ RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
   unsigned int format;
   unsigned long planeMask = 0xffffffff;
 
+  int oldDstxyValue;
+
   RegionPtr pDstRegion;
 
   int skip = 0;
@@ -605,6 +607,91 @@ RegionPtr nxagentCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
                           (void *) pDstDrawable, srcx, srcy, dstx, dsty, width, height);
   #endif
 
+ /*
+  * Here, before using fbDoCopy() called by fbCopyArea(),
+  * it should be provided that the cast in fbDoCopy() from
+  * int to short int would not cut off significative bits.
+  */
+
+  if (dstx + pDstDrawable->x + width > 32767)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: x2 exceeding short int.\n");
+    #endif
+
+    width = 32767 - dstx - pDstDrawable->x;
+
+    if (width <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on x2 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+  if (dstx + pDstDrawable->x < -32768)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: x1 exceeding short int.\n");
+    #endif
+
+    width += pDstDrawable->x + dstx + 32768;
+    srcx  -= pDstDrawable->x + dstx + 32768;
+    dstx = -32768 - pDstDrawable->x;
+
+    if (width <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on x1 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+    oldDstxyValue = dsty;
+
+  if (dsty + pDstDrawable->y + height > 32767)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: y2 exceeding short int.\n");
+    #endif
+
+    height = 32767 - dsty - pDstDrawable->y;
+
+    if (height <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on y2 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+  if (dsty + pDstDrawable->y < -32768)
+  {
+    #ifdef WARNING
+    fprintf(stderr, "nxagentCopyArea: y1 exceeding short int.\n");
+    #endif
+
+    height += 32768 + pDstDrawable->y + dsty;
+    srcy   -= 32768 + pDstDrawable->y + dsty;
+    dsty = -32768 - pDstDrawable->y;
+
+    if (height <= 0)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentCopyArea: Returning null on y1 check.\n");
+      #endif
+
+      return NullRegion;
+    }
+  }
+
+
   if (nxagentGCTrap == 1 || nxagentShmTrap == 1)
   {
     if (pSrcDrawable -> type == DRAWABLE_PIXMAP &&
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
index 14d30e392..7ae6d9923 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCs.h b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
index 207d563ed..bec290088 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCs.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index 3abc3575f..be407f160 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -105,6 +105,13 @@
 
 #define MINIMUM_DISPLAY_BUFFER   512
 
+#ifdef NX_DEBUG_INPUT
+extern int nxagentDebugInputDevices;
+extern unsigned long nxagentLastInputDevicesDumpTime;
+
+extern void nxagentDumpInputDevicesState(void);
+#endif
+
 /*
  * Used in the handling of the X desktop
  * manager protocol.
@@ -186,6 +193,18 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
 
   now = GetTimeInMillis();
 
+  #ifdef NX_DEBUG_INPUT
+
+  if (nxagentDebugInputDevices == 1 &&
+        now - nxagentLastInputDevicesDumpTime > 5000)
+  {
+    nxagentLastInputDevicesDumpTime = now;
+
+    nxagentDumpInputDevicesState();
+  }
+
+  #endif
+
   if (nxagentNeedConnectionChange() == 1)
   {
     #ifdef TEST
@@ -508,7 +527,8 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
                 synchronize, nxagentReady);
     #endif
 
-    if (nxagentQueuedEvents(nxagentDisplay) > 0)
+    if (NXDisplayError(nxagentDisplay) == 0 &&
+            nxagentQueuedEvents(nxagentDisplay) > 0)
     {
       #ifdef WARNING
       fprintf(stderr, "nxagentBlockHandler: WARNING! Forcing a null timeout with events queued.\n");
@@ -540,6 +560,8 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
 
   #endif
 
+  nxagentPrintGeometry();
+
   #ifdef BLOCKS
   fprintf(stderr, "[End block]\n");
   #endif
@@ -820,6 +842,8 @@ FIXME: Must queue multiple writes and handle
 
   #endif
 
+  nxagentPrintGeometry();
+
   #ifdef BLOCKS
   fprintf(stderr, "[End block]\n");
   #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
index fc72c7060..fe8aeef36 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.c b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
index 087d66017..a9ac77c09 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.h b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
index 6dc2b8ed2..9896aeead 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Icons.h b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
index cb2e08521..4d0e216cd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Icons.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com.          */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index 4e08f6bf1..e8405ed3a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.h b/nx-X11/programs/Xserver/hw/nxagent/Image.h
index fb77f3c80..7805b0312 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
index 633e17a22..51173e410 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -206,7 +206,8 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \
           -DNXAGENT_SPLASH \
           -DNXAGENT_ARTSD \
           -UNX_DEBUG_INPUT \
-          -UPANORAMIX
+          -UPANORAMIX \
+          -UDEBUG_TREE
 
 all:: $(OBJS)
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 81ed0c43e..64b6583bf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -74,7 +74,7 @@ is" without express or implied warranty.
 #undef  DEBUG
 #undef  DUMP
 
-#define NXAGENT_VERSION  "3.3.0"
+#define NXAGENT_VERSION  "3.4.0"
 
 /*
  * ProcVector array defined in tables.c.
@@ -193,7 +193,7 @@ void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
   if (serverGeneration <= 1)
   {
     fprintf(stderr, "\nNXAGENT - Version " NXAGENT_VERSION "\n\n");
-    fprintf(stderr, "Copyright (C) 2001, 2007 NoMachine.\n");
+    fprintf(stderr, "Copyright (C) 2001, 2010 NoMachine.\n");
     fprintf(stderr, "See http://www.nomachine.com/ for more information.\n\n");
 
     fprintf(stderr, "Info: Agent running with pid '%d'.\n", getpid());
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
index 63e27bada..576c1a74d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 73b4c706a..b0aeabeea 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -1791,7 +1791,6 @@ void nxagentResetKeycodeConversion(void)
 {
   int result;
   XkbAgentInfoRec info;
-  XkbDescPtr xkb;
 
   result = XkbQueryExtension(nxagentDisplay, &info.Opcode, &info.EventBase,
                                  &info.ErrorBase, &info.MajorVersion,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index 50dd2be78..1a953358a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index ea06913f8..de1da8654 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -31,6 +31,12 @@
 extern Bool nxagentWMIsRunning;
 extern Bool nxagentIpaq;
 
+#ifdef NX_DEBUG_INPUT
+int nxagentDebugInputDevices = 0;
+unsigned long nxagentLastInputDevicesDumpTime = 0;
+extern void nxagentDeactivateInputDevicesGrabs();
+#endif
+
 /*
  * Set here the required log level.
  */
@@ -86,6 +92,18 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
   {
     switch (sym)
     {
+      #ifdef DEBUG_TREE
+
+      case XK_q:
+      case XK_Q:
+      {
+        *result = doDebugTree;
+
+        break;
+      }
+
+      #endif /* DEBUG_TREE */
+
       case XK_t:
       case XK_T:
       {
@@ -209,6 +227,105 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       }
 
       #endif
+
+      #ifdef NX_DEBUG_INPUT
+
+      case XK_X:
+      case XK_x:
+      {
+        /*
+         * Used to test the input devices state.
+         */
+
+        if (X -> type == KeyPress)
+        {
+          if (nxagentDebugInputDevices == 0)
+          {
+            fprintf(stderr, "Info: Turning input devices debug ON.\n");
+    
+            nxagentDebugInputDevices = 1;
+          }
+          else
+          {
+            fprintf(stderr, "Info: Turning input devices debug OFF.\n");
+    
+            nxagentDebugInputDevices = 0;
+    
+            nxagentLastInputDevicesDumpTime = 0;
+          }
+        }
+
+        return 1;
+      }
+
+      case XK_Y:
+      case XK_y:
+      {
+        /*
+         * Used to deactivate input devices grab.
+         */
+
+        if (X -> type == KeyPress)
+        {
+          nxagentDeactivateInputDevicesGrabs();
+        }
+
+        return 1;
+      }
+
+      #endif
+    }
+  }
+  else if ((X -> state & nxagentAltMetaMask) &&
+               ((X -> state & (ControlMask | ShiftMask)) == (ControlMask |
+                   ShiftMask)))
+  {
+    switch (sym)
+    {
+      case XK_Left:
+      case XK_KP_Left:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveLeft;
+        }
+
+        break;
+      }
+      case XK_Up:
+      case XK_KP_Up:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveUp;
+        }
+
+        break;
+      }
+      case XK_Right:
+      case XK_KP_Right:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveRight;
+        }
+
+        break;
+      }
+      case XK_Down:
+      case XK_KP_Down:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveDown;
+        }
+
+        break;
+      }
     }
   }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index 49a35db1d..e9ca59ff2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/LICENSE b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
index f3e15ee70..141ca13ea 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/LICENSE
+++ b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
@@ -1,4 +1,4 @@
-Copyright (C) 2001, 2007 NoMachine - http://www.nomachine.com/.
+Copyright (c) 2001, 2010 NoMachine - http://www.nomachine.com/.
 
 NXAGENT and NX extensions to X are copyright of NoMachine.
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
index f6aab84e4..377dd7e25 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Literals.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.c b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
index 38435d9a8..bde85f090 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.h b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
index 8ee380ae1..2125eca3e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index 90da743a2..5106ffa8c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
index 90da743a2..5106ffa8c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
index 83103ffd6..0d8584218 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
index 83103ffd6..0d8584218 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
index dd607e0ca..cd8ced7a6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
index dd607e0ca..cd8ced7a6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
index 295b885c2..852ad1503 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
index 295b885c2..852ad1503 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
index dfd82b76b..55248195f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
index dfd82b76b..55248195f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
index 599e4c616..614d2db39 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
index 599e4c616..614d2db39 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
index 970d0bb4d..08ffb35b0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
index 970d0bb4d..08ffb35b0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
index 2521ae5c7..806cf2900 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
index 2521ae5c7..806cf2900 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
index 64ba970c9..a9c501b34 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
index 64ba970c9..a9c501b34 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
index a1790c3f0..26a95fe9f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
index a1790c3f0..26a95fe9f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
index f5cf91607..14b6136d4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
index f5cf91607..14b6136d4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
index 6f53dcdad..b7039e1e0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
index 6f53dcdad..b7039e1e0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
index 20aca4619..0940a3602 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -40,7 +40,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
index 20aca4619..0940a3602 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -40,7 +40,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
index 16328f9ab..0954cf8ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
index 16328f9ab..0954cf8ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -15,7 +15,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
index 91dafb6c6..8d05175ff 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
index 3fb504ea9..4e800e96d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
index 33b05b1f0..ae3a03d86 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index 64dbe3b42..1f04b0daf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -38,6 +38,11 @@ AgentOptionsRec nxagentOptionsBackup;
 
 AgentOptionsPtr nxagentOptionsPtr = &nxagentOptions;
 
+/*
+ * If this is set, print the geometry in the block handler.
+ */
+
+unsigned int nxagentPrintGeometryFlags = 0;
 /*
  * This must be called at startup to initialize
  * the options repository to the default values.
@@ -58,6 +63,9 @@ void nxagentInitOptions()
   nxagentOptions.Height      = 0;
   nxagentOptions.BorderWidth = 0;
 
+  nxagentOptions.WMBorderWidth = -1;
+  nxagentOptions.WMTitleHeight = -1;
+
   nxagentOptions.SavedX      = 0;
   nxagentOptions.SavedY      = 0;
   nxagentOptions.SavedWidth  = 0;
@@ -163,6 +171,9 @@ void nxagentResetOptions()
 
   nxagentOptions.TileWidth  = UNDEFINED;
   nxagentOptions.TileHeight = UNDEFINED;
+
+  nxagentOptions.WMBorderWidth = -1;
+  nxagentOptions.WMTitleHeight = -1;
 }
 
 void nxagentSaveOptions()
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index aa78489b1..1bc7eaa4c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -29,6 +29,8 @@
 #define UNDEFINED -1
 #define COPY_UNLIMITED -1
 
+extern unsigned int nxagentPrintGeometryFlags;
+
 typedef enum _BackingStoreMode
 {
   BackingStoreUndefined = -1,
@@ -124,6 +126,9 @@ typedef struct _AgentOptions
    * screen.
    */
 
+  int WMBorderWidth;
+  int WMTitleHeight;
+
   int SavedX;
   int SavedY;
   int SavedWidth;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
index 03970a14f..10c705dfc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
index f9f88233e..ea7c375ee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -108,6 +108,12 @@ FIXME: The condition checking for the render
        avoid problems with the render composi-
        te on XFree86 remote server.
 */
+/*
+FIXME: Changed macro: NXAGENT_SHOULD_DEFER_COMPOSITE
+       to handle situation, when pSrc -> pDrawable
+       is NULL. This case happens with gradients
+       and solid fill.
+
 #define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)                 \
     ((nxagentRenderVersionMajor == 0 &&                                   \
      nxagentRenderVersionMinor == 8 &&                                \
@@ -118,6 +124,18 @@ FIXME: The condition checking for the render
           nxagentOption(DeferLevel) == 1) ||               \
              (nxagentOption(DeferLevel) >= 2 &&           \
               nxagentOption(LinkType) < LINK_TYPE_ADSL))
+*/
+#define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)                                                \
+    ((nxagentRenderVersionMajor == 0 &&                                                                  \
+      nxagentRenderVersionMinor == 8 &&                                                                  \
+      (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP) ||                                                 \
+         (nxagentOption(DeferLevel) >= 2 &&                                                              \
+          nxagentOption(LinkType) < LINK_TYPE_ADSL) ||                                                   \
+             (nxagentOption(DeferLevel) == 1 &&                                                          \
+              (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP &&                                          \
+              (((pSrc) -> pDrawable && nxagentDrawableStatus((pSrc) -> pDrawable) == NotSynchronized) || \
+              ((pMask) && nxagentDrawableStatus((pMask) -> pDrawable) == NotSynchronized))))
+
 
 #define NXAGENT_SHOULD_DEFER_PUTIMAGE(pDrawable) \
     (nxagentSplitTrap == 0 &&                    \
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
index 4aea92e2d..1718c7363 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
index 5cf340d36..234650dd4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
index f53dfbe52..9c1bfaace 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -57,6 +57,13 @@ is" without express or implied warranty.
 #undef  TEST
 #undef  DEBUG
 
+/*
+ * The nxagentReversePointerMap array is used to
+ * memorize remote display pointer map.
+ */
+
+unsigned char nxagentReversePointerMap[MAXBUTTONS];
+
 void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl)
 {
   /*
@@ -125,6 +132,8 @@ int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
         return Success;
       }
 
+      nxagentInitPointerMap();
+
       nxagentEnablePointerEvents();
 
       break;
@@ -155,3 +164,28 @@ int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
 
   return Success;
 }
+
+void nxagentInitPointerMap(void)
+{
+  int numButtons;
+
+  int i;
+
+  unsigned char pointerMap[MAXBUTTONS];
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentInitPointerMap: Going to retrieve the "
+              "pointer map from remote display.\n");
+  #endif
+
+  numButtons = XGetPointerMapping(nxagentDisplay, pointerMap, MAXBUTTONS);
+
+  /*
+   * Computing revers pointer map.
+   */
+
+  for (i = 1; i <= numButtons; i++)
+  {
+    nxagentReversePointerMap[pointerMap[i - 1] - 1] = i;
+  }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
index 2adee6cb3..b0bb3f99c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -38,8 +38,17 @@ is" without express or implied warranty.
   (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
        EnterWindowMask | LeaveWindowMask)
 
+/*
+ * The nxagentReversePointerMap array is used to
+ * memorize remote display pointer map.
+ */
+
+extern unsigned char nxagentReversePointerMap[MAXBUTTONS];
+
 void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl);
 
 int nxagentPointerProc(DeviceIntPtr pDev, int onoff);
 
+void nxagentInitPointerMap(void);
+
 #endif /* __Pointer_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index 69b73a942..e63b481b2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -81,6 +81,8 @@ extern Bool nxagentUninstallFontServerPath(void);
 
 extern void nxagentRemoveXConnection(void);
 
+extern void nxagentInitPointerMap(void);
+
 static char *nxagentGetReconnectError(void);
 
 void nxagentInitializeRecLossyLevel(void);
@@ -257,7 +259,11 @@ TODO: This should be reset only when
 
       if ((dispatchException & DE_TERMINATE) == 0)
       {
+        #ifdef NX_DEBUG_INPUT
+        fprintf(stderr, "Session: Session suspended at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+        #else
         fprintf(stderr, "Session: Session suspended at '%s'.\n", GetTimeAsString());
+        #endif
       }
 
       nxagentResetDisplayHandlers();
@@ -580,6 +586,8 @@ Bool nxagentReconnectSession(void)
     nxagentOldKeyboard = NULL;
   }
 
+  nxagentInitPointerMap();
+
   nxagentDeactivatePointerGrab();
 
   nxagentWakeupByReconnect();
@@ -609,7 +617,11 @@ Bool nxagentReconnectSession(void)
     goto nxagentReconnectError;
   }
 
+  #ifdef NX_DEBUG_INPUT
+  fprintf(stderr, "Session: Session resumed at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+  #else
   fprintf(stderr, "Session: Session resumed at '%s'.\n", GetTimeAsString());
+  #endif
 
   nxagentRemoveSplashWindow(NULL);
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
index 0a2a8a6a7..12d0742df 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index f2d7b15f9..4f0f76474 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -147,8 +147,6 @@ void nxagentCursorPostSaveRenderInfo(CursorPtr pCursor, ScreenPtr pScreen,
 
 int nxagentCreatePicture(PicturePtr pPicture, Mask mask);
 
-void nxagentDestroyPicture(PicturePtr pPicture);
-
 int nxagentChangePictureClip(PicturePtr pPicture, int clipType, int nRects,
                                  xRectangle *rects, int xOrigin, int yOrigin);
 
@@ -1010,12 +1008,15 @@ void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pD
 
   #ifdef DEBUG
 
-  fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
-              nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
-              (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
-                   nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
-                       pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
-                           (void *) pSrc -> pDrawable);
+  if (pSrc -> pDrawable != NULL)
+  {
+    fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
+                nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
+                (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                     nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
+                         pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+                             (void *) pSrc -> pDrawable);
+  }
 
   fprintf(stderr, "nxagentComposite: Destination Picture [%lu][%p] with drawable [%s%s][%p].\n",
               nxagentPicturePriv(pDst) -> picture, (void *) pDst,
@@ -1064,16 +1065,19 @@ void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pD
    * the wrong data.
    */
 
-  nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
-
-  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  if (pSrc -> pDrawable != NULL)
   {
-    #ifdef TEST
-    fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
-                (void *) pSrc -> pDrawable);
-    #endif
+    nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
 
-    nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+    if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
+                  (void *) pSrc -> pDrawable);
+      #endif
+
+      nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+    }
   }
 
   if (pDst -> pDrawable != pSrc -> pDrawable)
@@ -2811,3 +2815,248 @@ Bool nxagentDisconnectAllPicture()
   return True;
 }
 
+void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color)
+{
+  Picture id;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateSolidFill: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (color == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! color pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+             sizeof(XRenderPictureAttributes_));
+
+  id = XRenderCreateSolidFill(nxagentDisplay, (XRenderColor *) color);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateSolidFill: Created solid fill xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+                                           xPointFixed *p2, int nStops,
+                                               xFixed *stops,
+                                                   xRenderColor *colors)
+{
+  Picture id;
+
+  XLinearGradient linearGradient;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateLinearGradient: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (p1 == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p1 pointer is NULL.\n");
+  }
+
+  if (p2 == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p2 pointer is NULL.\n");
+  }
+
+  if (stops == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! stops pointer is NULL.\n");
+  }
+
+  if (colors == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! colors pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+             sizeof(XRenderPictureAttributes_));
+
+  linearGradient.p1.x = (XFixed) p1 -> x;
+  linearGradient.p1.y = (XFixed) p1 -> y;
+  linearGradient.p2.x = (XFixed) p2 -> x;
+  linearGradient.p2.y = (XFixed) p2 -> y;
+
+  id = XRenderCreateLinearGradient(nxagentDisplay, &linearGradient,
+                                      (XFixed *) stops,
+                                          (XRenderColor *) colors, nStops);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateLinearGradient: Created linear gradient xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+                                           xPointFixed *outer,
+                                               xFixed innerRadius,
+                                                   xFixed outerRadius,
+                                                       int nStops,
+                                                           xFixed *stops,
+                                                               xRenderColor *colors)
+{
+  Picture id;
+
+  XRadialGradient radialGradient;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateRadialGradient: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (inner == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! inner pointer is NULL.\n");
+  }
+
+  if (outer == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! outer pointer is NULL.\n");
+  }
+
+  if (stops == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! stops pointer is NULL.\n");
+  }
+
+  if (colors == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! colors pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+               sizeof(XRenderPictureAttributes_));
+
+  radialGradient.inner.x = (XFixed) inner -> x;
+  radialGradient.inner.y = (XFixed) inner -> y;
+  radialGradient.inner.radius = (XFixed) innerRadius;
+  radialGradient.outer.x = (XFixed) outer -> x;
+  radialGradient.outer.y = (XFixed) outer -> y;
+  radialGradient.outer.radius = (XFixed) outerRadius;
+
+  id = XRenderCreateRadialGradient(nxagentDisplay, &radialGradient,
+                                       (XFixed *) stops,
+                                           (XRenderColor *) colors, nStops);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateRadialGradient: Created radial gradient xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+                                            xPointFixed *center,
+                                                xFixed angle, int nStops, 
+                                                    xFixed *stops, 
+                                                        xRenderColor *colors)
+{
+  Picture id;
+
+  XConicalGradient conicalGradient;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateConicalGradient: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (center == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! center pointer is NULL.\n");
+  }
+
+  if (stops == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! stops pointer is NULL.\n");
+  }
+
+  if (colors == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! colors pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+             sizeof(XRenderPictureAttributes_));
+
+  conicalGradient.center.x = (XFixed) center -> x;
+  conicalGradient.center.y = (XFixed) center -> y;
+  conicalGradient.angle = (XFixed) angle;
+
+  id = XRenderCreateConicalGradient(nxagentDisplay, &conicalGradient,
+                                        (XFixed *) stops,
+                                            (XRenderColor *) colors, nStops);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateConicalGradient: Created conical gradient xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
index 240dc3901..4346a4e1e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -105,4 +105,6 @@ void nxagentDisconnectPicture(pointer p0, XID x1, void* p2);
 
 void nxagentReconnectGlyphSet(void* p0, XID x1, void *p2);
 
+void nxagentDestroyPicture(PicturePtr pPicture);
+
 #endif /* __Render_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index 79cb74efa..612e71cf7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -60,6 +60,27 @@ typedef struct
 }
 nxagentWMHints;
 
+/*
+ * This structure is compatible with 32
+ * and 64 bit library interface. It has
+ * been copied from Xatomtype.h and it's
+ * a parameter of XChangeProperty().
+ */
+
+typedef struct
+{
+  unsigned long flags;
+  long          input;
+  long          initialState;
+  unsigned long iconPixmap;
+  unsigned long iconWindow;
+  long          iconX;
+  long          iconY;
+  unsigned long iconMask;
+  unsigned long windowGroup;
+}
+nxagentPropWMHints;
+
 WindowPtr nxagentRootlessWindow = NULL;
 
 #define TOP_LEVEL_TABLE_UNIT 100
@@ -429,6 +450,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
   Atom propertyX, typeX;
   char *output = NULL;
   nxagentWMHints wmHints;
+  nxagentPropWMHints propHints;
   Bool export = False;
   Bool freeMem = False;
 
@@ -489,8 +511,22 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     wmHints.flags |= InputHint;
     wmHints.input = True;
 
-    output = (char*) &wmHints;
-    export  = True;
+    /*
+     * Initialize the structure used in XChangeProperty().
+     */
+
+    propHints.flags = wmHints.flags;
+    propHints.input = (wmHints.input == True ? 1 : 0);
+    propHints.initialState = wmHints.initial_state;
+    propHints.iconPixmap = wmHints.icon_pixmap;
+    propHints.iconWindow = wmHints.icon_window;
+    propHints.iconX = wmHints.icon_x;
+    propHints.iconY = wmHints.icon_y;
+    propHints.iconMask = wmHints.icon_mask;
+    propHints.windowGroup = wmHints.window_group;
+
+    output = (char*) &propHints;
+    export = True;
 
     if ((wmHints.flags & IconPixmapHint) && (wmHints.icon_pixmap != None))
     {
@@ -504,17 +540,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
           nxagentSynchronizeRegion((DrawablePtr) icon, NullRegion, NEVER_BREAK, NULL);
         }
 
-        wmHints.icon_pixmap = nxagentPixmap(icon);
+        propHints.iconPixmap = nxagentPixmap(icon);
       }
       else
       {
-        wmHints.flags &= ~IconPixmapHint;
+        propHints.flags &= ~IconPixmapHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon pixmap %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_pixmap, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
@@ -526,17 +562,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (icon)
       {
-        wmHints.icon_window = nxagentWindow(icon);
+        propHints.iconWindow = nxagentWindow(icon);
       }
       else
       {
-        wmHints.flags &= ~IconWindowHint;
+        propHints.flags &= ~IconWindowHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon window %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_window, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
@@ -548,17 +584,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (icon)
       {
-        wmHints.icon_mask = nxagentPixmap(icon);
+        propHints.iconMask = nxagentPixmap(icon);
       }
       else
       {
-        wmHints.flags &= ~IconMaskHint;
+        propHints.flags &= ~IconMaskHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up icon mask %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.icon_mask, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
@@ -570,17 +606,17 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
       if (window)
       {
-        wmHints.window_group = nxagentWindow(window);
+        propHints.windowGroup = nxagentWindow(window);
       }
       else
       {
-        wmHints.flags &= ~WindowGroupHint;
+        propHints.flags &= ~WindowGroupHint;
 
         #ifdef WARNING
         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to look up window group %x from hint "
                     "exporting property %s type %s on window %p.\n",
                         (unsigned int) wmHints.window_group, propertyS, typeS,
-                            (void*)pWin);
+                            (void *) pWin);
         #endif
       }
     }
@@ -590,6 +626,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     XlibAtom *atoms = malloc(nUnits * sizeof(*atoms));
     Atom *input = value;
     int i;
+    int j = 0;
 
     freeMem = True;
     export = True;
@@ -597,16 +634,40 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
     for (i = 0; i < nUnits; i++)
     {
-       atoms[i] = nxagentLocalToRemoteAtom(input[i]);
-
-       if (atoms[i] == None)
-       {
-         #ifdef WARNING
-         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
-                     (long int) input[i], validateString(NameForAtom(input[i])));
-         #endif
-       }
+      /*
+       * Exporting the _NET_WM_PING property could
+       * result in rootless windows being grayed out
+       * when the compiz window manager is running.
+       *
+       * Better solution would probably be to handle
+       * the communication with the window manager
+       * instead of just getting rid of the property.
+       */
+
+      if (strcmp(NameForAtom(input[i]), "_NET_WM_PING") != 0)
+      {
+        atoms[j] = nxagentLocalToRemoteAtom(input[i]);
+
+        if (atoms[j] == None)
+        {
+          #ifdef WARNING
+          fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
+                      (long int) input[i], validateString(NameForAtom(input[i])));
+          #endif
+        }
+
+        j++;
+      }
+      #ifdef TEST
+      else
+      {
+        fprintf(stderr, "nxagentExportProperty: WARNING! "
+                    "Not exporting the _NET_WM_PING property.\n");
+      }
+      #endif
     }
+
+    nUnits = j;
   }
   else if (strcmp(typeS, "WINDOW") == 0)
   {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
index 90d25d0c1..ece4c9d31 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 524bafd10..2db7df8fe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -160,7 +160,6 @@ void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
 
 #endif
 
-Window nxagentIconWindow = None;
 Window nxagentFullscreenWindow = None;
 
 #ifdef VIEWPORT_FRAME
@@ -288,166 +287,6 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
   }
 }
 
-void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
-{
-  XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
-
-  if(nxagentIpaq)
-  {
-    XMapWindow(nxagentDisplay, nxagentIconWindow);
-    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                       DefaultScreen(nxagentDisplay));
-  }
-  else
-  {
-    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                       DefaultScreen(nxagentDisplay));
-  }
-}
-
-void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
-{
-  if(nxagentIpaq)
-  {
-    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
-
-    XMapWindow(nxagentDisplay, nxagentFullscreenWindow);
-  }
-  else
-  {
-/*
-    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
-*/
-/*
-FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWindow()
-       in order to avoid the session window is iconified.
-       We could avoid the sesssion window is iconified when a LeaveNotify event is received,
-       so this check would be unnecessary.
-*/
-    struct timeval timeout;
-    int i;
-    XEvent e;
-
-    XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
-                        RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
-
-    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
-      #endif
-
-      if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
-      {
-        break;
-      }
-
-      XSync(nxagentDisplay, 0);
-
-      timeout.tv_sec = 0;
-      timeout.tv_usec = 50 * 1000;
-
-      nxagentWaitEvents(nxagentDisplay, &timeout);
-    }
-
-    XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
-
-    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                       DefaultScreen(nxagentDisplay));
-
-    while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
-/*
-    XMapWindow(nxagentDisplay, nxagentIconWindow);
-*/
-  }
-}
-
-Window nxagentCreateIconWindow()
-{
-  XSetWindowAttributes attributes;
-  unsigned long valuemask;
-  char* window_name;
-  XTextProperty windowName;
-  XSizeHints sizeHints;
-  XWMHints wmHints;
-  Window w;
-  Mask mask;
-
-  /*
-   * Create icon window.
-   */
-
-  attributes.override_redirect = False;
-  attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
-  attributes.background_pixmap = nxagentScreenSaverPixmap;
-  valuemask = CWOverrideRedirect | CWBackPixmap | CWColormap;
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentCreateIconWindow: Going to create new icon window.\n");
-  #endif
-
-  w = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
-                        0, 0, 1, 1, 0,
-                            DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)),
-                                InputOutput,
-                                    DefaultVisual(nxagentDisplay, DefaultScreen(nxagentDisplay)),
-                                        valuemask, &attributes);
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentCreateIconWindow: Created new icon window with id [%ld].\n",
-              nxagentIconWindow);
-  #endif
-
-  /*
-   *  Set hints to the window manager for the icon window.
-   */
-
-  window_name = nxagentWindowName;
-  XStringListToTextProperty(&window_name, 1, &windowName);
-  sizeHints.flags = PMinSize | PMaxSize;
-  sizeHints.min_width = sizeHints.max_width = 1;
-  sizeHints.min_height = sizeHints.max_height = 1;
-  wmHints.flags = IconPixmapHint | IconMaskHint;
-  wmHints.initial_state = IconicState;
-  wmHints.icon_pixmap = nxagentIconPixmap;
-
-  if (useXpmIcon)
-  {
-    wmHints.icon_mask = nxagentIconShape;
-    wmHints.flags = IconPixmapHint | IconMaskHint;
-  }
-  else
-  {
-    wmHints.flags = StateHint | IconPixmapHint;
-  }
-
-  XSetWMProperties(nxagentDisplay, w,
-                      &windowName, &windowName,
-                          NULL , 0 , &sizeHints, &wmHints, NULL);
-
-  /*
-   * Enable events from the icon window.
-   */
-
-  nxagentGetDefaultEventMask(&mask);
-
-  XSelectInput(nxagentDisplay, w, (mask & ~(KeyPressMask |
-                   KeyReleaseMask)) | StructureNotifyMask);
-
-  /*
-   * Notify to client if user closes icon window.
-   */
-
-  if (nxagentWMIsRunning && !nxagentOption(Rootless))
-  {
-    XlibAtom deleteWMAtom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
-
-    XSetWMProtocols(nxagentDisplay, w, &deleteWMAtom, 1);
-  }
-
-  return w;
-}
-
 Bool nxagentMagicPixelZone(int x, int y)
 {
   return (x >= nxagentOption(Width) - 1 && y < 1);
@@ -977,6 +816,8 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
 
     nxagentChangeOption(Fullscreen, False);
 
+    nxagentFullscreenWindow = 0;
+
     resetAgentPosition = True;
   }
 
@@ -1382,8 +1223,6 @@ N/A
 
     if (nxagentOption(Fullscreen))
     {
-      attributes.override_redirect = True;
-
       /*
        * We need to disable the host's screensaver or
        * it will otherwise grab the screen even if it
@@ -1609,8 +1448,7 @@ N/A
   if (nxagentDoFullGeneration == 1 ||
           nxagentReconnectTrap == 1)
   {
-    valuemask = CWBackPixel | CWEventMask | CWColormap |
-                    (nxagentOption(Fullscreen) == 1 ? CWOverrideRedirect : 0);
+    valuemask = CWBackPixel | CWEventMask | CWColormap;
 
     attributes.background_pixel = nxagentBlackPixel;
 
@@ -1620,8 +1458,6 @@ N/A
 
     if (nxagentOption(Fullscreen) == 1)
     {
-      attributes.override_redirect = True;
-
       if (nxagentReconnectTrap)
       {
         /*
@@ -1754,7 +1590,7 @@ N/A
     sizeHints.width = nxagentOption(RootWidth);
     sizeHints.height = nxagentOption(RootHeight);
 
-    if (nxagentOption(DesktopResize) == 1)
+    if (nxagentOption(DesktopResize) == 1 || nxagentOption(Fullscreen) == 1)
     {
       sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
       sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
@@ -1799,37 +1635,6 @@ N/A
 
     XClearWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
 
-    if (nxagentOption(Fullscreen))
-    {
-      valuemask = CWBackPixmap | CWColormap | CWOverrideRedirect;
-    }
-    else
-    {
-      valuemask = CWBackPixmap | CWColormap;
-    }
-
-    attributes.background_pixmap = nxagentScreenSaverPixmap;
-    attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
-
-    if (nxagentOption(Fullscreen))
-    {
-      attributes.override_redirect = False;
-      if (nxagentReconnectTrap)
-      {
-        XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, True, GrabModeAsync,
-                      GrabModeAsync, CurrentTime);
-      }
-    }
-
-    if (nxagentOption(Fullscreen))
-    {
-      nxagentIconWindow = nxagentCreateIconWindow();
-    }
-    else
-    {
-      nxagentIconWindow = 0;
-    }
-
     /*
      * When we don't have window manager we grab keyboard
      * to let nxagent get keyboard events.
@@ -1880,13 +1685,6 @@ N/A
        */
 
       XSetWMProtocols(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &deleteWMatom, 1);
-
-      /*
-      if (nxagentOption(Fullscreen))
-      {
-        XSetWMProtocols(nxagentDisplay, nxagentIconWindow, &deleteWMatom, 1);
-      }
-      */
     }
     else
     {
@@ -2266,13 +2064,10 @@ FIXME: We should try to restore the previously
 
   if (nxagentOption(Fullscreen))
   {
-    nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-    nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-
-    nxagentChangeOption(RootX, (WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
-                            - nxagentOption(RootWidth)) / 2);
-    nxagentChangeOption(RootY,  (HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
-                            - nxagentOption(RootHeight)) / 2);
+    nxagentChangeOption(RootX, (nxagentOption(Width) -
+                            nxagentOption(RootWidth)) / 2);
+    nxagentChangeOption(RootY, (nxagentOption(Height) -
+                            nxagentOption(RootHeight)) / 2);
   }
   else
   {
@@ -2283,62 +2078,6 @@ FIXME: We should try to restore the previously
   nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
   nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
 
-  /*
-   * Change agent window size and size hints.
-   */
-
-  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);
-
-  if (nxagentOption(Fullscreen))
-  {
-    XResizeWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
-                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
-                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-
-    XResizeWindow(nxagentDisplay, nxagentInputWindows[pScreen -> myNum],
-                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
-                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-  }
-  else
-  {
-    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.
    */
@@ -2360,8 +2099,6 @@ FIXME: We should try to restore the previously
 
   (*pScreen -> PositionWindow)(WindowTable[pScreen -> myNum], 0, 0);
 
-  pRootWinSize = &WindowTable[pScreen -> myNum] -> winSize;
-
   nxagentSetRootClip(pScreen, 1);
 
   XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[0]),
@@ -2369,12 +2106,17 @@ FIXME: We should try to restore the previously
 
   nxagentMoveViewport(pScreen, 0, 0);
 
+  /*
+   * Update pointer bounds.
+   */
+
+  ScreenRestructured(pScreen);
+
   #ifdef TEST
   nxagentPrintAgentGeometry("After Resize Screen", "nxagentResizeScreen:");
   #endif
 
-  fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d].\n",
-              pScreen -> myNum, width, height);
+  nxagentSetPrintGeometry(pScreen -> myNum);
 
   return 1;
 
@@ -2451,9 +2193,10 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
   #endif
 
   #ifdef TEST
-  fprintf(stderr, "Info: Init shadow session. nxagentDisplayName [%s] nxagentDisplay "
-              "[%p] nxagentShadowDisplayName [%s].\n", nxagentDisplayName,
-                  (void *) nxagentDisplay, nxagentShadowDisplayName);
+  fprintf(stderr, "Info: Init shadow session. nxagentDisplayName [%s] "
+              "nxagentDisplay [%p] nxagentShadowDisplayName [%s].\n",
+                  nxagentDisplayName, (void *) nxagentDisplay,
+                      nxagentShadowDisplayName);
   #endif
 
   if (nxagentKeyboard != NULL)
@@ -2463,7 +2206,7 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
     if(nxagentKeyboard[i] == 0 || nxagentKeyboard[i + 1] == 0 || i == 0)
     {
       #ifdef WARNING
-      fprintf(stderr,"Warning: Wrong keyboard type: %s.\n", nxagentKeyboard);
+      fprintf(stderr,"WARNING! Wrong keyboard type: %s.\n", nxagentKeyboard);
       #endif
     }
     else
@@ -2475,7 +2218,8 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
   }
 
   #ifdef DEBUG
-  fprintf(stderr, "nxagentShadowInit: Setting the master uid [%d].\n", nxagentShadowUid);
+  fprintf(stderr, "nxagentShadowInit: Setting the master uid [%d].\n",
+              nxagentShadowUid);
   #endif
 
 #if !defined (__CYGWIN32__) && !defined (WIN32)
@@ -2495,8 +2239,9 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
   if (NXShadowCreate(nxagentDisplay, layout, nxagentShadowDisplayName,
                          (void *) &nxagentShadowDisplay) != 1)
   {
-    #ifdef TEST
-    fprintf(stderr, "nxagentShadowInit: Failed to initialize shadow display [%s].\n", nxagentShadowDisplayName);
+    #ifdef PANIIC
+    fprintf(stderr, "nxagentShadowInit: PANIC! Failed to initialize shadow "
+                "display [%s].\n", nxagentShadowDisplayName);
     #endif
 
     return -1;
@@ -2519,8 +2264,8 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
   if (NXShadowAddUpdaterDisplay(nxagentDisplay, &nxagentShadowWidth,
                                     &nxagentShadowHeight, &nxagentMasterDepth) == 0)
   {
-    #ifdef TEST
-    fprintf(stderr, "nxagentShadowInit: Failed to add display [%s].\n",
+    #ifdef PANIC
+    fprintf(stderr, "nxagentShadowInit: PANIC! Failed to add display [%s].\n",
                 nxagentDisplayName);
     #endif
 
@@ -2540,16 +2285,73 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
                               nxagentOption(RootHeight) * 1.0 / nxagentShadowHeight);
   }
 
-  if (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) -> class != TrueColor ||
-          DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentShadowDisplay)) -> class != TrueColor)
+  if (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentDisplay)) ->
+          class != TrueColor)
   {
-    #ifdef TEST
-    fprintf(stderr, "nxagentShadowInit: PANIC! The visual class is not TrueColor.\n");
+    #ifdef PANIC
+    fprintf(stderr, "nxagentShadowInit: PANIC! The visual class of the remote "
+                "X server is not TrueColor.\n");
     #endif
 
     return -1;
   }
 
+  if (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentShadowDisplay)) ->
+          class != TrueColor)
+  {
+    #ifdef PANIC
+
+    const char *className;
+
+    switch (DefaultVisualOfScreen(DefaultScreenOfDisplay(nxagentShadowDisplay)) -> class)
+    {
+      case StaticGray:
+      {
+        className = "StaticGray";
+
+        break;
+      }
+      case StaticColor:
+      {
+        className = "StaticColor";
+
+        break;
+      }
+      case PseudoColor:
+      {
+        className = "PseudoColor";
+
+        break;
+      }
+      case DirectColor:
+      {
+        className = "DirectColor";
+
+        break;
+      }
+      case GrayScale:
+      {
+        className = "GrayScale";
+
+        break;
+      }
+      default:
+      {
+        className = "";
+
+        break;
+      }
+    }
+
+    fprintf(stderr, "nxagentShadowInit: PANIC! Cannot shadow the display. "
+                "%s visual class is not supported. Only TrueColor visuals "
+                    "are supported.\n", className);
+
+    #endif /* #endif PANIC */
+
+    return -1;
+  }
+
   #endif
 
   nxagentShadowDepth = pScreen -> rootDepth;
@@ -2566,7 +2368,8 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
       else if (nxagentShadowDepth == 8)
       {
         #ifdef PANIC
-        fprintf(stderr, "nxagentShadowInit: PANIC! The target depth is 8 bit.\n");
+        fprintf(stderr, "nxagentShadowInit: PANIC! Unable to shadow a %d bit "
+                    "display with a 8 bit screen depth.\n", nxagentMasterDepth);
         #endif
 
         return -1;
@@ -2585,7 +2388,8 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
       else if (nxagentShadowDepth == 8)
       {
         #ifdef PANIC
-        fprintf(stderr, "nxagentShadowInit: PANIC! The target depth is 8 bit.\n");
+        fprintf(stderr, "nxagentShadowInit: PANIC! Unable to shadow a 16 bit "
+                    "display with a 8 bit screen depth.\n");
         #endif
 
         return -1;
@@ -2600,7 +2404,8 @@ int nxagentShadowInit(ScreenPtr pScreen, WindowPtr pWin)
       if (nxagentShadowDepth != 8)
       {
         #ifdef PANIC
-        fprintf(stderr, "nxagentShadowInit: PANIC! The target depth is 8 bit.\n");
+        fprintf(stderr, "nxagentShadowInit: PANIC! Unable to shadow a 8 bit "
+                    "display with a %d bit screen depth.\n", nxagentShadowDepth);
         #endif
 
         return -1;
@@ -3046,7 +2851,7 @@ void nxagentShadowAdaptDepth(unsigned int width, unsigned int height,
     #ifdef WARNING
     fprintf(stderr, "nxagentCorrectDepthShadow: WARNING! Visual not found. Using default visual.\n");
     #endif
-    
+
     pVisual = nxagentVisuals[nxagentDefaultVisualIndex].visual;
   }
 
@@ -3473,10 +3278,10 @@ int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height)
     RRScreenSizePtr oldSizes;
 
     pScrPriv = rrGetScrPriv(pScreen);
-   
+
     oldWidth = pScreen->width;
     oldHeight = pScreen->height;
-    
+
     if (!pScrPriv)
     {
       return 1;
@@ -3556,7 +3361,7 @@ int nxagentRRSetScreenConfig(ScreenPtr pScreen, int width, int height)
     }
 
     RREditConnectionInfo (pScreen);
-    
+
     /*
      * Fix pointer bounds and location
      */
@@ -3694,7 +3499,8 @@ void nxagentSaveAreas(PixmapPtr pPixmap, RegionPtr prgnSave, int xorg, int yorg,
   return;
 }
 
-void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int yorg, WindowPtr pWin)
+void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg,
+                             int yorg, WindowPtr pWin)
 {
   PixmapPtr pVirtualPixmap;
   RegionPtr clipRegion;
@@ -3710,6 +3516,14 @@ void nxagentRestoreAreas(PixmapPtr pPixmap, RegionPtr prgnRestore, int xorg, int
   BoxRec extents;
   miBSWindowPtr pBackingStore;
 
+  /*
+   * Limit the area to restore to the
+   * root window size.
+   */
+
+  REGION_INTERSECT(pWin -> pScreen, prgnRestore, prgnRestore,
+                       &WindowTable[pWin -> drawable.pScreen -> myNum] -> winSize);
+
   pBackingStore = (miBSWindowPtr) pWin -> backStorage;
 
   pVirtualPixmap = nxagentVirtualPixmap(pPixmap);
@@ -3903,6 +3717,24 @@ void nxagentShadowAdaptToRatio(void)
   REGION_UNINIT(pScreen, &region);
 }
 
+void nxagentPrintGeometry()
+{
+  int i;
+
+  for (i = 0; i < screenInfo.numScreens; i++)
+  {
+    if (nxagentPrintGeometryFlags && (1 << i))
+    {
+      fprintf(stderr, "Info: Screen [%d] resized to geometry [%dx%d] "
+                  "fullscreen [%d].\n", i, screenInfo.screens[i] -> width,
+                      screenInfo.screens[i] -> height,
+                          nxagentOption(Fullscreen));
+    }
+  }
+
+  nxagentPrintGeometryFlags = 0;
+}
+
 #ifdef DUMP
 
 void nxagentShowPixmap(PixmapPtr pPixmap, int x, int y, int width, int height)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 3550dd553..1ab6caad2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -36,6 +36,9 @@ is" without express or implied warranty.
 #define MIN_NXAGENT_HEIGHT 60
 #define NXAGENT_FRAME_WIDTH 2000
 
+#define nxagentSetPrintGeometry(screen) \
+    nxagentPrintGeometryFlags = (1 << (screen));
+    
 extern int nxagentClients;
 
 extern int nxagentAutoDisconnectTimeout;
@@ -44,7 +47,6 @@ extern ScreenPtr nxagentDefaultScreen;
 
 extern Pixmap nxagentPixmapLogo;
 
-extern Window nxagentIconWindow;
 extern Window nxagentFullscreenWindow;
 
 extern RegionRec nxagentShadowUpdateRegion;
@@ -58,6 +60,8 @@ extern short nxagentShadowUid;
 void nxagentSetScreenInfo(ScreenInfo *screenInfo);
 void nxagentSetPixmapFormats(ScreenInfo *screenInfo);
 
+void nxagentPrintGeometry();
+
 extern Window nxagentDefaultWindows[MAXSCREENS];
 extern Window nxagentInputWindows[MAXSCREENS];
 extern Window nxagentScreenSaverWindows[MAXSCREENS];
@@ -83,11 +87,6 @@ extern int nxagentBitsPerPixel(int depth);
 
 void nxagentSetScreenSaverTime(void);
 
-void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
-void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
-
-Window nxagentCreateIconWindow(void);
-
 Bool nxagentMagicPixelZone(int x, int y);
 
 Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
index 8de74b85b..24dbf1413 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.h b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
index bcc3a90b1..86920ad8b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.c b/nx-X11/programs/Xserver/hw/nxagent/Split.c
index 8f1c65eba..bf7f705b9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.h b/nx-X11/programs/Xserver/hw/nxagent/Split.h
index 397feef16..60be29b39 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
index 704c63e51..1d5fdee20 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
index 2796b2f14..22de3bc1b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
index 493a18a1b..aa6937e70 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Utils.h b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
index 9334a7868..830b2753f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Utils.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.c b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
index 2a8283a30..f38931677 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.h b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
index 6d8a8742d..c682f92dd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 8da5d8bd1..2da21b91c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -692,222 +692,91 @@ void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
 
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 {
-  Window w;
-  XSetWindowAttributes attributes;
-  unsigned long valuemask;
+  XEvent e;
+  XSizeHints sizeHints;
 
-  if (nxagentOption(Rootless))
+  if (nxagentOption(Rootless) == 1)
   {
     return;
   }
 
-  if (!switchOn)
+  if (switchOn == 0)
   {
     nxagentWMDetect();
 
-    if (!nxagentWMIsRunning)
-    {
-      #ifdef WARNING
-      fprintf(stderr, "Warning: Can't switch to window mode, no window manager has been detected.\n");
-      #endif
-
-      return;
-    }
-  }
-
-  w = nxagentDefaultWindows[pScreen -> myNum];
-  attributes.override_redirect = switchOn;
-  valuemask = CWOverrideRedirect;
-  XUnmapWindow(nxagentDisplay, w);
-  XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
-
-  if (switchOn)
-  {
     /*
-     * Change to fullscreen mode.
+     * The smart scheduler could be stopped while
+     * waiting for the reply. In this case we need
+     * to yield explicitly to avoid to be stuck in
+     * the dispatch loop forever.
      */
 
-    struct timeval timeout;
-    int i;
-    XEvent e;
-
-    /*
-     * Wait for window manager reparenting the default window.
-     */
+    isItTimeToYield = 1;
 
-    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+    if (nxagentWMIsRunning == 0)
     {
-      #ifdef TEST
-      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
+      #ifdef WARNING
+      fprintf(stderr, "Warning: Can't switch to window mode, no window manager "
+                  "has been detected.\n");
       #endif
 
-      if (XCheckTypedWindowEvent(nxagentDisplay, w, ReparentNotify, &e))
-      {
-        break;
-      }
-
-      /*
-       * This should also flush
-       * the NX link for us.
-       */
-
-      XSync(nxagentDisplay, 0);
-
-      timeout.tv_sec  = 0;
-      timeout.tv_usec = 50 * 1000;
-
-      nxagentWaitEvents(nxagentDisplay, &timeout);
+      return;
     }
+  }
 
-    if (i < 100)
-    {
-      /*
-       * The window manager has done with the reparent
-       * operation. We can resize and map the window.
-       */
-
-      nxagentChangeOption(Fullscreen, True);
-
-      /*
-       * Save the window-mode configuration.
-       */
-
-      nxagentChangeOption(SavedX, nxagentOption(X));
-      nxagentChangeOption(SavedY, nxagentOption(Y));
-      nxagentChangeOption(SavedWidth, nxagentOption(Width));
-      nxagentChangeOption(SavedHeight, nxagentOption(Height));
-      nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
-      nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
-
-      /*
-       * Reconf the Default window.
-       */
-
-      nxagentChangeOption(X, 0);
-      nxagentChangeOption(Y, 0);
-      nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-      nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-
-      /*
-       * Move the root window.
-       */
-
-      nxagentChangeOption(RootX, (nxagentOption(Width) - nxagentOption(RootWidth)) / 2);
-      nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) / 2);
-      nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
-      nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
-
-      XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
-                            nxagentOption(Width), nxagentOption(Height));
-
-      nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight));
-
-      XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
-                      nxagentOption(RootX), nxagentOption(RootY));
-
-      /*
-       * We disable the screensaver when changing
-       * mode to fullscreen. Is it really needed?
-       */
-
-      XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
-
-      if (nxagentIconWindow == None)
-      {
-        nxagentIconWindow = nxagentCreateIconWindow();
+  #ifdef TEST
+  fprintf(stderr, "nxagentSwitchFullscreen: Switching to %s mode.\n",
+              switchOn ? "fullscreen" : "windowed");
+  #endif
 
-        XMapWindow(nxagentDisplay, nxagentIconWindow);
-      }
+  nxagentChangeOption(Fullscreen, switchOn);
 
-      XMapRaised(nxagentDisplay, w);
-      XSetInputFocus(nxagentDisplay, w, RevertToParent, CurrentTime);
-      XCheckTypedWindowEvent(nxagentDisplay, w, LeaveNotify, &e);
-      nxagentFullscreenWindow = w;
+  if (nxagentOption(DesktopResize) == 1)
+  {
+    sizeHints.flags = PSize;
 
-      if (nxagentOption(DesktopResize) == 1)
-      {
-        if (nxagentOption(Shadow) == 0)
-        {
-          nxagentRRSetScreenConfig(pScreen, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
-                                       HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-        }
-        else
-        {
-          nxagentShadowAdaptToRatio();
-        }
-      }
-    }
-    else
+    if (switchOn == 1)
     {
-      /*
-       * We have waited for a reparent event unsuccessfully.
-       * Something happened to the window manager.
-       */
-
-      #ifdef WARNING
-      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Expected ReparentNotify event missing.\n");
-      #endif
-
-      nxagentWMIsRunning = False;
-      attributes.override_redirect = False;
-      XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
-      XMapWindow(nxagentDisplay, w);
+      sizeHints.width =
+          WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+      sizeHints.height =
+          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
     }
-  }
-  else
-  {
-    /*
-     * FIXME:
-     * It could be necessary:
-     * - To restore screensaver.
-     * - To set or reset nxagentForceBackingStore flag.
-     * - To grab keyboard.
-     * - To propagate device settings to the X server if no WM is running.
-     */
-
-    /*
-     * Change to windowed mode.
-     */
-
-    nxagentChangeOption(Fullscreen, False);
-    XDestroyWindow(nxagentDisplay, nxagentIconWindow);
-    nxagentIconWindow = nxagentFullscreenWindow = None;
-
-    if (nxagentOption(DesktopResize) == 1)
+    else
     {
-      nxagentChangeOption(RootWidth, nxagentOption(SavedRootWidth));
-      nxagentChangeOption(RootHeight, nxagentOption(SavedRootHeight));
-
-      if (nxagentOption(Shadow) == 0)
-      {
-        nxagentRRSetScreenConfig(pScreen, nxagentOption(RootWidth), nxagentOption(RootHeight));
-      }
+      sizeHints.width = nxagentOption(RootWidth);
+      sizeHints.height = nxagentOption(RootHeight);
     }
 
-    nxagentChangeOption(X, nxagentOption(SavedX));
-    nxagentChangeOption(Y, nxagentOption(SavedY));
-    nxagentChangeOption(Width, nxagentOption(SavedWidth));
-    nxagentChangeOption(Height, nxagentOption(SavedHeight));
+    XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+                         &sizeHints);
+  }
 
-    if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1)
-    {
-      nxagentShadowAdaptToRatio();
-    }
+  memset(&e, 0, sizeof(e));
 
-    XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
-                          nxagentOption(Width), nxagentOption(Height));
+  e.xclient.type = ClientMessage;
+  e.xclient.message_type = nxagentAtoms[13]; /* _NET_WM_STATE */
+  e.xclient.display = nxagentDisplay;
+  e.xclient.window = nxagentDefaultWindows[pScreen -> myNum];
+  e.xclient.format = 32;
+  e.xclient.data.l[0] = nxagentOption(Fullscreen) ? 1 : 0;
+  e.xclient.data.l[1] = nxagentAtoms[14]; /* _NET_WM_STATE_FULLSCREEN */
 
-    nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height));
+  XSendEvent(nxagentDisplay, DefaultRootWindow(nxagentDisplay), False,
+                 SubstructureRedirectMask, &e);
 
-    XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), 0, 0);
-    XMapWindow(nxagentDisplay, w);
+  if (switchOn == 1)
+  {
+    nxagentFullscreenWindow = nxagentDefaultWindows[pScreen -> myNum];
 
-    nxagentChangeOption(RootX, 0);
-    nxagentChangeOption(RootY, 0);
+    nxagentGrabPointerAndKeyboard(NULL);
   }
+  else
+  {
+    nxagentFullscreenWindow = None;
 
-  XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
-                        nxagentOption(Width), nxagentOption(Height));
+    nxagentUngrabPointerAndKeyboard(NULL);
+  } 
 }
 
 #ifdef VIEWPORT_FRAME
@@ -2409,6 +2278,11 @@ void nxagentMapDefaultWindows()
         #endif
 
         XMapWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
+
+        if (nxagentOption(Fullscreen) == 1 && nxagentWMIsRunning == 1)
+        {
+          nxagentSwitchFullscreen(pScreen, 1);
+        }
       }
 
       /*
@@ -2438,26 +2312,6 @@ void nxagentMapDefaultWindows()
                            nxagentDefaultWindows[i], CurrentTime);
   }
 
-  /*
-   * Map the icon window.
-   */
-
-  if (nxagentIconWindow != 0)
-  {
-    #ifdef TEST
-    fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
-                nxagentIconWindow);
-    #endif
-
-    XMapWindow(nxagentDisplay, nxagentIconWindow);
-
-    if (nxagentIpaq != 0)
-    {
-      XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                         DefaultScreen(nxagentDisplay));
-    }
-  }
-
   /*
    * Ensure that the fullscreen window gets the focus.
    */
@@ -2895,6 +2749,13 @@ FIXME: Do we need to set save unders attribute here?
       XSizeHints *props, hints;
       unsigned char *data = NULL;
 
+      #ifdef _XSERVER64
+
+      unsigned char *data64 = NULL;
+      unsigned int i;
+
+      #endif
+
       hints.flags = 0;
 
       ret = GetWindowProperty(pWin,
@@ -2903,10 +2764,13 @@ FIXME: Do we need to set save unders attribute here?
                                           False, XA_WM_SIZE_HINTS,
                                               &type, &format, &nItems, &bytesLeft, &data);
 
-      props = (XSizeHints*) data;
+      /*
+       * 72 is the number of bytes returned by
+       * sizeof(XSizeHints) on 32 bit platforms.
+       */
 
       if (ret == Success &&
-              ((format >> 3) * nItems) == sizeof(XSizeHints) &&
+              ((format >> 3) * nItems) == 72 &&
                   bytesLeft == 0 &&
                       type == XA_WM_SIZE_HINTS)
       {
@@ -2915,6 +2779,30 @@ FIXME: Do we need to set save unders attribute here?
                     (void*)pWin, pWin -> drawable.id, nxagentWindow(pWin));
         #endif
 
+        #ifdef _XSERVER64
+
+        data64 = (unsigned char *) malloc(sizeof(XSizeHints) + 4);
+
+        for (i = 0; i < 4; i++)
+        {
+          *(data64 + i) = *(data + i);
+        }
+
+        *(((int *) data64) + 1) = 0;
+
+        for (i = 8; i < sizeof(XSizeHints) + 4; i++)
+        {
+          *(data64 + i) = *(data + i - 4);
+        }
+
+        props = (XSizeHints *) data64;
+
+        #else
+
+        props = (XSizeHints *) data;
+
+        #endif   /* _XSERVER64 */
+
         hints = *props;
       }
       else
@@ -2933,6 +2821,15 @@ FIXME: Do we need to set save unders attribute here?
       XSetWMNormalHints(nxagentDisplay,
                            nxagentWindow(pWin),
                               &hints);
+
+      #ifdef _XSERVER64
+
+      if (data64 != NULL)
+      {
+        free(data64);
+      }
+
+      #endif
     }
   }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
index ca33f1448..6fc97b341 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Windows.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
index c49f1587f..7bc1c74cb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
index c49f1587f..7bc1c74cb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index f84ca0e03..ba4e1e662 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -513,13 +513,6 @@ Dispatch(void)
      * completed. We can now handle our clients.
      */
 
-    if (serverGeneration > nxagentMaxAllowedResets)
-    {
-      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
-
-      nxagentSessionState = SESSION_UP;
-    }
-
     #ifdef XKB
 
     nxagentInitXkbWrapper();
@@ -603,6 +596,21 @@ Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
           clientReady[1] = NXAGENT_WAKEUP;
         }
 
+        if (serverGeneration > nxagentMaxAllowedResets &&
+                nxagentSessionState == SESSION_STARTING &&
+                    (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
+        {
+          #ifdef NX_DEBUG_INPUT
+          fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
+                      GetTimeAsString(), GetTimeInMillis());
+          #else
+          fprintf(stderr, "Session: Session started at '%s'.\n",
+                      GetTimeAsString());
+          #endif
+
+          nxagentSessionState = SESSION_UP;
+        }
+
         #ifdef BLOCKS
         fprintf(stderr, "[End dispatch]\n");
         #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index f84ca0e03..ba4e1e662 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -513,13 +513,6 @@ Dispatch(void)
      * completed. We can now handle our clients.
      */
 
-    if (serverGeneration > nxagentMaxAllowedResets)
-    {
-      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
-
-      nxagentSessionState = SESSION_UP;
-    }
-
     #ifdef XKB
 
     nxagentInitXkbWrapper();
@@ -603,6 +596,21 @@ Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
           clientReady[1] = NXAGENT_WAKEUP;
         }
 
+        if (serverGeneration > nxagentMaxAllowedResets &&
+                nxagentSessionState == SESSION_STARTING &&
+                    (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
+        {
+          #ifdef NX_DEBUG_INPUT
+          fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
+                      GetTimeAsString(), GetTimeInMillis());
+          #else
+          fprintf(stderr, "Session: Session started at '%s'.\n",
+                      GetTimeAsString());
+          #endif
+
+          nxagentSessionState = SESSION_UP;
+        }
+
         #ifdef BLOCKS
         fprintf(stderr, "[End dispatch]\n");
         #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
index b431796be..225ecdaf8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
index b431796be..225ecdaf8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index a8a2a68bd..8e87d58c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -191,6 +191,7 @@ xEvent *xeviexE;
 
 #ifdef NX_DEBUG_INPUT
 extern int nxagentDebugInput;
+extern int nxagentDebugInputDevices;
 #endif
  
 extern Display *nxagentDisplay;
@@ -1865,6 +1866,12 @@ DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n");
+        }
+        #endif
 	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
 					   currentTime, TRUE);
     }
@@ -2735,6 +2742,13 @@ CheckPassiveGrabsOnWindow(
 				tempGrab.modifiersDetail.exact&(~0x1f00);
 	    }
 #endif
+            #ifdef NX_DEBUG_INPUT
+            if (nxagentDebugInputDevices == 1)
+            {
+              fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n",
+                          device == inputInfo.keyboard ? "keyboard" : "pointer");
+            }
+            #endif
 	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  
 	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
@@ -3093,7 +3107,17 @@ drawable.id:0;
     else
 	DeliverFocusedEvent(keybd, xE, sprite.win, count);
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n");
+      }
+    #endif
         (*keybd->DeactivateGrab)(keybd);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #ifdef XKB
@@ -3320,7 +3344,17 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 			    mouse, count);
     #endif
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n");
+      }
+    #endif
         (*mouse->DeactivateGrab)(mouse);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #define AtMostOneClient \
@@ -4041,6 +4075,12 @@ ProcGrabPointer(ClientPtr client)
     pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
     if (!pWin)
 	return BadWindow;
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index);
+    }
+    #endif
     if (stuff->confineTo == None)
 	confineTo = NullWindow;
     else 
@@ -4100,6 +4140,12 @@ ProcGrabPointer(ClientPtr client)
 	tempGrab.keyboardMode = stuff->keyboardMode;
 	tempGrab.pointerMode = stuff->pointerMode;
 	tempGrab.device = device;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n");
+        }
+        #endif
 	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
 	if (oldCursor)
 	    FreeCursor (oldCursor, (Cursor)0);
@@ -4163,6 +4209,12 @@ ProcUngrabPointer(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4170,7 +4222,25 @@ ProcUngrabPointer(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	    (grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
@@ -4225,6 +4295,12 @@ GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
 	tempGrab.pointerMode = other_mode;
 	tempGrab.eventMask = mask;
 	tempGrab.device = dev;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n");
+        }
+        #endif
 	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4238,6 +4314,12 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST(xGrabKeyboardReq);
     int result;
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 #ifdef XCSECURITY
     if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
@@ -4268,6 +4350,12 @@ ProcUngrabKeyboard(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4275,7 +4363,25 @@ ProcUngrabKeyboard(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	(grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index a8a2a68bd..8e87d58c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -191,6 +191,7 @@ xEvent *xeviexE;
 
 #ifdef NX_DEBUG_INPUT
 extern int nxagentDebugInput;
+extern int nxagentDebugInputDevices;
 #endif
  
 extern Display *nxagentDisplay;
@@ -1865,6 +1866,12 @@ DeliverEventsToWindow(register WindowPtr pWin, xEvent *pEvents, int count,
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "DeliverEventsToWindow: Activating passive grab on pointer.\n");
+        }
+        #endif
 	(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
 					   currentTime, TRUE);
     }
@@ -2735,6 +2742,13 @@ CheckPassiveGrabsOnWindow(
 				tempGrab.modifiersDetail.exact&(~0x1f00);
 	    }
 #endif
+            #ifdef NX_DEBUG_INPUT
+            if (nxagentDebugInputDevices == 1)
+            {
+              fprintf(stderr, "CheckPassiveGrabsOnWindow: Activating passive grab on %s.\n",
+                          device == inputInfo.keyboard ? "keyboard" : "pointer");
+            }
+            #endif
 	    (*device->ActivateGrab)(device, grab, currentTime, TRUE);
  
 	    FixUpEventFromWindow(xE, grab->window, None, TRUE);
@@ -3093,7 +3107,17 @@ drawable.id:0;
     else
 	DeliverFocusedEvent(keybd, xE, sprite.win, count);
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessKeyboardEvent: Deactivating grab on keyboard.\n");
+      }
+    #endif
         (*keybd->DeactivateGrab)(keybd);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #ifdef XKB
@@ -3320,7 +3344,17 @@ ProcessPointerEvent (register xEvent *xE, register DeviceIntPtr mouse, int count
 			    mouse, count);
     #endif
     if (deactivateGrab)
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcessPointerEvent: Deactivating grab on pointer.\n");
+      }
+    #endif
         (*mouse->DeactivateGrab)(mouse);
+    #ifdef NX_DEBUG_INPUT
+    }
+    #endif
 }
 
 #define AtMostOneClient \
@@ -4041,6 +4075,12 @@ ProcGrabPointer(ClientPtr client)
     pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
     if (!pWin)
 	return BadWindow;
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabPointer: pWin [%p] client [%d].\n", pWin, client -> index);
+    }
+    #endif
     if (stuff->confineTo == None)
 	confineTo = NullWindow;
     else 
@@ -4100,6 +4140,12 @@ ProcGrabPointer(ClientPtr client)
 	tempGrab.keyboardMode = stuff->keyboardMode;
 	tempGrab.pointerMode = stuff->pointerMode;
 	tempGrab.device = device;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "ProcGrabPointer: Activating active grab on pointer.\n");
+        }
+        #endif
 	(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
 	if (oldCursor)
 	    FreeCursor (oldCursor, (Cursor)0);
@@ -4163,6 +4209,12 @@ ProcUngrabPointer(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabPointer: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4170,7 +4222,25 @@ ProcUngrabPointer(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	    (CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	    (grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: Deactivating grab on pointer.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabPointer: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
@@ -4225,6 +4295,12 @@ GrabDevice(register ClientPtr client, register DeviceIntPtr dev,
 	tempGrab.pointerMode = other_mode;
 	tempGrab.eventMask = mask;
 	tempGrab.device = dev;
+        #ifdef NX_DEBUG_INPUT
+        if (nxagentDebugInputDevices == 1)
+        {
+          fprintf(stderr, "GrabDevice: Activating active grab on keyboard.\n");
+        }
+        #endif
 	(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4238,6 +4314,12 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST(xGrabKeyboardReq);
     int result;
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcGrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 #ifdef XCSECURITY
     if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
@@ -4268,6 +4350,12 @@ ProcUngrabKeyboard(ClientPtr client)
     TimeStamp time;
     REQUEST(xResourceReq);
 
+    #ifdef NX_DEBUG_INPUT
+    if (nxagentDebugInputDevices == 1)
+    {
+      fprintf(stderr, "ProcUngrabKeyboard: client [%d].\n", client -> index);
+    }
+    #endif
     REQUEST_SIZE_MATCH(xResourceReq);
     UpdateCurrentTime();
     grab = device->grab;
@@ -4275,7 +4363,25 @@ ProcUngrabKeyboard(ClientPtr client)
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
 	(grab) && SameClient(grab, client))
+    #ifdef NX_DEBUG_INPUT
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: Deactivating grab on keyboard.\n");
+      }
+    #endif
 	(*device->DeactivateGrab)(device);
+    #ifdef NX_DEBUG_INPUT
+    }
+    else
+    {
+      if (nxagentDebugInputDevices == 1)
+      {
+        fprintf(stderr, "ProcUngrabKeyboard: current time [%lu] request time [%lu] grab time [%lu].\n",
+                    currentTime.milliseconds, time.milliseconds, device->grabTime.milliseconds);
+      }
+    }
+    #endif
     return Success;
 }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
index a510c9356..6e67b7ffe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
index a510c9356..6e67b7ffe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
index aee27e820..172252b32 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
index aee27e820..172252b32 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index f51a8bce9..6340de537 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index f51a8bce9..6340de537 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
index 3e105ac64..d6cd96631 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
index 3e105ac64..d6cd96631 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
index 0f30843d6..e78a1bf14 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
index 0f30843d6..e78a1bf14 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
index af07fdcc2..c71ea8142 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
index af07fdcc2..c71ea8142 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
index 6ad60223f..efb295861 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
index 6ad60223f..efb295861 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
index e08f5e45f..d2bead0bc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
index e08f5e45f..d2bead0bc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
index 1731e0753..be1096c6c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
index 1731e0753..be1096c6c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
index 5d6f71475..be961c400 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -62,6 +62,7 @@
 #include "Screen.h"
 #include "Pixmaps.h"
 #include "Drawable.h"
+#include "Render.h"
 
 #define PANIC
 #define WARNING
@@ -1063,7 +1064,47 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
 static PicturePtr createSourcePicture(void)
 {
     PicturePtr pPicture;
-    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+
+    extern int nxagentPicturePrivateIndex;
+
+    unsigned int totalPictureSize;
+
+    DevUnion *ppriv;
+
+    char *privPictureRecAddr;
+
+    int i;
+
+    /*
+     * Compute size of entire PictureRect, plus privates.
+     */
+
+    totalPictureSize = sizeof(PictureRec) +
+                           picturePrivateCount * sizeof(DevUnion) +
+                               sizeof(nxagentPrivPictureRec);
+
+    pPicture = (PicturePtr) xalloc(totalPictureSize);
+
+    if (pPicture != NULL)
+    {
+      ppriv = (DevUnion *) (pPicture + 1);
+
+      for (i = 0; i < picturePrivateCount; ++i)
+      {
+        /*
+         * Other privates are inaccessible.
+         */
+
+        ppriv[i].ptr = NULL;
+      }
+
+      privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
+
+      ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
+
+      pPicture -> devPrivates = ppriv;
+    }
+
     pPicture->pDrawable = 0;
     pPicture->pFormat = 0;
     pPicture->pNext = 0;
@@ -1697,6 +1738,10 @@ FreePicture (pointer	value,
 
     if (--pPicture->refcnt == 0)
     {
+#ifdef NXAGENT_SERVER
+        nxagentDestroyPicture(pPicture);
+#endif
+
 	if (pPicture->transform)
 	    xfree (pPicture->transform);
         if (!pPicture->pDrawable) {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
index 5d6f71475..be961c400 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -62,6 +62,7 @@
 #include "Screen.h"
 #include "Pixmaps.h"
 #include "Drawable.h"
+#include "Render.h"
 
 #define PANIC
 #define WARNING
@@ -1063,7 +1064,47 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
 static PicturePtr createSourcePicture(void)
 {
     PicturePtr pPicture;
-    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+
+    extern int nxagentPicturePrivateIndex;
+
+    unsigned int totalPictureSize;
+
+    DevUnion *ppriv;
+
+    char *privPictureRecAddr;
+
+    int i;
+
+    /*
+     * Compute size of entire PictureRect, plus privates.
+     */
+
+    totalPictureSize = sizeof(PictureRec) +
+                           picturePrivateCount * sizeof(DevUnion) +
+                               sizeof(nxagentPrivPictureRec);
+
+    pPicture = (PicturePtr) xalloc(totalPictureSize);
+
+    if (pPicture != NULL)
+    {
+      ppriv = (DevUnion *) (pPicture + 1);
+
+      for (i = 0; i < picturePrivateCount; ++i)
+      {
+        /*
+         * Other privates are inaccessible.
+         */
+
+        ppriv[i].ptr = NULL;
+      }
+
+      privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
+
+      ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
+
+      pPicture -> devPrivates = ppriv;
+    }
+
     pPicture->pDrawable = 0;
     pPicture->pFormat = 0;
     pPicture->pNext = 0;
@@ -1697,6 +1738,10 @@ FreePicture (pointer	value,
 
     if (--pPicture->refcnt == 0)
     {
+#ifdef NXAGENT_SERVER
+        nxagentDestroyPicture(pPicture);
+#endif
+
 	if (pPicture->transform)
 	    xfree (pPicture->transform);
         if (!pPicture->pDrawable) {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
index 255411a9b..b6cee91f1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
index 255411a9b..b6cee91f1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
index 772a1fbe5..d02f3f015 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
index 772a1fbe5..d02f3f015 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
index 426d15b1b..e1bb44148 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
index 426d15b1b..e1bb44148 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index de2df855f..562cd2c66 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -35,7 +35,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -116,7 +116,6 @@ int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
 void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
 int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
 int  nxagentCreatePicture(PicturePtr, Mask);
-void nxagentDestroyPicture(PicturePtr pPicture);
 void nxagentChangePicture(PicturePtr, Mask);
 int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
 void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
@@ -132,6 +131,28 @@ void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
 void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
                            INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
 
+void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
+
+void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+                                           xPointFixed *p2, int nStops,
+                                               xFixed *stops,
+                                                   xRenderColor *colors);
+
+void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+                                           xPointFixed *outer,
+                                               xFixed innerRadius,
+                                                   xFixed outerRadius,
+                                                       int nStops,
+                                                           xFixed *stops,
+                                                               xRenderColor *colors);
+
+void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+                                            xPointFixed *center,
+                                                xFixed angle, int nStops, 
+                                                    xFixed *stops, 
+                                                        xRenderColor *colors);
+
+
 /*
  * The void pointer is actually a XGlyphElt8.
  */
@@ -823,8 +844,6 @@ ProcRenderFreePicture (ClientPtr client)
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
 		    RenderErrBase + BadPicture);
 
-    nxagentDestroyPicture(pPicture);
-
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -926,9 +945,16 @@ ProcRenderComposite (ClientPtr client)
 		    RenderErrBase + BadPicture);
     VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
 		  RenderErrBase + BadPicture);
+/*
+FIXME: Imported change from newest version of Xorg. Changed pSrc to pDst.
+
     if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
 	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
 	return BadMatch;
+*/
+    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
 
     ValidatePicture (pSrc);
     if (pMask)
@@ -2336,6 +2362,11 @@ static int ProcRenderCreateSolidFill(ClientPtr client)
     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2367,6 +2398,12 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
+                                          stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2397,6 +2434,14 @@ static int ProcRenderCreateRadialGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
+                                          stuff->inner_radius,
+                                              stuff->outer_radius, 
+                                                  stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2426,6 +2471,13 @@ static int ProcRenderCreateConicalGradient (ClientPtr client)
                                              stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
+                                           stuff->angle, stuff->nStops, stops,
+                                               colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index de2df855f..562cd2c66 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -35,7 +35,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
@@ -116,7 +116,6 @@ int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
 void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
 int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
 int  nxagentCreatePicture(PicturePtr, Mask);
-void nxagentDestroyPicture(PicturePtr pPicture);
 void nxagentChangePicture(PicturePtr, Mask);
 int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
 void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
@@ -132,6 +131,28 @@ void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
 void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
                            INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
 
+void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
+
+void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+                                           xPointFixed *p2, int nStops,
+                                               xFixed *stops,
+                                                   xRenderColor *colors);
+
+void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+                                           xPointFixed *outer,
+                                               xFixed innerRadius,
+                                                   xFixed outerRadius,
+                                                       int nStops,
+                                                           xFixed *stops,
+                                                               xRenderColor *colors);
+
+void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+                                            xPointFixed *center,
+                                                xFixed angle, int nStops, 
+                                                    xFixed *stops, 
+                                                        xRenderColor *colors);
+
+
 /*
  * The void pointer is actually a XGlyphElt8.
  */
@@ -823,8 +844,6 @@ ProcRenderFreePicture (ClientPtr client)
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
 		    RenderErrBase + BadPicture);
 
-    nxagentDestroyPicture(pPicture);
-
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -926,9 +945,16 @@ ProcRenderComposite (ClientPtr client)
 		    RenderErrBase + BadPicture);
     VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
 		  RenderErrBase + BadPicture);
+/*
+FIXME: Imported change from newest version of Xorg. Changed pSrc to pDst.
+
     if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
 	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
 	return BadMatch;
+*/
+    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
 
     ValidatePicture (pSrc);
     if (pMask)
@@ -2336,6 +2362,11 @@ static int ProcRenderCreateSolidFill(ClientPtr client)
     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2367,6 +2398,12 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
+                                          stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2397,6 +2434,14 @@ static int ProcRenderCreateRadialGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
+                                          stuff->inner_radius,
+                                              stuff->outer_radius, 
+                                                  stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2426,6 +2471,13 @@ static int ProcRenderCreateConicalGradient (ClientPtr client)
                                              stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
+                                           stuff->angle, stuff->nStops, stops,
+                                               colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
index 91e03cb0e..8c69217e7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index 91e03cb0e..8c69217e7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index a6d638ea7..b99cbe3e3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index a6d638ea7..b99cbe3e3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
index 24dad322f..4022bc397 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
index 24dad322f..4022bc397 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
index 15fdd9ff3..aa902226e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
index 15fdd9ff3..aa902226e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
index d35ac4ec1..5955f1705 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
index 497fa2511..e7dee27b1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
index 81c479233..80419d871 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/screensaver b/nx-X11/programs/Xserver/hw/nxagent/screensaver
index b9408a2b7..4c5c10620 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/screensaver
+++ b/nx-X11/programs/Xserver/hw/nxagent/screensaver
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2003 NoMachine, http://www.nomachine.com.          */
+/* Copyright (c) 2001, 2010 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      */
@@ -9,7 +9,7 @@
 /*                                                                        */
 /* Check http://www.nomachine.com/licensing.html for applicability.       */
 /*                                                                        */
-/* NX and NoMachine are trademarks of NoMachine S.r.l.                    */
+/* NX and NoMachine are trademarks of Medialogic S.p.A.                   */
 /*                                                                        */
 /* All rights reserved.                                                   */
 /*                                                                        */
-- 
cgit v1.2.3


From 25af86cd3aaa61dc4a3d69825aa523177c2229e1 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:57 +0200
Subject: Imported nxagent-3.4.0-16.tar.gz

Summary: Imported nxagent-3.4.0-16.tar.gz
Keywords:

Imported nxagent-3.4.0-16.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Agent.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |  15 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |  32 +--
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  59 +++++
 nx-X11/programs/Xserver/hw/nxagent/Client.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Client.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 284 ++++++++++----------
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |   3 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.c    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.h    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GC.c            |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCs.h           |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Icons.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  14 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/LICENSE         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Literals.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c    |   2 +-
 .../Xserver/hw/nxagent/NXdispatch.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c    |   2 +-
 .../Xserver/hw/nxagent/NXdixfonts.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXevents.c      |   2 +-
 .../Xserver/hw/nxagent/NXevents.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXextension.c   |   2 +-
 .../Xserver/hw/nxagent/NXextension.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c       |   2 +-
 .../Xserver/hw/nxagent/NXglyph.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c   |   2 +-
 .../Xserver/hw/nxagent/NXglyphcurs.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h    |   2 +-
 .../Xserver/hw/nxagent/NXglyphstr.h.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c     |   2 +-
 .../Xserver/hw/nxagent/NXmiglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c     |   2 +-
 .../Xserver/hw/nxagent/NXpicture.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h  |   2 +-
 .../Xserver/hw/nxagent/NXpicturestr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c    |   2 +-
 .../Xserver/hw/nxagent/NXproperty.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c       |   2 +-
 .../Xserver/hw/nxagent/NXrandr.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrender.c      |   2 +-
 .../Xserver/hw/nxagent/NXrender.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c      |   2 +-
 .../Xserver/hw/nxagent/NXwindow.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmap.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        |  12 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      |  56 +++-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        | 195 +++++++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |  10 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/TestExt.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Utils.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Window.c        | 285 +++++++++++++++++++--
 nx-X11/programs/Xserver/hw/nxagent/Windows.h       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXdamage.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXdixfonts.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c |   2 +-
 .../Xserver/hw/nxagent/X/NXextension.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXglxext.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h  |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphstr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiexpose.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c   |   2 +-
 .../Xserver/hw/nxagent/X/NXmiglyph.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXmitrap.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiwindow.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c   |   7 +-
 .../Xserver/hw/nxagent/X/NXpicture.c.NX.original   |   7 +-
 .../programs/Xserver/hw/nxagent/X/NXpicturestr.h   |   2 +-
 .../hw/nxagent/X/NXpicturestr.h.NX.original        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXrandr.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   2 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXwindow.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXxvdisp.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/os2Stub.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/screensaver     |   2 +-
 160 files changed, 943 insertions(+), 339 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Agent.h b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
index 3f2c93fdb..dbed1e0d8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Agent.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index c2e58bd58..8fbb275a6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -562,11 +562,15 @@ int ddxProcessArgument(int argc, char *argv[], int i)
       if (!strcmp(argv[i],"fullscreen"))
       {
         nxagentChangeOption(Fullscreen, True);
+
+        nxagentChangeOption(AllScreens, True);
       }
       else if (!strcmp(argv[i],"ipaq"))
       {
         nxagentChangeOption(Fullscreen, True);
 
+        nxagentChangeOption(AllScreens, True);
+
         nxagentIpaq = True;
       }
       else
@@ -1071,10 +1075,14 @@ static void nxagentParseOptions(char *name, char *value)
     else if (!strcmp(value, "1"))
     {
       nxagentChangeOption(Fullscreen, True);
+
+      nxagentChangeOption(AllScreens, True);
     }
     else if (!strcmp(value, "0"))
     {
       nxagentChangeOption(Fullscreen, False);
+
+      nxagentChangeOption(AllScreens, False);
     }
     else
     {
@@ -1680,6 +1688,11 @@ N/A
       nxagentChangeOption(Fullscreen, False);
     }
 
+    if (nxagentOption(AllScreens) == UNDEFINED)
+    {
+      nxagentChangeOption(AllScreens, False);
+    }
+
     if (nxagentOption(Binder) == UNDEFINED)
     {
       nxagentChangeOption(Binder, False);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
index 92650a4a0..9cb97ca03 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
index 171df95a9..578731f07 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -66,21 +66,21 @@ Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
 static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
 {
-  "NX_IDENTITY",              /* 0  */
-  "WM_PROTOCOLS",             /* 1  */
-  "WM_DELETE_WINDOW",         /* 2  */
-  "WM_NX_READY",              /* 3  */
-  "MCOPGLOBALS",              /* 4  */
-  "NX_CUT_BUFFER_SERVER",     /* 5  */
-  "TARGETS",                  /* 6  */
-  "TEXT",                     /* 7  */
-  "NX_AGENT_SIGNATURE",       /* 8  */
-  "NXDARWIN",                 /* 9  */
-  "CLIPBOARD",                /* 10 */
-  "TIMESTAMP",                /* 11 */
-  "UTF8_STRING",              /* 12 */
-  "_NET_WM_STATE",            /* 13 */
-  "_NET_WM_STATE_FULLSCREEN", /* 14 */
+  "NX_IDENTITY",                 /* 0  */
+  "WM_PROTOCOLS",                /* 1  */
+  "WM_DELETE_WINDOW",            /* 2  */
+  "WM_NX_READY",                 /* 3  */
+  "MCOPGLOBALS",                 /* 4  */
+  "NX_CUT_BUFFER_SERVER",        /* 5  */
+  "TARGETS",                     /* 6  */
+  "TEXT",                        /* 7  */
+  "NX_AGENT_SIGNATURE",          /* 8  */
+  "NXDARWIN",                    /* 9  */
+  "CLIPBOARD",                   /* 10 */
+  "TIMESTAMP",                   /* 11 */
+  "UTF8_STRING",                 /* 12 */
+  "_NET_WM_STATE",               /* 13 */
+  "_NET_WM_STATE_FULLSCREEN",    /* 14 */
   NULL,
   NULL
 };
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
index f49f2751e..d5b7fe5aa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.c b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
index 34433bd2b..d40aaebe6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.h b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
index e0da3e357..f28a82b9f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 3f0a6abcd..64e41b8cc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,64 @@
 ChangeLog:
 
+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.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
index acfaab7c0..63ed0e134 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
index 45f87fc66..a9b06c845 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index eb830234d..2742e147f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
index 2750ddfd2..43189df81 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
index 259aa3b24..b0f0507b5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
index 8321e8038..b2960590c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
index b0640ff11..c79104fc1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.h b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
index fb1d6d8e9..e875d0051 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
index 141ba3a64..9ed7c233f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
index 11e407efd..df7dc44f7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
index 2f807b1dc..0fb9491a4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
index aa845c7c2..bd12f3097 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index 1a57788e6..87be98116 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h
index 35b7857ad..454150d6e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 75057097a..9c167743f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
index 146610efb..c987fa119 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.c b/nx-X11/programs/Xserver/hw/nxagent/Error.c
index 963cfa287..43bf85900 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.h b/nx-X11/programs/Xserver/hw/nxagent/Error.h
index 2d6083d4e..e55fd71a5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 1576962fb..b9da934d6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -205,8 +205,6 @@ CARD32 nxagentLastEventTime     = 0;
 CARD32 nxagentLastKeyPressTime  = 0;
 Time   nxagentLastServerTime    = 0;
 
-int nxagentPointerAndKeyboardGrabbed = 0;
-
 /*
  * Used for storing windows that need to
  * receive expose events from the agent.
@@ -806,6 +804,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
   Bool startKbd = False;
   Bool closeSession = False;
   Bool switchFullscreen = False;
+  Bool switchAllScreens = False;
 
   /*
    * Last entered top level window.
@@ -990,6 +989,12 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
             break;
           }
+          case doSwitchAllScreens:
+          {
+            switchAllScreens = TRUE;
+
+            break;
+          }
           case doViewportMoveUp:
           {
             nxagentMoveViewport(pScreen, 0, -nxagentOption(Height));
@@ -1193,23 +1198,6 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
         nxagentInputEvent = 1;
 
-        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
-        {
-          x.u.u.type = ButtonPress;
-          x.u.u.detail = inputInfo.pointer -> button -> map[3];
-          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
-
-          mieqEnqueue(&x);
-
-          x.u.u.type = ButtonRelease;
-          x.u.u.detail = inputInfo.pointer -> button -> map[3];
-          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
-
-          mieqEnqueue(&x);
-
-          break;
-        }
-
         if (nxagentOption(Fullscreen))
         {
           if (nxagentMagicPixelZone(X.xbutton.x, X.xbutton.y))
@@ -1313,11 +1301,6 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
         nxagentInputEvent = 1;
 
-        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
-        {
-          break;
-        }
-
         if (viewportCursor)
         {
           /*
@@ -1688,14 +1671,11 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           nxagentScreenTrap = 0;
         }
 
-        if (nxagentOption(Fullscreen) == 1)
+        if (nxagentOption(Fullscreen) == 1 &&
+                X.xcrossing.window == nxagentFullscreenWindow &&
+                    X.xcrossing.detail != NotifyInferior)
         {
-          if (X.xcrossing.window == nxagentDefaultWindows[0] &&
-                  X.xcrossing.detail != NotifyInferior &&
-                      X.xcrossing.mode == NotifyNormal)
-          {
-            nxagentGrabPointerAndKeyboard(&X);
-          }
+          nxagentGrabPointerAndKeyboard(&X);
         }
 
         if (X.xcrossing.detail != NotifyInferior)
@@ -2002,7 +1982,8 @@ FIXME: Don't enqueue the KeyRelease event if the key was
         }
 
         if (nxagentUseNXTrans == 1 && nxagentOption(Rootless) == 0 &&
-                nxagentOption(Nested) == 0)
+                nxagentOption(Nested) == 0 &&
+                    X.xmap.window != nxagentIconWindow)
         {
           nxagentVisibility = VisibilityFullyObscured;
         }
@@ -2041,6 +2022,15 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           }
         }
 
+        if (nxagentOption(AllScreens) == 1)
+        {
+          if (X.xmap.window == nxagentIconWindow)
+          {
+            pScreen = nxagentScreen(X.xmap.window);
+            nxagentMaximizeToFullScreen(pScreen);
+          }
+        }
+
         if (nxagentOption(Fullscreen) == 1)
         {
           nxagentVisibility = VisibilityUnobscured;
@@ -2136,14 +2126,40 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
     if (nxagentWMIsRunning)
     {
-      XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
-                         DefaultScreen(nxagentDisplay));
+      if (nxagentOption(AllScreens))
+      {
+        nxagentMinimizeFromFullScreen(pScreen);
+      }
+      else
+      {
+        XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
+                           DefaultScreen(nxagentDisplay));
+      }
     }
   }
 
   if (switchFullscreen)
   {
-    nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
+    if (nxagentOption(AllScreens) == 1 && nxagentOption(Fullscreen) == 1)
+    {
+      nxagentSwitchAllScreens(pScreen, 0);
+    }
+    else
+    {
+      nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
+    }
+  }
+
+  if (switchAllScreens)
+  {
+    if (nxagentOption(AllScreens) == 0 && nxagentOption(Fullscreen) == 1)
+    {
+      nxagentSwitchFullscreen(pScreen, 0);
+    }
+    else
+    {
+      nxagentSwitchAllScreens(pScreen, !nxagentOption(AllScreens));
+    }
   }
 
   if (startKbd)
@@ -2615,6 +2631,7 @@ int nxagentHandleGraphicsExposeEvent(XEvent *X)
 
 int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
 {
+  ScreenPtr pScreen;
   WindowPtr pWin;
   xEvent x;
 
@@ -2730,8 +2747,20 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         fprintf(stderr, "Events: WM_DELETE_WINDOW arrived Atom = %ld.\n", wmAtom);
         #endif
 
-        if (X -> xclient.window == nxagentDefaultWindows[0] ||
-                nxagentWMIsRunning == 0)
+        if (X -> xclient.window == nxagentIconWindow)
+        {
+          pScreen = nxagentScreen(X -> xmap.window);
+
+          XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+          XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                             DefaultScreen(nxagentDisplay));
+
+        }
+
+        if (X -> xclient.window == (nxagentOption(Fullscreen) ?
+                nxagentIconWindow : nxagentDefaultWindows[0]) ||
+                    nxagentWMIsRunning == 0)
         {
           *result = doCloseSession;
         }
@@ -3328,110 +3357,113 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
     if (X -> xconfigure.window == nxagentDefaultWindows[pScreen -> myNum])
     {
-      if (nxagentOption(DesktopResize) == 1)
+      if (nxagentOption(AllScreens) == 0)
       {
-        if (nxagentOption(Width) != X -> xconfigure.width ||
-              nxagentOption(Height) != X -> xconfigure.height)
+        if (nxagentOption(DesktopResize) == 1)
         {
-          Bool newEvents = False;
+          if (nxagentOption(Width) != X -> xconfigure.width ||
+                nxagentOption(Height) != X -> xconfigure.height)
+          {
+            Bool newEvents = False;
 
-          doRandR = True;
+            doRandR = True;
 
-          NXFlushDisplay(nxagentDisplay, NXFlushLink);
+            NXFlushDisplay(nxagentDisplay, NXFlushLink);
 
-          do
-          {
-            newEvents = False;
+            do
+            {
+              newEvents = False;
 
-            timeout.tv_sec  = 0;
-            timeout.tv_usec = 500 * 1000;
+              timeout.tv_sec  = 0;
+              timeout.tv_usec = 500 * 1000;
 
-            nxagentWaitEvents(nxagentDisplay, &timeout);
+              nxagentWaitEvents(nxagentDisplay, &timeout);
 
-            /*
-             * This should also flush
-             * the NX link for us.
-             */
+              /*
+               * This should also flush
+               * the NX link for us.
+               */
 
-            XSync(nxagentDisplay, 0);
+              XSync(nxagentDisplay, 0);
 
-            while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
-                                            ConfigureNotify, X))
-            {
-              newEvents = True;
-            }
+              while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+                                              ConfigureNotify, X))
+              {
+                newEvents = True;
+              }
 
-          } while (newEvents);
+            } while (newEvents);
+          }
         }
-      }
 
-      if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
-      {
-        nxagentChangeOption(X, X -> xconfigure.x);
-        nxagentChangeOption(Y, X -> xconfigure.y);
-      }
+        if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
+        {
+          nxagentChangeOption(X, X -> xconfigure.x);
+          nxagentChangeOption(Y, X -> xconfigure.y);
+        }
 
-      if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
-              (nxagentOption(Width) != X -> xconfigure.width ||
-                  nxagentOption(Height) != X -> xconfigure.height))
-      {
-        nxagentShadowResize = 1;
-      }
+        if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
+                (nxagentOption(Width) != X -> xconfigure.width ||
+                    nxagentOption(Height) != X -> xconfigure.height))
+        {
+          nxagentShadowResize = 1;
+        }
 
-      nxagentChangeOption(Width, X -> xconfigure.width);
-      nxagentChangeOption(Height, X -> xconfigure.height);
+        nxagentChangeOption(Width, X -> xconfigure.width);
+        nxagentChangeOption(Height, X -> xconfigure.height);
 
-      nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
-                              (int) nxagentOption(RootWidth));
-      nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
-                              (int) nxagentOption(RootHeight));
+        nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
+                                (int) nxagentOption(RootWidth));
+        nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
+                                (int) nxagentOption(RootHeight));
 
-      nxagentMoveViewport(pScreen, 0, 0);
+        nxagentMoveViewport(pScreen, 0, 0);
 
-      if (nxagentOption(Shadow) == 1 ||
-              (nxagentOption(Width) == nxagentOption(RootWidth) &&
-                  nxagentOption(Height) == nxagentOption(RootHeight)))
-      {
-        doRandR = 0;
-      }
+        if (nxagentOption(Shadow) == 1 ||
+                (nxagentOption(Width) == nxagentOption(RootWidth) &&
+                    nxagentOption(Height) == nxagentOption(RootHeight)))
+        {
+          doRandR = 0;
+        }
 
-      nxagentChangeOption(Width, X -> xconfigure.width);
-      nxagentChangeOption(Height, X -> xconfigure.height);
+        nxagentChangeOption(Width, X -> xconfigure.width);
+        nxagentChangeOption(Height, X -> xconfigure.height);
 
-      XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
-                            X -> xconfigure.width, X -> xconfigure.height);
+        XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+                              X -> xconfigure.width, X -> xconfigure.height);
 
-      if (nxagentOption(Fullscreen) == 0)
-      {
-        nxagentMoveViewport(pScreen, 0, 0);
-      }
-      else
-      {
-        nxagentChangeOption(RootX, (nxagentOption(Width) -
-                                nxagentOption(RootWidth)) / 2);
-        nxagentChangeOption(RootY, (nxagentOption(Height) -
-                                nxagentOption(RootHeight)) / 2);
-        nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
-                                nxagentOption(RootWidth));
-        nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
-                                nxagentOption(RootHeight));
-
-        nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
-                                       nxagentOption(RootHeight));
-
-        XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
-                        nxagentOption(RootX), nxagentOption(RootY));
-      }
+        if (nxagentOption(Fullscreen) == 0)
+        {
+          nxagentMoveViewport(pScreen, 0, 0);
+        }
+        else
+        {
+          nxagentChangeOption(RootX, (nxagentOption(Width) -
+                                  nxagentOption(RootWidth)) / 2);
+          nxagentChangeOption(RootY, (nxagentOption(Height) -
+                                  nxagentOption(RootHeight)) / 2);
+          nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
+                                  nxagentOption(RootWidth));
+          nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
+                                  nxagentOption(RootHeight));
+
+          nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
+                                         nxagentOption(RootHeight));
+
+          XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                          nxagentOption(RootX), nxagentOption(RootY));
+        }
 
-      if (doRandR)
-      {
-        #ifdef TEST
-        fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
-                    nxagentOption(Width), nxagentOption(Height));
-        #endif
+        if (doRandR)
+        {
+          #ifdef TEST
+          fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
+                      nxagentOption(Width), nxagentOption(Height));
+          #endif
 
-        nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
-                                   nxagentOption(Width), nxagentOption(Height));
+          nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
+                                     nxagentOption(Width), nxagentOption(Height));
+        }
       }
 
       return 1;
@@ -3800,11 +3832,6 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
 
   int result;
 
-  if (nxagentPointerAndKeyboardGrabbed == 1)
-  {
-    return;
-  }
-
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Grabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
@@ -3867,19 +3894,12 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
     XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
                        RevertToParent, now);
   }
-
-  nxagentPointerAndKeyboardGrabbed = 1;
 }
 
 void nxagentUngrabPointerAndKeyboard(XEvent *X)
 {
   unsigned long now;
 
-  if (nxagentPointerAndKeyboardGrabbed == 0)
-  {
-    return;
-  }
-
   #ifdef TEST
   fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Ungrabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
@@ -3905,8 +3925,6 @@ void nxagentUngrabPointerAndKeyboard(XEvent *X)
   #endif
 
   XUngrabPointer(nxagentDisplay, now);
-
-  nxagentPointerAndKeyboardGrabbed = 0;
 }
 
 void nxagentDeactivatePointerGrab()
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index 109475c16..c74fa151f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -33,6 +33,7 @@ enum HandleEventResult
   doCloseSession,
   doStartKbd,
   doSwitchFullscreen,
+  doSwitchAllScreens,
   doViewportMoveUp,
   doViewportMoveLeft,
   doViewportMoveRight,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
index e76cbb4ad..aced24ff4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
index 620645d00..5335cf87c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index 13b819322..5e58b792b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.h b/nx-X11/programs/Xserver/hw/nxagent/Font.h
index 75ae3f6f5..63cb6aa24 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GC.c b/nx-X11/programs/Xserver/hw/nxagent/GC.c
index c53e3b9f7..71562d999 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GC.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GC.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index 85730797e..e18b034eb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
index 7ae6d9923..fa4967aee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCs.h b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
index bec290088..f7e13477a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCs.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index be407f160..310b572cc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
index fe8aeef36..3d3b335c0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.c b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
index a9ac77c09..bfd907cde 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.h b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
index 9896aeead..c39b98780 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Icons.h b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
index 4d0e216cd..0601584d4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Icons.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index e8405ed3a..e499b7a11 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.h b/nx-X11/programs/Xserver/hw/nxagent/Image.h
index 7805b0312..57272ab18 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 64b6583bf..789ff3446 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
index 576c1a74d..cf154e86d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index b0aeabeea..8db38892e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index 1a953358a..0e11a8a13 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index de1da8654..6c6e477ab 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -116,7 +116,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       {
         if (nxagentOption(Rootless) == False)
         {
-          *result = doSwitchFullscreen;
+          *result = doSwitchAllScreens;
         }
 
         break;
@@ -282,6 +282,16 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
   {
     switch (sym)
     {
+      case XK_f:
+      case XK_F:
+      {
+        if (nxagentOption(Rootless) == 0)
+        {
+          *result = doSwitchFullscreen;
+        }
+
+        break;
+      }
       case XK_Left:
       case XK_KP_Left:
       {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index e9ca59ff2..ef71a8851 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/LICENSE b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
index 141ca13ea..8446e6f55 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/LICENSE
+++ b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2001, 2010 NoMachine - http://www.nomachine.com/.
+Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/.
 
 NXAGENT and NX extensions to X are copyright of NoMachine.
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
index 377dd7e25..aaa3430d6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Literals.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.c b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
index bde85f090..e9c739eeb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.h b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
index 2125eca3e..69d247bbc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index 5106ffa8c..4f59b8098 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
index 5106ffa8c..4f59b8098 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
index 0d8584218..1cccfd972 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
index 0d8584218..1cccfd972 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
index cd8ced7a6..f697cf3ca 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
index cd8ced7a6..f697cf3ca 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
index 852ad1503..1d86bf870 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
index 852ad1503..1d86bf870 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
index 55248195f..22483b3fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
index 55248195f..22483b3fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
index 614d2db39..9212bf438 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
index 614d2db39..9212bf438 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
index 08ffb35b0..0f122be4a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
index 08ffb35b0..0f122be4a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
index 806cf2900..09901ba9c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
index 806cf2900..09901ba9c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
index a9c501b34..d32cdb6c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
index a9c501b34..d32cdb6c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
index 26a95fe9f..91eab0125 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
index 26a95fe9f..91eab0125 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
index 14b6136d4..20a6bd6dc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
index 14b6136d4..20a6bd6dc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
index b7039e1e0..d593fa6aa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
index b7039e1e0..d593fa6aa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
index 0940a3602..43607ac08 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
index 0940a3602..43607ac08 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
index 0954cf8ae..95ecde951 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
index 0954cf8ae..95ecde951 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
index 8d05175ff..37b2c74fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
index 4e800e96d..160dc6517 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
index ae3a03d86..97ae77e29 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index 1f04b0daf..5d7855667 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index 1bc7eaa4c..7850a0586 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -102,6 +102,13 @@ typedef struct _AgentOptions
 
   int Fullscreen;
 
+  /*
+   * True if the fullscreen NX session will
+   * extend on all available screens.
+   */
+
+  int AllScreens;
+
   /*
    * Set to the auto-disconnect timeout, if
    * the user activated this feature.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
index 10c705dfc..d3ab9dd2f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
index ea7c375ee..918d74dc7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
index 1718c7363..ad7e9c313 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
index 234650dd4..98d5666d1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
index 9c1bfaace..a751974af 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
index b0bb3f99c..3b9ccce15 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index e63b481b2..b78660240 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
index 12d0742df..c321bfada 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index 4f0f76474..6c74c147f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -584,16 +584,16 @@ XRenderPictFormat *nxagentMatchingFormats(PictFormatPtr pFormat)
 
 void nxagentDestroyPicture(PicturePtr pPicture)
 {
+  if (pPicture == NULL || nxagentPicturePriv(pPicture) -> picture == 0)
+  {
+    return;
+  }
+
   #ifdef TEST
   fprintf(stderr, "nxagentDestroyPicture: Going to destroy picture at [%p].\n",
               (void *) pPicture);
   #endif
 
-  if (pPicture == NULL)
-  {
-    return;
-  }
-
   XRenderFreePicture(nxagentDisplay,
                      nxagentPicturePriv(pPicture) -> picture);
   
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
index 4346a4e1e..6f61ca85f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index 612e71cf7..706aa9320 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -725,7 +725,57 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     }
     else
     {
-      XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX, format, mode, (void*)output, nUnits);
+      #ifdef TEST
+      fprintf(stderr, "nxagentExportProperty: Property [%lu] format [%i] "
+                  "units [%lu].\n", propertyX, format, nUnits);
+      #endif
+
+      if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
+              (MAX_REQUEST_SIZE << 2))
+      {
+        XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX,
+                            format, mode, (void*)output, nUnits);
+      }
+      else if (mode == PropModeReplace)
+      {
+        int n;
+        char *data;
+
+        XDeleteProperty(nxagentDisplay, nxagentWindow(pWin), propertyX);
+
+        data = (char *) output;
+
+        while (nUnits > 0)
+        {
+          if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
+                  (MAX_REQUEST_SIZE << 2))
+          {
+            n = nUnits;
+          }
+          else
+          {
+            n = ((MAX_REQUEST_SIZE << 2) - sizeof(xChangePropertyReq)) /
+                    (format >> 3);
+          }
+
+          XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX,
+                              typeX, format, PropModeAppend, (void*) data, n);
+
+          nUnits -= n;
+
+          data = (char *) data + n * (format >> 3);
+        }
+      }
+      else
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentExportProperty: WARNING! "
+                    "Property [%lu] too long.\n", propertyX);
+        #endif
+
+        goto nxagentExportPropertyError;
+      }
+
       nxagentAddPropertyToList(propertyX, pWin);
     }
   }
@@ -740,6 +790,8 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     #endif
   }
 
+  nxagentExportPropertyError:
+
   if (freeMem)
   {
     xfree(output);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
index ece4c9d31..1ea258db3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 2db7df8fe..0a0d409eb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -160,6 +160,7 @@ void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
 
 #endif
 
+Window nxagentIconWindow = None;
 Window nxagentFullscreenWindow = None;
 
 #ifdef VIEWPORT_FRAME
@@ -287,6 +288,166 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
   }
 }
 
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
+{
+  XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
+
+  if (nxagentIpaq)
+  {
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+  }
+  else
+  {
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+  }
+}
+
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
+{
+  if (nxagentIpaq)
+  {
+    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+
+    XMapWindow(nxagentDisplay, nxagentFullscreenWindow);
+  }
+  else
+  {
+/*
+    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+/*
+FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWindow()
+       in order to avoid the session window is iconified.
+       We could avoid the sesssion window is iconified when a LeaveNotify event is received,
+       so this check would be unnecessary.
+*/
+    struct timeval timeout;
+    int i;
+    XEvent e;
+
+    XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
+                        RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
+
+    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
+      #endif
+
+      if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
+      {
+        break;
+      }
+
+      XSync(nxagentDisplay, 0);
+
+      timeout.tv_sec = 0;
+      timeout.tv_usec = 50 * 1000;
+
+      nxagentWaitEvents(nxagentDisplay, &timeout);
+    }
+
+    XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+
+    while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
+/*
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+  }
+}
+
+Window nxagentCreateIconWindow()
+{
+  XSetWindowAttributes attributes;
+  unsigned long valuemask;
+  char* window_name;
+  XTextProperty windowName;
+  XSizeHints sizeHints;
+  XWMHints wmHints;
+  Window w;
+  Mask mask;
+
+  /*
+   * Create icon window.
+   */
+
+  attributes.override_redirect = False;
+  attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
+  attributes.background_pixmap = nxagentScreenSaverPixmap;
+  valuemask = CWOverrideRedirect | CWBackPixmap | CWColormap;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateIconWindow: Going to create new icon window.\n");
+  #endif
+
+  w = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                        0, 0, 1, 1, 0,
+                            DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+                                InputOutput,
+                                    DefaultVisual(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+                                        valuemask, &attributes);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateIconWindow: Created new icon window with id [%ld].\n",
+              nxagentIconWindow);
+  #endif
+
+  /*
+   *  Set hints to the window manager for the icon window.
+   */
+
+  window_name = nxagentWindowName;
+  XStringListToTextProperty(&window_name, 1, &windowName);
+  sizeHints.flags = PMinSize | PMaxSize;
+  sizeHints.min_width = sizeHints.max_width = 1;
+  sizeHints.min_height = sizeHints.max_height = 1;
+  wmHints.flags = IconPixmapHint | IconMaskHint;
+  wmHints.initial_state = IconicState;
+  wmHints.icon_pixmap = nxagentIconPixmap;
+
+  if (useXpmIcon)
+  {
+    wmHints.icon_mask = nxagentIconShape;
+    wmHints.flags = IconPixmapHint | IconMaskHint;
+  }
+  else
+  {
+    wmHints.flags = StateHint | IconPixmapHint;
+  }
+
+  XSetWMProperties(nxagentDisplay, w,
+                      &windowName, &windowName,
+                          NULL , 0 , &sizeHints, &wmHints, NULL);
+
+  /*
+   * Enable events from the icon window.
+   */
+
+  nxagentGetDefaultEventMask(&mask);
+
+  XSelectInput(nxagentDisplay, w, (mask & ~(KeyPressMask |
+                   KeyReleaseMask)) | StructureNotifyMask);
+
+  /*
+   * Notify to client if user closes icon window.
+   */
+
+  if (nxagentWMIsRunning && !nxagentOption(Rootless))
+  {
+    XlibAtom deleteWMAtom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
+
+    XSetWMProtocols(nxagentDisplay, w, &deleteWMAtom, 1);
+  }
+
+  return w;
+}
+
 Bool nxagentMagicPixelZone(int x, int y)
 {
   return (x >= nxagentOption(Width) - 1 && y < 1);
@@ -816,6 +977,8 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
 
     nxagentChangeOption(Fullscreen, False);
 
+    nxagentChangeOption(AllScreens, False);
+
     nxagentFullscreenWindow = 0;
 
     resetAgentPosition = True;
@@ -1221,6 +1384,11 @@ N/A
       nxagentChangeOption(Height, gattributes.height);
     }
 
+    if (nxagentOption(AllScreens))
+    {
+      attributes.override_redirect = True; 
+    }
+
     if (nxagentOption(Fullscreen))
     {
       /*
@@ -1448,7 +1616,8 @@ N/A
   if (nxagentDoFullGeneration == 1 ||
           nxagentReconnectTrap == 1)
   {
-    valuemask = CWBackPixel | CWEventMask | CWColormap;
+    valuemask = CWBackPixel | CWEventMask | CWColormap |
+                    (nxagentOption(AllScreens) == 1 ? CWOverrideRedirect : 0);
 
     attributes.background_pixel = nxagentBlackPixel;
 
@@ -1456,6 +1625,11 @@ N/A
 
     attributes.colormap = nxagentDefaultVisualColormap(nxagentDefaultVisual(pScreen));
 
+    if (nxagentOption(AllScreens) == 1)
+    {
+      attributes.override_redirect = True;
+    }
+
     if (nxagentOption(Fullscreen) == 1)
     {
       if (nxagentReconnectTrap)
@@ -1635,6 +1809,21 @@ N/A
 
     XClearWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
 
+    if (nxagentOption(AllScreens))
+    {
+      if (nxagentReconnectTrap)
+      {
+        XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, True, GrabModeAsync,
+                      GrabModeAsync, CurrentTime);
+      }
+
+      nxagentIconWindow = nxagentCreateIconWindow();
+    }
+    else
+    {
+      nxagentIconWindow = 0;
+    }
+
     /*
      * When we don't have window manager we grab keyboard
      * to let nxagent get keyboard events.
@@ -1983,8 +2172,6 @@ Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
   int oldMmWidth;
   int oldMmHeight;
 
-  RegionPtr pRootWinSize;
-
   #ifdef TEST
   nxagentPrintAgentGeometry("Before Resize Screen", "nxagentResizeScreen:");
   #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 1ab6caad2..5b1957755 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -47,6 +47,8 @@ extern ScreenPtr nxagentDefaultScreen;
 
 extern Pixmap nxagentPixmapLogo;
 
+extern Window nxagentIconWindow;
+
 extern Window nxagentFullscreenWindow;
 
 extern RegionRec nxagentShadowUpdateRegion;
@@ -87,6 +89,12 @@ extern int nxagentBitsPerPixel(int depth);
 
 void nxagentSetScreenSaverTime(void);
 
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
+
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
+
+Window nxagentCreateIconWindow(void);
+
 Bool nxagentMagicPixelZone(int x, int y);
 
 Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
index 24dbf1413..235c48c23 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.h b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
index 86920ad8b..f7ba6c2e2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.c b/nx-X11/programs/Xserver/hw/nxagent/Split.c
index bf7f705b9..4cc2ea607 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.h b/nx-X11/programs/Xserver/hw/nxagent/Split.h
index 60be29b39..2be449a18 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
index 1d5fdee20..6bce2eaeb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
index 22de3bc1b..f5e6bde0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
index aa6937e70..9258e3b67 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Utils.h b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
index 830b2753f..f5bd55d8b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Utils.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.c b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
index f38931677..b086c0e9a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.h b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
index c682f92dd..8436f79ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 2da21b91c..3e6d41d04 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -693,7 +693,6 @@ void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 {
   XEvent e;
-  XSizeHints sizeHints;
 
   if (nxagentOption(Rootless) == 1)
   {
@@ -731,27 +730,6 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 
   nxagentChangeOption(Fullscreen, switchOn);
 
-  if (nxagentOption(DesktopResize) == 1)
-  {
-    sizeHints.flags = PSize;
-
-    if (switchOn == 1)
-    {
-      sizeHints.width =
-          WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
-      sizeHints.height =
-          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
-    }
-    else
-    {
-      sizeHints.width = nxagentOption(RootWidth);
-      sizeHints.height = nxagentOption(RootHeight);
-    }
-
-    XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
-                         &sizeHints);
-  }
-
   memset(&e, 0, sizeof(e));
 
   e.xclient.type = ClientMessage;
@@ -779,6 +757,245 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
   } 
 }
 
+void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
+{
+  Window w;
+  XSetWindowAttributes attributes;
+  unsigned long valuemask;
+
+  if (nxagentOption(Rootless))
+  {
+    return;
+  }
+
+  if (!switchOn)
+  {
+    nxagentWMDetect();
+
+    if (!nxagentWMIsRunning)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "Warning: Can't switch to window mode, no window manager has been detected.\n");
+      #endif
+
+      return;
+    }
+  }
+
+  w = nxagentDefaultWindows[pScreen -> myNum];
+  attributes.override_redirect = switchOn;
+  valuemask = CWOverrideRedirect;
+  XUnmapWindow(nxagentDisplay, w);
+  XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+
+  XReparentWindow(nxagentDisplay, w, DefaultRootWindow(nxagentDisplay), 0, 0);
+
+  if (switchOn)
+  {
+    /*
+     * Change to fullscreen mode.
+     */
+
+    struct timeval timeout;
+    int i;
+    XEvent e;
+
+    /*
+     * Wait for window manager reparenting the default window.
+     */
+
+    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Going to wait for the ReparentNotify event.\n");
+      #endif
+
+      if (XCheckTypedWindowEvent(nxagentDisplay, w, ReparentNotify, &e))
+      {
+        break;
+      }
+
+      /*
+       * This should also flush
+       * the NX link for us.
+       */
+
+      XSync(nxagentDisplay, 0);
+
+      timeout.tv_sec  = 0;
+      timeout.tv_usec = 50 * 1000;
+
+      nxagentWaitEvents(nxagentDisplay, &timeout);
+    }
+
+    if (i < 100)
+    {
+      /*
+       * The window manager has done with the reparent
+       * operation. We can resize and map the window.
+       */
+
+      nxagentChangeOption(Fullscreen, True);
+      nxagentChangeOption(AllScreens, True);
+      
+
+      /*
+       * Save the window-mode configuration.
+       */
+
+      nxagentChangeOption(SavedX, nxagentOption(X));
+      nxagentChangeOption(SavedY, nxagentOption(Y));
+      nxagentChangeOption(SavedWidth, nxagentOption(Width));
+      nxagentChangeOption(SavedHeight, nxagentOption(Height));
+      nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
+      nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+      /*
+       * Reconf the Default window.
+       */
+
+      nxagentChangeOption(X, 0);
+      nxagentChangeOption(Y, 0);
+      nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+      nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+      /*
+       * Move the root window.
+       */
+
+      nxagentChangeOption(RootX, (nxagentOption(Width) - nxagentOption(RootWidth)) / 2);
+      nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) / 2);
+      nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+      nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+      XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+                            nxagentOption(Width), nxagentOption(Height));
+
+      nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight));
+
+      XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                      nxagentOption(RootX), nxagentOption(RootY));
+
+      /*
+       * We disable the screensaver when changing
+       * mode to fullscreen. Is it really needed?
+       */
+
+      XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+
+      if (nxagentIconWindow == None)
+      {
+        nxagentIconWindow = nxagentCreateIconWindow();
+
+        XMapWindow(nxagentDisplay, nxagentIconWindow);
+      }
+
+      XMapRaised(nxagentDisplay, w);
+      XSetInputFocus(nxagentDisplay, w, RevertToParent, CurrentTime);
+      XCheckTypedWindowEvent(nxagentDisplay, w, LeaveNotify, &e);
+      nxagentFullscreenWindow = w;
+
+      if (nxagentOption(DesktopResize) == 1)
+      {
+        if (nxagentOption(Shadow) == 0)
+        {
+          nxagentRRSetScreenConfig(pScreen, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+                                       HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+        }
+        else
+        {
+          nxagentShadowAdaptToRatio();
+        }
+      }
+    }
+    else
+    {
+      /*
+       * We have waited for a reparent event unsuccessfully.
+       * Something happened to the window manager.
+       */
+
+      #ifdef WARNING
+      fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Expected ReparentNotify event missing.\n");
+      #endif
+ 
+      nxagentWMIsRunning = False;
+      attributes.override_redirect = False;
+      XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+      XMapWindow(nxagentDisplay, w);
+    }
+  }
+  else
+  {
+    /*
+     * FIXME:
+     * It could be necessary:
+     * - To restore screensaver.
+     * - To set or reset nxagentForceBackingStore flag.
+     * - To propagate device settings to the X server if no WM is running.
+     */
+
+    /*
+     * Change to windowed mode.
+     */
+
+    nxagentChangeOption(Fullscreen, False);
+    nxagentChangeOption(AllScreens, False);
+
+    XDestroyWindow(nxagentDisplay, nxagentIconWindow);
+
+    nxagentIconWindow = nxagentFullscreenWindow = None;
+
+    if (nxagentOption(DesktopResize) == 1)
+    {
+      nxagentChangeOption(RootWidth, nxagentOption(SavedRootWidth));
+      nxagentChangeOption(RootHeight, nxagentOption(SavedRootHeight));
+
+      if (nxagentOption(Shadow) == 0)
+      {
+        nxagentRRSetScreenConfig(pScreen, nxagentOption(RootWidth), nxagentOption(RootHeight));
+      }
+    }
+
+    if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0)
+    {
+      nxagentChangeOption(X, nxagentOption(SavedX) -
+                              nxagentOption(WMBorderWidth));
+      nxagentChangeOption(Y, nxagentOption(SavedY) -
+                              nxagentOption(WMTitleHeight));
+    }
+    else
+    {
+      nxagentChangeOption(X, nxagentOption(SavedX));
+      nxagentChangeOption(Y, nxagentOption(SavedY));
+    }
+
+    nxagentChangeOption(Width, nxagentOption(SavedWidth));
+    nxagentChangeOption(Height, nxagentOption(SavedHeight));
+
+    if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1)
+    {
+      nxagentShadowAdaptToRatio();
+    }
+
+    XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+                          nxagentOption(Width), nxagentOption(Height));
+
+    nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height));
+
+    XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), 0, 0);
+    XMapWindow(nxagentDisplay, w);
+
+    nxagentChangeOption(RootX, 0);
+    nxagentChangeOption(RootY, 0);
+  }
+
+  XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+                        nxagentOption(Width), nxagentOption(Height));
+
+  nxagentSetPrintGeometry(pScreen -> myNum); 
+}
+
 #ifdef VIEWPORT_FRAME
 
 void nxagentUpdateViewportFrame(int x, int y, int w, int h)
@@ -2281,7 +2498,7 @@ void nxagentMapDefaultWindows()
 
         if (nxagentOption(Fullscreen) == 1 && nxagentWMIsRunning == 1)
         {
-          nxagentSwitchFullscreen(pScreen, 1);
+          nxagentMaximizeToFullScreen(pScreen);
         }
       }
 
@@ -2312,6 +2529,26 @@ void nxagentMapDefaultWindows()
                            nxagentDefaultWindows[i], CurrentTime);
   }
 
+  /*
+   * Map the icon window.
+   */
+
+  if (nxagentIconWindow != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
+                nxagentIconWindow);
+    #endif
+
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+
+    if (nxagentIpaq != 0)
+    {
+      XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                         DefaultScreen(nxagentDisplay));
+    }
+  }
+
   /*
    * Ensure that the fullscreen window gets the focus.
    */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
index 6fc97b341..3ca74ba8e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Windows.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -222,6 +222,8 @@ void nxagentSetTopLevelEventMask(WindowPtr pWin);
 
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn);
 
+void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn);
+
 void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift);
 
 #ifdef VIEWPORT_FRAME
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
index 7bc1c74cb..cf5d48ba2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
index 7bc1c74cb..cf5d48ba2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index ba4e1e662..69ad30d2d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index ba4e1e662..69ad30d2d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
index 225ecdaf8..04fc047fc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
index 225ecdaf8..04fc047fc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index 8e87d58c4..c5593adbb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index 8e87d58c4..c5593adbb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
index 6e67b7ffe..ead9b9d28 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
index 6e67b7ffe..ead9b9d28 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
index 172252b32..51c547984 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
index 172252b32..51c547984 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index 6340de537..cd65fdc0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index 6340de537..cd65fdc0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
index d6cd96631..7a1d813b3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
index d6cd96631..7a1d813b3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
index e78a1bf14..fa6b5fb02 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
index e78a1bf14..fa6b5fb02 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
index c71ea8142..3fc73cf3b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
index c71ea8142..3fc73cf3b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
index efb295861..5f32334ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
index efb295861..5f32334ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
index d2bead0bc..f418654b4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
index d2bead0bc..f418654b4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
index be1096c6c..190294979 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
index be1096c6c..190294979 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
index be961c400..d9054b4b6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -873,6 +873,9 @@ AllocatePicture (ScreenPtr  pScreen)
 	else
 	    ppriv->ptr = (pointer)NULL;
     }
+
+    nxagentPicturePriv(pPicture) -> picture = 0;
+
     return pPicture;
 }
 
@@ -1103,6 +1106,8 @@ static PicturePtr createSourcePicture(void)
       ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
 
       pPicture -> devPrivates = ppriv;
+
+      nxagentPicturePriv(pPicture) -> picture = 0;
     }
 
     pPicture->pDrawable = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
index be961c400..d9054b4b6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -873,6 +873,9 @@ AllocatePicture (ScreenPtr  pScreen)
 	else
 	    ppriv->ptr = (pointer)NULL;
     }
+
+    nxagentPicturePriv(pPicture) -> picture = 0;
+
     return pPicture;
 }
 
@@ -1103,6 +1106,8 @@ static PicturePtr createSourcePicture(void)
       ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
 
       pPicture -> devPrivates = ppriv;
+
+      nxagentPicturePriv(pPicture) -> picture = 0;
     }
 
     pPicture->pDrawable = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
index b6cee91f1..0d1a8e1d8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
index b6cee91f1..0d1a8e1d8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
index d02f3f015..cd1ec6ddd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
index d02f3f015..cd1ec6ddd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
index e1bb44148..5f460f23e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
index e1bb44148..5f460f23e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index 562cd2c66..89e790135 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index 562cd2c66..89e790135 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
index 8c69217e7..d1c8325f2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index 8c69217e7..d1c8325f2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index b99cbe3e3..eaaa92041 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index b99cbe3e3..eaaa92041 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
index 4022bc397..76e86fd2a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
index 4022bc397..76e86fd2a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
index aa902226e..f6dad312a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
index aa902226e..f6dad312a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
index 5955f1705..dd8be6cb3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
index e7dee27b1..854e0a611 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
index 80419d871..9ec7e6bc8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/screensaver b/nx-X11/programs/Xserver/hw/nxagent/screensaver
index 4c5c10620..ef7cd661a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/screensaver
+++ b/nx-X11/programs/Xserver/hw/nxagent/screensaver
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
-- 
cgit v1.2.3


From d30ef0340e759378964b75e8143625ecaea245b0 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:58 +0200
Subject: Imported nxagent-3.4.0-3.tar.gz

Summary: Imported nxagent-3.4.0-3.tar.gz
Keywords:

Imported nxagent-3.4.0-3.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Agent.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |  19 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |  30 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       | 165 ------
 nx-X11/programs/Xserver/hw/nxagent/Client.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Client.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 603 ++-------------------
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |   8 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.c    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.h    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GC.c            |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCs.h           |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |   5 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Icons.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Imakefile       |   3 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  78 +--
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/LICENSE         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Literals.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c    |   2 +-
 .../Xserver/hw/nxagent/NXdispatch.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c    |   2 +-
 .../Xserver/hw/nxagent/NXdixfonts.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXevents.c      |   2 +-
 .../Xserver/hw/nxagent/NXevents.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXextension.c   |   2 +-
 .../Xserver/hw/nxagent/NXextension.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c       |   2 +-
 .../Xserver/hw/nxagent/NXglyph.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c   |   2 +-
 .../Xserver/hw/nxagent/NXglyphcurs.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h    |   2 +-
 .../Xserver/hw/nxagent/NXglyphstr.h.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c     |   2 +-
 .../Xserver/hw/nxagent/NXmiglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c     |   2 +-
 .../Xserver/hw/nxagent/NXpicture.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h  |   2 +-
 .../Xserver/hw/nxagent/NXpicturestr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c    |   2 +-
 .../Xserver/hw/nxagent/NXproperty.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c       |   2 +-
 .../Xserver/hw/nxagent/NXrandr.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrender.c      |   2 +-
 .../Xserver/hw/nxagent/NXrender.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c      |   2 +-
 .../Xserver/hw/nxagent/NXwindow.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |   8 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |  12 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.h        |  20 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmap.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.c       |  36 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.h       |  11 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        | 293 +---------
 nx-X11/programs/Xserver/hw/nxagent/Render.h        |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      |  99 +---
 nx-X11/programs/Xserver/hw/nxagent/Rootless.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        | 130 ++++-
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/TestExt.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Utils.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Window.c        | 152 +-----
 nx-X11/programs/Xserver/hw/nxagent/Windows.h       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXdamage.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |  28 +-
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |  28 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXdixfonts.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c |   2 +-
 .../Xserver/hw/nxagent/X/NXextension.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXglxext.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h  |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphstr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiexpose.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c   |   2 +-
 .../Xserver/hw/nxagent/X/NXmiglyph.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXmitrap.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiwindow.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c   |  54 +-
 .../Xserver/hw/nxagent/X/NXpicture.c.NX.original   |  54 +-
 .../programs/Xserver/hw/nxagent/X/NXpicturestr.h   |   2 +-
 .../hw/nxagent/X/NXpicturestr.h.NX.original        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXrandr.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |  60 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |  60 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   2 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXwindow.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXxvdisp.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/os2Stub.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/screensaver     |   2 +-
 161 files changed, 382 insertions(+), 1866 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Agent.h b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
index dbed1e0d8..13f87c96e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Agent.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 8fbb275a6..0588f43d6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -562,15 +562,11 @@ int ddxProcessArgument(int argc, char *argv[], int i)
       if (!strcmp(argv[i],"fullscreen"))
       {
         nxagentChangeOption(Fullscreen, True);
-
-        nxagentChangeOption(AllScreens, True);
       }
       else if (!strcmp(argv[i],"ipaq"))
       {
         nxagentChangeOption(Fullscreen, True);
 
-        nxagentChangeOption(AllScreens, True);
-
         nxagentIpaq = True;
       }
       else
@@ -1075,14 +1071,10 @@ static void nxagentParseOptions(char *name, char *value)
     else if (!strcmp(value, "1"))
     {
       nxagentChangeOption(Fullscreen, True);
-
-      nxagentChangeOption(AllScreens, True);
     }
     else if (!strcmp(value, "0"))
     {
       nxagentChangeOption(Fullscreen, False);
-
-      nxagentChangeOption(AllScreens, False);
     }
     else
     {
@@ -1216,7 +1208,7 @@ static void nxagentParseOptions(char *name, char *value)
     {
       nxagentChangeOption(ClientOs, ClientOsSolaris);
     }
-    else if (strcmp(value, "macosx") == 0)
+    else if (strcmp(value, "mac") == 0)
     {
       nxagentChangeOption(ClientOs, ClientOsMac);
     }
@@ -1520,7 +1512,7 @@ N/A
       int splitMode = 0;
       int splitSize = 0;
 
-      unsigned int packMethod = PACK_NONE;
+      unsigned int packMethod  = PACK_NONE;
       unsigned int packQuality = 9;
 
       int dataLevel   = 0;
@@ -1688,11 +1680,6 @@ N/A
       nxagentChangeOption(Fullscreen, False);
     }
 
-    if (nxagentOption(AllScreens) == UNDEFINED)
-    {
-      nxagentChangeOption(AllScreens, False);
-    }
-
     if (nxagentOption(Binder) == UNDEFINED)
     {
       nxagentChangeOption(Binder, False);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
index 9cb97ca03..2aac8e387 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
index 578731f07..13f9b8082 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -66,21 +66,19 @@ Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
 static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
 {
-  "NX_IDENTITY",                 /* 0  */
-  "WM_PROTOCOLS",                /* 1  */
-  "WM_DELETE_WINDOW",            /* 2  */
-  "WM_NX_READY",                 /* 3  */
-  "MCOPGLOBALS",                 /* 4  */
-  "NX_CUT_BUFFER_SERVER",        /* 5  */
-  "TARGETS",                     /* 6  */
-  "TEXT",                        /* 7  */
-  "NX_AGENT_SIGNATURE",          /* 8  */
-  "NXDARWIN",                    /* 9  */
-  "CLIPBOARD",                   /* 10 */
-  "TIMESTAMP",                   /* 11 */
-  "UTF8_STRING",                 /* 12 */
-  "_NET_WM_STATE",               /* 13 */
-  "_NET_WM_STATE_FULLSCREEN",    /* 14 */
+  "NX_IDENTITY",          /* 0  */
+  "WM_PROTOCOLS",         /* 1  */
+  "WM_DELETE_WINDOW",     /* 2  */
+  "WM_NX_READY",          /* 3  */
+  "MCOPGLOBALS",          /* 4  */
+  "NX_CUT_BUFFER_SERVER", /* 5  */
+  "TARGETS",              /* 6  */
+  "TEXT",                 /* 7  */
+  "NX_AGENT_SIGNATURE",   /* 8  */
+  "NXDARWIN",             /* 9  */
+  "CLIPBOARD",            /* 10 */
+  "TIMESTAMP",            /* 11 */
+  "UTF8_STRING",          /* 12 */
   NULL,
   NULL
 };
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
index d5b7fe5aa..842b820db 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -22,7 +22,7 @@
 #include "../../include/window.h"
 #include "screenint.h"
 
-#define NXAGENT_NUMBER_OF_ATOMS  16
+#define NXAGENT_NUMBER_OF_ATOMS  14
 
 extern Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.c b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
index d40aaebe6..4fb5224fb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.h b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
index f28a82b9f..c4daeea8c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 64e41b8cc..4e964d0ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,170 +1,5 @@
 ChangeLog:
 
-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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
index 63ed0e134..b0db1df0f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
index a9b06c845..4b12ed127 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 2742e147f..442b1c871 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
index 43189df81..5a592a4da 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
index b0f0507b5..d9a979a42 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
index b2960590c..a8e225460 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
index c79104fc1..44bab3cf9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.h b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
index e875d0051..c5dede9eb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
index 9ed7c233f..7e4385712 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
index df7dc44f7..7b4e6beac 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
index 0fb9491a4..c6f8a9104 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
index bd12f3097..5c71fad87 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index 87be98116..c1a80b391 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h
index 454150d6e..4c04c5ba8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 9c167743f..ddd7f13ca 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
index c987fa119..6ce0e3156 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.c b/nx-X11/programs/Xserver/hw/nxagent/Error.c
index 43bf85900..2a8173019 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.h b/nx-X11/programs/Xserver/hw/nxagent/Error.h
index e55fd71a5..f7a53cbd1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index b9da934d6..83665ff90 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -76,9 +76,7 @@
 #include "input.h"
 #endif
 
-#define Time XlibXID
 #include "XKBlib.h"
-#undef Time
 
 #define GC     XlibGC
 #define Font   XlibFont
@@ -220,16 +218,6 @@ static void nxagentForwardRemoteExpose(void);
 
 static int nxagentClipAndSendExpose(WindowPtr pWin, pointer ptr);
 
-/*
- * This is from NXproperty.c.
- */
-
-int GetWindowProperty(WindowPtr pWin, Atom property, long longOffset,
-                          long longLength, Bool delete, Atom type,
-                              Atom *actualType, int *format, unsigned
-                                  long *nItems, unsigned long *bytesAfter,
-                                      unsigned char **propData);
-
 /*
  * Associate a resource to a drawable and
  * store the region affected by the split
@@ -286,280 +274,6 @@ void ProcessInputEvents()
   mieqProcessInputEvents();
 }
 
-#ifdef DEBUG_TREE
-
-/*
- * Print ID and name of window.
- */
-
-void nxagentRemoteWindowID(Window window, Bool newline)
-{
-#ifdef NO_I18N
-    char *winName;
-#else
-    XTextProperty tp;
-#endif
-
-  fprintf(stderr, "0x%lx", window);
-
-  if (!window)
-  {
-    fprintf(stderr, " (none) ");
-  }
-  else
-  {
-    if (window == DefaultRootWindow(nxagentDisplay))
-    {
-      fprintf(stderr, " (the root window) ");
-    }
-
-#ifdef NO_I18N
-
-    if (!XFetchName(nxagentDisplay, window, &winName))
-    {
-      fprintf(stderr, " (has no name) ");
-    }
-    else if (winName)
-    {
-      fprintf(stderr, " \"%s\" ", winName);
-      XFree(winName);
-    }
-
-#else
-
-    if (XGetWMName(nxagentDisplay, window, &tp) != 0)
-    {
-      fprintf(stderr, " (has no name) ");
-    }
-    else if (tp.nitems > 0)
-    {
-      int count = 0;
-      int i, ret;
-      char **list = NULL;
-
-      fprintf(stderr, " \"");
-
-      ret = XmbTextPropertyToTextList(nxagentDisplay, &tp, &list, &count);
-
-      if ((ret == Success || ret > 0) && list != NULL)
-      {
-        for (i = 0; i < count; i++)
-        {
-          fprintf(stderr, "%s", list[i]);
-        }
-
-        XFreeStringList(list);
-      }
-      else
-      {
-        fprintf(stderr, "%s", tp.value);
-      }
-
-      fprintf(stderr, "\" ");
-    }
-
-#endif
-
-    else
-    {
-      fprintf(stderr, " (has no name) ");
-    }
-  }
-
-  if (newline == TRUE)
-  {
-    fprintf(stderr, "\n");
-  }
-
-  return;
-}
-
-/*
- * Print info about remote window.
- */
-
-void nxagentRemoteWindowInfo(Window win, int indent, Bool newLine)
-{
-  XWindowAttributes attributes;
-  int i;
-
-  if (XGetWindowAttributes(nxagentDisplay, win, &attributes) == 0)
-  {
-    return;
-  }
-
-  for (i = 0; i < indent; i++)
-  {
-    fprintf(stderr, " ");
-  }
-
-  fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
-             "override_redirect=%s\n", attributes.x, attributes.y,
-                 attributes.width, attributes.height, (attributes.class == 0) ?
-                     "InputOutput" : "InputOnly", (attributes.map_state == 0) ?
-                         "IsUnmapped" : (attributes.map_state == 1 ?
-                             "IsUnviewable" : "IsViewable"),
-                                 (attributes.override_redirect == 0) ?
-                                     "No" : "Yes" );
-
-  if (newLine == TRUE)
-  {
-    fprintf(stderr, "\n");
-  }
-}
-
-/*
- * Walk remote windows tree.
- */
-
-void nxagentRemoteWindowsTree(Window window, int level)
-{
-  int i, j;
-  Window rootWin, parentWin;
-  unsigned int numChildren;
-  Window *childList;
-
-  if (!XQueryTree(nxagentDisplay, window, &rootWin, &parentWin, &childList,
-                      &numChildren))
-  {
-    fprintf(stderr, "nxagentRemoteWindowsTree - XQueryTree failed.\n");
-
-    return;
-  }
-
-  if (level == 0)
-  {
-    fprintf(stderr, "\n");
-
-    fprintf(stderr, "  Root Window ID: ");
-    nxagentRemoteWindowID(rootWin, TRUE);
-
-    fprintf(stderr, "  Parent window ID: ");
-    nxagentRemoteWindowID(parentWin, TRUE);
-  }
-
-  if (level == 0 || numChildren > 0)
-  {
-    fprintf(stderr, "     ");
-
-    for (j = 0; j < level; j++)
-    {
-      fprintf(stderr, "    ");
-    }
-
-    fprintf(stderr, "%d child%s%s\n", numChildren, (numChildren == 1) ? "" :
-               "ren", (numChildren == 1) ? ":" : ".");
-  }
-
-  for (i = (int) numChildren - 1; i >= 0; i--)
-  {
-    fprintf(stderr, "      ");
-
-    for (j = 0; j < level; j++)
-    {
-      fprintf(stderr, "     ");
-    }
-
-    nxagentRemoteWindowID(childList[i], TRUE);
-
-    nxagentRemoteWindowInfo(childList[i], (level * 5) + 6, TRUE);
-
-    nxagentRemoteWindowsTree(childList[i], level + 1);
-  }
-
-  if (childList)
-  {
-    XFree((char *) childList);
-  }
-}
-
-/*
- * Print info about internal window.
- */
-
-void nxagentInternalWindowInfo(WindowPtr pWin, int indent, Bool newLine)
-{
-  int i;
-  int result;
-  unsigned long ulReturnItems;
-  unsigned long ulReturnBytesLeft;
-  Atom          atomReturnType;
-  int           iReturnFormat;
-  unsigned char *pszReturnData = NULL;
-
-  fprintf(stderr, "Window ID=[0x%lx] Remote ID=[0x%lx] ", pWin -> drawable.id,
-             nxagentWindow(pWin));
-
-  result = GetWindowProperty(pWin, MakeAtom("WM_NAME", 7, False) , 0,
-                                sizeof(CARD32), False, AnyPropertyType,
-                                    &atomReturnType, &iReturnFormat,
-                                        &ulReturnItems, &ulReturnBytesLeft,
-                                            &pszReturnData);
-
-  fprintf(stderr, "Name: ");
-
-  if (result == Success && pszReturnData != NULL)
-  {
-    pszReturnData[ulReturnItems] = '\0';
-
-    fprintf(stderr, "\"%s\"\n", (char *) pszReturnData);
-  }
-  else
-  {
-    fprintf(stderr, "%s\n", "( has no name )");
-  }
-
-  for (i = 0; i < indent; i++)
-  {
-    fprintf(stderr, " ");
-  }
-
-  fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
-             "override_redirect=%s", pWin -> drawable.x, pWin -> drawable.y,
-                 pWin -> drawable.width, pWin -> drawable.height,
-                     (pWin -> drawable.class == 0) ? "InputOutput" :
-                         "InputOnly", (pWin -> mapped == 0) ?
-                             "IsUnmapped" : (pWin -> mapped == 1 ?
-                                 "IsUnviewable" : "IsViewable"),
-                                     (pWin -> overrideRedirect == 0) ?
-                                         "No" : "Yes");
-
-  if (newLine == TRUE)
-  {
-    fprintf(stderr, "\n");
-  }
-}
-
-/*
- * Walk internal windows tree.
- */
-
-void nxagentInternalWindowsTree(WindowPtr pWin, int indent)
-{
-  WindowPtr pChild;
-  int i;
-
-  while (pWin)
-  {
-    pChild = pWin -> firstChild;
-
-    for (i = 0; i < indent; i++)
-    {
-      fprintf(stderr, " ");
-    }
-
-    nxagentInternalWindowInfo(pWin, indent, TRUE);
-
-    fprintf(stderr, "\n");
-
-    nxagentInternalWindowsTree(pChild, indent + 4);
-
-    pWin = pWin -> nextSib;
-  }
-}
-
-#endif /* DEBUG_TREE */
-
 void nxagentSwitchResizeMode(ScreenPtr pScreen)
 {
   XSizeHints sizeHints;
@@ -576,14 +290,8 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentLaunchDialog(DIALOG_DISABLE_DESKTOP_RESIZE_MODE);
 
-    if (nxagentOption(Fullscreen) == 0)
-    {
-      sizeHints.max_width = nxagentOption(RootWidth);
-      sizeHints.max_height = nxagentOption(RootHeight);
-
-      XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
-                            &sizeHints);
-    }
+    sizeHints.max_width = nxagentOption(RootWidth);
+    sizeHints.max_height = nxagentOption(RootHeight);
   }
   else
   {
@@ -591,8 +299,7 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentLaunchDialog(DIALOG_ENABLE_DESKTOP_RESIZE_MODE);
 
-    nxagentRRSetScreenConfig(pScreen, nxagentOption(Width),
-                                 nxagentOption(Height));
+    nxagentRRSetScreenConfig(pScreen, nxagentOption(Width), nxagentOption(Height));
 
     if (nxagentOption(ClientOs) == ClientOsWinnt)
     {
@@ -601,10 +308,10 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
     sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
-
-    XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
-                          &sizeHints);
   }
+
+  XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                       &sizeHints);
 }
 
 void nxagentShadowSwitchResizeMode(ScreenPtr pScreen)
@@ -804,7 +511,6 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
   Bool startKbd = False;
   Bool closeSession = False;
   Bool switchFullscreen = False;
-  Bool switchAllScreens = False;
 
   /*
    * Last entered top level window.
@@ -949,22 +655,6 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           {
             break;
           }
-
-          #ifdef DEBUG_TREE
-
-          case doDebugTree:
-          {
-            fprintf(stderr, "\n ========== nxagentRemoteWindowsTree ==========\n");
-            nxagentRemoteWindowsTree(nxagentWindow(WindowTable[0]), 0);
-
-            fprintf(stderr, "\n========== nxagentInternalWindowsTree ==========\n");
-            nxagentInternalWindowsTree(WindowTable[0], 0);
-
-            break;
-          }
-
-          #endif /* DEBUG_TREE */
-
           case doCloseSession:
           {
             closeSession = TRUE;
@@ -989,36 +679,6 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
             break;
           }
-          case doSwitchAllScreens:
-          {
-            switchAllScreens = TRUE;
-
-            break;
-          }
-          case doViewportMoveUp:
-          {
-            nxagentMoveViewport(pScreen, 0, -nxagentOption(Height));
-
-            break;
-          }
-          case doViewportMoveDown:
-          {
-            nxagentMoveViewport(pScreen, 0, nxagentOption(Height));
-
-            break;
-          }
-          case doViewportMoveLeft:
-          {
-            nxagentMoveViewport(pScreen, -nxagentOption(Width), 0);
-
-            break;
-          }
-          case doViewportMoveRight:
-          {
-            nxagentMoveViewport(pScreen, nxagentOption(Width), 0);
-
-            break;
-          }
           case doViewportUp:
           {
             nxagentMoveViewport(pScreen, 0, -nextinc(viewportInc));
@@ -1095,8 +755,6 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow) == 1 && result == doNothing)
         {
-          X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
-
           NXShadowEvent(nxagentDisplay, X);
         }
 
@@ -1105,27 +763,6 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
       case KeyRelease:
       {
         enum HandleEventResult result;
-        int sendKey = 0;
-
-/*
-FIXME: If we don't flush the queue here, it could happen
-       that the inputInfo structure will not be up to date
-       when we perform the following check on down keys.
-*/
-        ProcessInputEvents();
-
-/*
-FIXME: Don't enqueue the KeyRelease event if the key was
-       not already pressed. This workaround avoids a fake
-       KeyPress is enqueued by the XKEYBOARD extension.
-       Another solution would be to let the events are
-       enqueued and to remove the KeyPress afterwards.
-*/
-        if (BitIsOn(inputInfo.keyboard -> key -> down,
-                       nxagentConvertKeycode(X.xkey.keycode)))
-        {
-          sendKey = 1;
-        }
 
         #ifdef TEST
         fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeyRelease event.\n");
@@ -1171,7 +808,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           x.u.keyButtonPointer.time = nxagentLastEventTime;
         }
 
-        if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)) && sendKey == 1)
+        if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)))
         {
           mieqEnqueue(&x);
 
@@ -1179,8 +816,6 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
           if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
           {
-            X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
-
             NXShadowEvent(nxagentDisplay, X);
           }
         }
@@ -1244,7 +879,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
                     X.xbutton.subwindow == None))
         {
           x.u.u.type = ButtonPress;
-          x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]];
+          x.u.u.detail = X.xbutton.button;
           x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
 
           if (nxagentOption(Rootless))
@@ -1317,7 +952,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
         if (minimize != True)
         {
           x.u.u.type = ButtonRelease;
-          x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]];
+          x.u.u.detail = X.xbutton.button;
           x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
 
           if (nxagentOption(Rootless))
@@ -1671,11 +1306,13 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           nxagentScreenTrap = 0;
         }
 
-        if (nxagentOption(Fullscreen) == 1 &&
-                X.xcrossing.window == nxagentFullscreenWindow &&
-                    X.xcrossing.detail != NotifyInferior)
+        if (nxagentOption(Fullscreen))
         {
-          nxagentGrabPointerAndKeyboard(&X);
+          if (X.xcrossing.window == nxagentFullscreenWindow &&
+                  X.xcrossing.detail != NotifyInferior)
+          {
+            nxagentGrabPointerAndKeyboard(&X);
+          }
         }
 
         if (X.xcrossing.detail != NotifyInferior)
@@ -1724,11 +1361,14 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           nxagentLastEnteredWindow = NULL;
         }
 
-        if (X.xcrossing.window == nxagentDefaultWindows[0] &&
-                X.xcrossing.detail != NotifyInferior &&
-                    X.xcrossing.mode == NotifyNormal)
+        if (nxagentOption(Fullscreen))
         {
-          nxagentUngrabPointerAndKeyboard(&X);
+          if (X.xcrossing.window == nxagentFullscreenWindow &&
+                  X.xcrossing.detail != NotifyInferior &&
+                      X.xcrossing.mode == NotifyNormal)
+          {
+            nxagentUngrabPointerAndKeyboard(&X);
+          }
         }
 
         if (X.xcrossing.detail != NotifyInferior)
@@ -1982,8 +1622,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
         }
 
         if (nxagentUseNXTrans == 1 && nxagentOption(Rootless) == 0 &&
-                nxagentOption(Nested) == 0 &&
-                    X.xmap.window != nxagentIconWindow)
+                nxagentOption(Nested) == 0 && X.xmap.window != nxagentIconWindow)
         {
           nxagentVisibility = VisibilityFullyObscured;
         }
@@ -2022,17 +1661,14 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           }
         }
 
-        if (nxagentOption(AllScreens) == 1)
+        if (nxagentOption(Fullscreen) == 1)
         {
           if (X.xmap.window == nxagentIconWindow)
           {
             pScreen = nxagentScreen(X.xmap.window);
             nxagentMaximizeToFullScreen(pScreen);
           }
-        }
 
-        if (nxagentOption(Fullscreen) == 1)
-        {
           nxagentVisibility = VisibilityUnobscured;
           nxagentVisibilityStop = False;
           nxagentVisibilityTimeout = GetTimeInMillis() + 2000;
@@ -2042,17 +1678,10 @@ FIXME: Don't enqueue the KeyRelease event if the key was
       }
       case MappingNotify:
       {
-        XMappingEvent *mappingEvent = (XMappingEvent *) &X;
-
         #ifdef DEBUG
         fprintf(stderr, "nxagentDispatchEvents: WARNING! Going to handle new MappingNotify event.\n");
         #endif
 
-        if (mappingEvent -> request == MappingPointer)
-        {
-            nxagentInitPointerMap();
-        }
-
         break;
       }
       default:
@@ -2126,40 +1755,20 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
     if (nxagentWMIsRunning)
     {
-      if (nxagentOption(AllScreens))
+      if (nxagentOption(Fullscreen))
       {
         nxagentMinimizeFromFullScreen(pScreen);
       }
       else
       {
-        XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
-                           DefaultScreen(nxagentDisplay));
+        XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0], DefaultScreen(nxagentDisplay));
       }
     }
   }
 
   if (switchFullscreen)
   {
-    if (nxagentOption(AllScreens) == 1 && nxagentOption(Fullscreen) == 1)
-    {
-      nxagentSwitchAllScreens(pScreen, 0);
-    }
-    else
-    {
-      nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
-    }
-  }
-
-  if (switchAllScreens)
-  {
-    if (nxagentOption(AllScreens) == 0 && nxagentOption(Fullscreen) == 1)
-    {
-      nxagentSwitchFullscreen(pScreen, 0);
-    }
-    else
-    {
-      nxagentSwitchAllScreens(pScreen, !nxagentOption(AllScreens));
-    }
+    nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
   }
 
   if (startKbd)
@@ -2312,16 +1921,8 @@ int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
     return 1;
   }
 
-  if (X -> xkey.keycode == 66)
-  {
-    nxagentXkbState.Caps = (~nxagentXkbState.Caps & 1);
-  }
-  else if (X -> xkey.keycode == 77)
-  {
-    nxagentXkbState.Num = (~nxagentXkbState.Num & 1);
-  }
-
   nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
+
   
   x.u.u.type = KeyPress;
   x.u.u.detail = nxagentConvertKeycode(X -> xkey.keycode);
@@ -2759,8 +2360,7 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         }
 
         if (X -> xclient.window == (nxagentOption(Fullscreen) ?
-                nxagentIconWindow : nxagentDefaultWindows[0]) ||
-                    nxagentWMIsRunning == 0)
+              nxagentIconWindow : nxagentDefaultWindows[0]))
         {
           *result = doCloseSession;
         }
@@ -3357,7 +2957,7 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
     if (X -> xconfigure.window == nxagentDefaultWindows[pScreen -> myNum])
     {
-      if (nxagentOption(AllScreens) == 0)
+      if (nxagentOption(Fullscreen) == 0)
       {
         if (nxagentOption(DesktopResize) == 1)
         {
@@ -3426,34 +3026,6 @@ int nxagentHandleConfigureNotify(XEvent* X)
           doRandR = 0;
         }
 
-        nxagentChangeOption(Width, X -> xconfigure.width);
-        nxagentChangeOption(Height, X -> xconfigure.height);
-
-        XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
-                              X -> xconfigure.width, X -> xconfigure.height);
-
-        if (nxagentOption(Fullscreen) == 0)
-        {
-          nxagentMoveViewport(pScreen, 0, 0);
-        }
-        else
-        {
-          nxagentChangeOption(RootX, (nxagentOption(Width) -
-                                  nxagentOption(RootWidth)) / 2);
-          nxagentChangeOption(RootY, (nxagentOption(Height) -
-                                  nxagentOption(RootHeight)) / 2);
-          nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
-                                  nxagentOption(RootWidth));
-          nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
-                                  nxagentOption(RootHeight));
-
-          nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
-                                         nxagentOption(RootHeight));
-
-          XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
-                          nxagentOption(RootX), nxagentOption(RootY));
-        }
-
         if (doRandR)
         {
           #ifdef TEST
@@ -3475,6 +3047,8 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
 int nxagentHandleReparentNotify(XEvent* X)
 {
+  ScreenPtr pScreen = nxagentScreen(X -> xreparent.window);
+
   #ifdef TEST
   fprintf(stderr, "nxagentHandleReparentNotify: Going to handle a new reparent event.\n");
   #endif
@@ -3527,8 +3101,6 @@ int nxagentHandleReparentNotify(XEvent* X)
           #ifdef WARNING
           fprintf(stderr, "nxagentHandleReparentNotify: WARNING! Failed QueryTree request.\n");
           #endif
-
-          break;
         }
 
         if (result && children_return)
@@ -3581,95 +3153,6 @@ int nxagentHandleReparentNotify(XEvent* X)
 
     return 1;
   }
-  else if (nxagentWMIsRunning == 1 && nxagentOption(Fullscreen) == 0 &&
-               nxagentOption(WMBorderWidth) == -1)
-  {
-    XlibWindow w;
-    XlibWindow rootReturn = 0;
-    XlibWindow parentReturn = 0;
-    XlibWindow junk;
-    XlibWindow *childrenReturn = NULL;
-    unsigned int nchildrenReturn = 0;
-    Status result;
-    XWindowAttributes attributes;
-    int x, y;
-    int xParent, yParent;
-
-    /*
-     * Calculate the absolute upper-left X e Y 
-     */
-
-    if ((XGetWindowAttributes(nxagentDisplay, X -> xreparent.window,
-                                  &attributes) == 0))
-    {
-      #ifdef WARNING
-      fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
-                  "XGetWindowAttributes failed.\n");
-      #endif
-
-      return 1;
-    }
-
-    x = attributes.x;
-    y = attributes.y;
-
-    XTranslateCoordinates(nxagentDisplay, X -> xreparent.window,
-                              attributes.root, -attributes.border_width,
-                                  -attributes.border_width, &x, &y, &junk);
-
-   /*
-    * Calculate the parent X and parent Y.
-    */
-
-    w = X -> xreparent.parent;
-
-    if (w != DefaultRootWindow(nxagentDisplay))
-    {
-      do
-      {
-        result = XQueryTree(nxagentDisplay, w, &rootReturn, &parentReturn,
-                                &childrenReturn, &nchildrenReturn);
-    
-        if (parentReturn == rootReturn || parentReturn == 0 || result == 0)
-        {
-          break;
-        }
-
-        if (result == 1 && childrenReturn != NULL)
-        {
-          XFree(childrenReturn);
-        }
-    
-        w = parentReturn;
-      }
-      while (True);
-
-      /*
-       * WM reparented. Find edge of the frame.
-       */
-
-      if (XGetWindowAttributes(nxagentDisplay, w, &attributes) == 0)
-      {
-        #ifdef WARNING
-        fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
-                    "XGetWindowAttributes failed for parent window.\n");
-        #endif
-
-        return 1;
-      }
-
-      xParent = attributes.x;
-      yParent = attributes.y;
-
-      /*
-       * Difference between Absolute X and Parent X gives thickness of side frame.
-       * Difference between Absolute Y and Parent Y gives thickness of title bar. 
-       */
-
-      nxagentChangeOption(WMBorderWidth, (x - xParent));
-      nxagentChangeOption(WMTitleHeight, (y - yParent));
-    }
-  }
 
   return 1;
 }
@@ -3830,8 +3313,6 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
 
   int resource;
 
-  int result;
-
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Grabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
@@ -3850,22 +3331,8 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n");
   #endif
 
-  result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
-                             True, GrabModeAsync, GrabModeAsync, now);
-
-  if (result != GrabSuccess)
-  {
-    return;
-  }
-
-  /*
-   * The smart scheduler could be stopped while
-   * waiting for the reply. In this case we need
-   * to yield explicitly to avoid to be stuck in
-   * the dispatch loop forever.
-   */
-
-  isItTimeToYield = 1;
+  XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
+                    True, GrabModeAsync, GrabModeAsync, now);
 
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the pointer in context [B2].\n");
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index c74fa151f..3e04222a2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -29,15 +29,9 @@ enum HandleEventResult
 {
   doNothing = 0,
   doMinimize,
-  doDebugTree,
   doCloseSession,
   doStartKbd,
   doSwitchFullscreen,
-  doSwitchAllScreens,
-  doViewportMoveUp,
-  doViewportMoveLeft,
-  doViewportMoveRight,
-  doViewportMoveDown,
   doViewportLeft,
   doViewportUp,
   doViewportRight,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
index aced24ff4..748afa53e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
index 5335cf87c..06185170e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index 5e58b792b..b14dc883b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.h b/nx-X11/programs/Xserver/hw/nxagent/Font.h
index 63cb6aa24..d95cbdc83 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GC.c b/nx-X11/programs/Xserver/hw/nxagent/GC.c
index 71562d999..55a0a0031 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GC.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GC.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index e18b034eb..d2cc58400 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
index fa4967aee..666a098bf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCs.h b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
index f7e13477a..460469696 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCs.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index 310b572cc..e43fbb931 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -527,8 +527,7 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
                 synchronize, nxagentReady);
     #endif
 
-    if (NXDisplayError(nxagentDisplay) == 0 &&
-            nxagentQueuedEvents(nxagentDisplay) > 0)
+    if (nxagentQueuedEvents(nxagentDisplay) > 0)
     {
       #ifdef WARNING
       fprintf(stderr, "nxagentBlockHandler: WARNING! Forcing a null timeout with events queued.\n");
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
index 3d3b335c0..8cf92b219 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.c b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
index bfd907cde..02fde6782 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.h b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
index c39b98780..469da223d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Icons.h b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
index 0601584d4..350e76487 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Icons.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index e499b7a11..ec7a60a96 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.h b/nx-X11/programs/Xserver/hw/nxagent/Image.h
index 57272ab18..bd6d4c948 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
index 51173e410..633e17a22 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -206,8 +206,7 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \
           -DNXAGENT_SPLASH \
           -DNXAGENT_ARTSD \
           -UNX_DEBUG_INPUT \
-          -UPANORAMIX \
-          -UDEBUG_TREE
+          -UPANORAMIX
 
 all:: $(OBJS)
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 789ff3446..f60d7c457 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -193,7 +193,7 @@ void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
   if (serverGeneration <= 1)
   {
     fprintf(stderr, "\nNXAGENT - Version " NXAGENT_VERSION "\n\n");
-    fprintf(stderr, "Copyright (C) 2001, 2010 NoMachine.\n");
+    fprintf(stderr, "Copyright (C) 2001, 2007 NoMachine.\n");
     fprintf(stderr, "See http://www.nomachine.com/ for more information.\n\n");
 
     fprintf(stderr, "Info: Agent running with pid '%d'.\n", getpid());
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
index cf154e86d..16c74ea99 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index 8db38892e..a4729e9b7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index 0e11a8a13..4c7395a43 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index 6c6e477ab..eee13db2d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -92,18 +92,6 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
   {
     switch (sym)
     {
-      #ifdef DEBUG_TREE
-
-      case XK_q:
-      case XK_Q:
-      {
-        *result = doDebugTree;
-
-        break;
-      }
-
-      #endif /* DEBUG_TREE */
-
       case XK_t:
       case XK_T:
       {
@@ -116,7 +104,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       {
         if (nxagentOption(Rootless) == False)
         {
-          *result = doSwitchAllScreens;
+          *result = doSwitchFullscreen;
         }
 
         break;
@@ -276,68 +264,6 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       #endif
     }
   }
-  else if ((X -> state & nxagentAltMetaMask) &&
-               ((X -> state & (ControlMask | ShiftMask)) == (ControlMask |
-                   ShiftMask)))
-  {
-    switch (sym)
-    {
-      case XK_f:
-      case XK_F:
-      {
-        if (nxagentOption(Rootless) == 0)
-        {
-          *result = doSwitchFullscreen;
-        }
-
-        break;
-      }
-      case XK_Left:
-      case XK_KP_Left:
-      {
-        if (nxagentOption(Rootless) == 0 &&
-                nxagentOption(DesktopResize) == 0)
-        {
-          *result = doViewportMoveLeft;
-        }
-
-        break;
-      }
-      case XK_Up:
-      case XK_KP_Up:
-      {
-        if (nxagentOption(Rootless) == 0 &&
-                nxagentOption(DesktopResize) == 0)
-        {
-          *result = doViewportMoveUp;
-        }
-
-        break;
-      }
-      case XK_Right:
-      case XK_KP_Right:
-      {
-        if (nxagentOption(Rootless) == 0 &&
-                nxagentOption(DesktopResize) == 0)
-        {
-          *result = doViewportMoveRight;
-        }
-
-        break;
-      }
-      case XK_Down:
-      case XK_KP_Down:
-      {
-        if (nxagentOption(Rootless) == 0 &&
-                nxagentOption(DesktopResize) == 0)
-        {
-          *result = doViewportMoveDown;
-        }
-
-        break;
-      }
-    }
-  }
 
   return (*result == doNothing) ? 0 : 1;
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index ef71a8851..fea97975c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/LICENSE b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
index 8446e6f55..451196c1a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/LICENSE
+++ b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/.
+Copyright (c) 2001, 2009 NoMachine - http://www.nomachine.com/.
 
 NXAGENT and NX extensions to X are copyright of NoMachine.
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
index aaa3430d6..21c27afa1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Literals.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.c b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
index e9c739eeb..e275b985f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.h b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
index 69d247bbc..9b6d879d7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index 4f59b8098..e189b9539 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
index 4f59b8098..e189b9539 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
index 1cccfd972..b57401ceb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
index 1cccfd972..b57401ceb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
index f697cf3ca..b01e4a452 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
index f697cf3ca..b01e4a452 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
index 1d86bf870..9bb868f2b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
index 1d86bf870..9bb868f2b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
index 22483b3fd..6ec64afae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
index 22483b3fd..6ec64afae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
index 9212bf438..6352c88d1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
index 9212bf438..6352c88d1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
index 0f122be4a..0874f0fef 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
index 0f122be4a..0874f0fef 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
index 09901ba9c..e0f6d1cdf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
index 09901ba9c..e0f6d1cdf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
index d32cdb6c4..95178d362 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
index d32cdb6c4..95178d362 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
index 91eab0125..90a31d36f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
index 91eab0125..90a31d36f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
index 20a6bd6dc..06d6074ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
index 20a6bd6dc..06d6074ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
index d593fa6aa..179cc1ab0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
index d593fa6aa..179cc1ab0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
index 43607ac08..a670c3521 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
index 43607ac08..a670c3521 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
index 95ecde951..a0d4cd6ee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
index 95ecde951..a0d4cd6ee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
index 37b2c74fd..a8aa254ff 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
index 160dc6517..8ceb49418 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
index 97ae77e29..727161648 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index 5d7855667..955be61bc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -63,9 +63,6 @@ void nxagentInitOptions()
   nxagentOptions.Height      = 0;
   nxagentOptions.BorderWidth = 0;
 
-  nxagentOptions.WMBorderWidth = -1;
-  nxagentOptions.WMTitleHeight = -1;
-
   nxagentOptions.SavedX      = 0;
   nxagentOptions.SavedY      = 0;
   nxagentOptions.SavedWidth  = 0;
@@ -171,9 +168,6 @@ void nxagentResetOptions()
 
   nxagentOptions.TileWidth  = UNDEFINED;
   nxagentOptions.TileHeight = UNDEFINED;
-
-  nxagentOptions.WMBorderWidth = -1;
-  nxagentOptions.WMTitleHeight = -1;
 }
 
 void nxagentSaveOptions()
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index 7850a0586..7126338a8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -102,13 +102,6 @@ typedef struct _AgentOptions
 
   int Fullscreen;
 
-  /*
-   * True if the fullscreen NX session will
-   * extend on all available screens.
-   */
-
-  int AllScreens;
-
   /*
    * Set to the auto-disconnect timeout, if
    * the user activated this feature.
@@ -133,9 +126,6 @@ typedef struct _AgentOptions
    * screen.
    */
 
-  int WMBorderWidth;
-  int WMTitleHeight;
-
   int SavedX;
   int SavedY;
   int SavedWidth;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
index d3ab9dd2f..eb8daf8f3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
index 918d74dc7..cd2df1fa6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -108,12 +108,6 @@ FIXME: The condition checking for the render
        avoid problems with the render composi-
        te on XFree86 remote server.
 */
-/*
-FIXME: Changed macro: NXAGENT_SHOULD_DEFER_COMPOSITE
-       to handle situation, when pSrc -> pDrawable
-       is NULL. This case happens with gradients
-       and solid fill.
-
 #define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)                 \
     ((nxagentRenderVersionMajor == 0 &&                                   \
      nxagentRenderVersionMinor == 8 &&                                \
@@ -124,18 +118,6 @@ FIXME: Changed macro: NXAGENT_SHOULD_DEFER_COMPOSITE
           nxagentOption(DeferLevel) == 1) ||               \
              (nxagentOption(DeferLevel) >= 2 &&           \
               nxagentOption(LinkType) < LINK_TYPE_ADSL))
-*/
-#define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)                                                \
-    ((nxagentRenderVersionMajor == 0 &&                                                                  \
-      nxagentRenderVersionMinor == 8 &&                                                                  \
-      (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP) ||                                                 \
-         (nxagentOption(DeferLevel) >= 2 &&                                                              \
-          nxagentOption(LinkType) < LINK_TYPE_ADSL) ||                                                   \
-             (nxagentOption(DeferLevel) == 1 &&                                                          \
-              (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP &&                                          \
-              (((pSrc) -> pDrawable && nxagentDrawableStatus((pSrc) -> pDrawable) == NotSynchronized) || \
-              ((pMask) && nxagentDrawableStatus((pMask) -> pDrawable) == NotSynchronized))))
-
 
 #define NXAGENT_SHOULD_DEFER_PUTIMAGE(pDrawable) \
     (nxagentSplitTrap == 0 &&                    \
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
index ad7e9c313..9a4776192 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
index 98d5666d1..93df4d444 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
index a751974af..8a6702d18 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -57,13 +57,6 @@ is" without express or implied warranty.
 #undef  TEST
 #undef  DEBUG
 
-/*
- * The nxagentReversePointerMap array is used to
- * memorize remote display pointer map.
- */
-
-unsigned char nxagentReversePointerMap[MAXBUTTONS];
-
 void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl)
 {
   /*
@@ -132,8 +125,6 @@ int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
         return Success;
       }
 
-      nxagentInitPointerMap();
-
       nxagentEnablePointerEvents();
 
       break;
@@ -164,28 +155,3 @@ int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
 
   return Success;
 }
-
-void nxagentInitPointerMap(void)
-{
-  int numButtons;
-
-  int i;
-
-  unsigned char pointerMap[MAXBUTTONS];
-
-  #ifdef DEBUG
-  fprintf(stderr, "nxagentInitPointerMap: Going to retrieve the "
-              "pointer map from remote display.\n");
-  #endif
-
-  numButtons = XGetPointerMapping(nxagentDisplay, pointerMap, MAXBUTTONS);
-
-  /*
-   * Computing revers pointer map.
-   */
-
-  for (i = 1; i <= numButtons; i++)
-  {
-    nxagentReversePointerMap[pointerMap[i - 1] - 1] = i;
-  }
-}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
index 3b9ccce15..3d8899bbe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -38,17 +38,8 @@ is" without express or implied warranty.
   (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
        EnterWindowMask | LeaveWindowMask)
 
-/*
- * The nxagentReversePointerMap array is used to
- * memorize remote display pointer map.
- */
-
-extern unsigned char nxagentReversePointerMap[MAXBUTTONS];
-
 void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl);
 
 int nxagentPointerProc(DeviceIntPtr pDev, int onoff);
 
-void nxagentInitPointerMap(void);
-
 #endif /* __Pointer_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index b78660240..c656f2912 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -81,8 +81,6 @@ extern Bool nxagentUninstallFontServerPath(void);
 
 extern void nxagentRemoveXConnection(void);
 
-extern void nxagentInitPointerMap(void);
-
 static char *nxagentGetReconnectError(void);
 
 void nxagentInitializeRecLossyLevel(void);
@@ -586,8 +584,6 @@ Bool nxagentReconnectSession(void)
     nxagentOldKeyboard = NULL;
   }
 
-  nxagentInitPointerMap();
-
   nxagentDeactivatePointerGrab();
 
   nxagentWakeupByReconnect();
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
index c321bfada..6a3b56fc7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index 6c74c147f..5c6503e64 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -147,6 +147,8 @@ void nxagentCursorPostSaveRenderInfo(CursorPtr pCursor, ScreenPtr pScreen,
 
 int nxagentCreatePicture(PicturePtr pPicture, Mask mask);
 
+void nxagentDestroyPicture(PicturePtr pPicture);
+
 int nxagentChangePictureClip(PicturePtr pPicture, int clipType, int nRects,
                                  xRectangle *rects, int xOrigin, int yOrigin);
 
@@ -584,16 +586,16 @@ XRenderPictFormat *nxagentMatchingFormats(PictFormatPtr pFormat)
 
 void nxagentDestroyPicture(PicturePtr pPicture)
 {
-  if (pPicture == NULL || nxagentPicturePriv(pPicture) -> picture == 0)
-  {
-    return;
-  }
-
   #ifdef TEST
   fprintf(stderr, "nxagentDestroyPicture: Going to destroy picture at [%p].\n",
               (void *) pPicture);
   #endif
 
+  if (pPicture == NULL)
+  {
+    return;
+  }
+
   XRenderFreePicture(nxagentDisplay,
                      nxagentPicturePriv(pPicture) -> picture);
   
@@ -1008,15 +1010,12 @@ void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pD
 
   #ifdef DEBUG
 
-  if (pSrc -> pDrawable != NULL)
-  {
-    fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
-                nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
-                (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
-                     nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
-                         pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
-                             (void *) pSrc -> pDrawable);
-  }
+  fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
+              nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
+              (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                   nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
+                       pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+                           (void *) pSrc -> pDrawable);
 
   fprintf(stderr, "nxagentComposite: Destination Picture [%lu][%p] with drawable [%s%s][%p].\n",
               nxagentPicturePriv(pDst) -> picture, (void *) pDst,
@@ -1065,19 +1064,16 @@ void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pD
    * the wrong data.
    */
 
-  if (pSrc -> pDrawable != NULL)
-  {
-    nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
+  nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
 
-    if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
-                  (void *) pSrc -> pDrawable);
-      #endif
+  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
+                (void *) pSrc -> pDrawable);
+    #endif
 
-      nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
-    }
+    nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
   }
 
   if (pDst -> pDrawable != pSrc -> pDrawable)
@@ -2815,248 +2811,3 @@ Bool nxagentDisconnectAllPicture()
   return True;
 }
 
-void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color)
-{
-  Picture id;
-
-  if (nxagentRenderEnable == False)
-  {
-    return;
-  }
-
-  #ifdef DEBUG
-
-  fprintf(stderr, "nxagentRenderCreateSolidFill: Got called.\n");
-
-  if (pPicture == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! pPicture pointer is NULL.\n");
-  }
-
-  if (color == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! color pointer is NULL.\n");
-  }
-
-  #endif /* #ifdef DEBUG */
-
-  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
-             sizeof(XRenderPictureAttributes_));
-
-  id = XRenderCreateSolidFill(nxagentDisplay, (XRenderColor *) color);
-
-  #ifdef DEBUG
-  XSync(nxagentDisplay, 0);
-  #endif
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentRenderCreateSolidFill: Created solid fill xid [%lu].\n", id);
-  #endif
-
-  nxagentPicturePriv(pPicture) -> picture = id;
-}
-
-void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
-                                           xPointFixed *p2, int nStops,
-                                               xFixed *stops,
-                                                   xRenderColor *colors)
-{
-  Picture id;
-
-  XLinearGradient linearGradient;
-
-  if (nxagentRenderEnable == False)
-  {
-    return;
-  }
-
-  #ifdef DEBUG
-
-  fprintf(stderr, "nxagentRenderCreateLinearGradient: Got called.\n");
-
-  if (pPicture == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! pPicture pointer is NULL.\n");
-  }
-
-  if (p1 == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p1 pointer is NULL.\n");
-  }
-
-  if (p2 == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p2 pointer is NULL.\n");
-  }
-
-  if (stops == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! stops pointer is NULL.\n");
-  }
-
-  if (colors == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! colors pointer is NULL.\n");
-  }
-
-  #endif /* #ifdef DEBUG */
-
-  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
-             sizeof(XRenderPictureAttributes_));
-
-  linearGradient.p1.x = (XFixed) p1 -> x;
-  linearGradient.p1.y = (XFixed) p1 -> y;
-  linearGradient.p2.x = (XFixed) p2 -> x;
-  linearGradient.p2.y = (XFixed) p2 -> y;
-
-  id = XRenderCreateLinearGradient(nxagentDisplay, &linearGradient,
-                                      (XFixed *) stops,
-                                          (XRenderColor *) colors, nStops);
-
-  #ifdef DEBUG
-  XSync(nxagentDisplay, 0);
-  #endif
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentRenderCreateLinearGradient: Created linear gradient xid [%lu].\n", id);
-  #endif
-
-  nxagentPicturePriv(pPicture) -> picture = id;
-}
-
-void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
-                                           xPointFixed *outer,
-                                               xFixed innerRadius,
-                                                   xFixed outerRadius,
-                                                       int nStops,
-                                                           xFixed *stops,
-                                                               xRenderColor *colors)
-{
-  Picture id;
-
-  XRadialGradient radialGradient;
-
-  if (nxagentRenderEnable == False)
-  {
-    return;
-  }
-
-  #ifdef DEBUG
-
-  fprintf(stderr, "nxagentRenderCreateRadialGradient: Got called.\n");
-
-  if (pPicture == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! pPicture pointer is NULL.\n");
-  }
-
-  if (inner == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! inner pointer is NULL.\n");
-  }
-
-  if (outer == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! outer pointer is NULL.\n");
-  }
-
-  if (stops == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! stops pointer is NULL.\n");
-  }
-
-  if (colors == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! colors pointer is NULL.\n");
-  }
-
-  #endif /* #ifdef DEBUG */
-
-  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
-               sizeof(XRenderPictureAttributes_));
-
-  radialGradient.inner.x = (XFixed) inner -> x;
-  radialGradient.inner.y = (XFixed) inner -> y;
-  radialGradient.inner.radius = (XFixed) innerRadius;
-  radialGradient.outer.x = (XFixed) outer -> x;
-  radialGradient.outer.y = (XFixed) outer -> y;
-  radialGradient.outer.radius = (XFixed) outerRadius;
-
-  id = XRenderCreateRadialGradient(nxagentDisplay, &radialGradient,
-                                       (XFixed *) stops,
-                                           (XRenderColor *) colors, nStops);
-
-  #ifdef DEBUG
-  XSync(nxagentDisplay, 0);
-  #endif
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentRenderCreateRadialGradient: Created radial gradient xid [%lu].\n", id);
-  #endif
-
-  nxagentPicturePriv(pPicture) -> picture = id;
-}
-
-void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
-                                            xPointFixed *center,
-                                                xFixed angle, int nStops, 
-                                                    xFixed *stops, 
-                                                        xRenderColor *colors)
-{
-  Picture id;
-
-  XConicalGradient conicalGradient;
-
-  if (nxagentRenderEnable == False)
-  {
-    return;
-  }
-
-  #ifdef DEBUG
-
-  fprintf(stderr, "nxagentRenderCreateConicalGradient: Got called.\n");
-
-  if (pPicture == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! pPicture pointer is NULL.\n");
-  }
-
-  if (center == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! center pointer is NULL.\n");
-  }
-
-  if (stops == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! stops pointer is NULL.\n");
-  }
-
-  if (colors == NULL)
-  {
-    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! colors pointer is NULL.\n");
-  }
-
-  #endif /* #ifdef DEBUG */
-
-  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
-             sizeof(XRenderPictureAttributes_));
-
-  conicalGradient.center.x = (XFixed) center -> x;
-  conicalGradient.center.y = (XFixed) center -> y;
-  conicalGradient.angle = (XFixed) angle;
-
-  id = XRenderCreateConicalGradient(nxagentDisplay, &conicalGradient,
-                                        (XFixed *) stops,
-                                            (XRenderColor *) colors, nStops);
-
-  #ifdef DEBUG
-  XSync(nxagentDisplay, 0);
-  #endif
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentRenderCreateConicalGradient: Created conical gradient xid [%lu].\n", id);
-  #endif
-
-  nxagentPicturePriv(pPicture) -> picture = id;
-}
-
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
index 6f61ca85f..77e842d16 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -105,6 +105,4 @@ void nxagentDisconnectPicture(pointer p0, XID x1, void* p2);
 
 void nxagentReconnectGlyphSet(void* p0, XID x1, void *p2);
 
-void nxagentDestroyPicture(PicturePtr pPicture);
-
 #endif /* __Render_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index 706aa9320..53f4df41e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -626,7 +626,6 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     XlibAtom *atoms = malloc(nUnits * sizeof(*atoms));
     Atom *input = value;
     int i;
-    int j = 0;
 
     freeMem = True;
     export = True;
@@ -634,40 +633,16 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
     for (i = 0; i < nUnits; i++)
     {
-      /*
-       * Exporting the _NET_WM_PING property could
-       * result in rootless windows being grayed out
-       * when the compiz window manager is running.
-       *
-       * Better solution would probably be to handle
-       * the communication with the window manager
-       * instead of just getting rid of the property.
-       */
-
-      if (strcmp(NameForAtom(input[i]), "_NET_WM_PING") != 0)
-      {
-        atoms[j] = nxagentLocalToRemoteAtom(input[i]);
-
-        if (atoms[j] == None)
-        {
-          #ifdef WARNING
-          fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
-                      (long int) input[i], validateString(NameForAtom(input[i])));
-          #endif
-        }
-
-        j++;
-      }
-      #ifdef TEST
-      else
-      {
-        fprintf(stderr, "nxagentExportProperty: WARNING! "
-                    "Not exporting the _NET_WM_PING property.\n");
-      }
-      #endif
+       atoms[i] = nxagentLocalToRemoteAtom(input[i]);
+
+       if (atoms[i] == None)
+       {
+         #ifdef WARNING
+         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
+                     (long int) input[i], validateString(NameForAtom(input[i])));
+         #endif
+       }
     }
-
-    nUnits = j;
   }
   else if (strcmp(typeS, "WINDOW") == 0)
   {
@@ -725,57 +700,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     }
     else
     {
-      #ifdef TEST
-      fprintf(stderr, "nxagentExportProperty: Property [%lu] format [%i] "
-                  "units [%lu].\n", propertyX, format, nUnits);
-      #endif
-
-      if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
-              (MAX_REQUEST_SIZE << 2))
-      {
-        XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX,
-                            format, mode, (void*)output, nUnits);
-      }
-      else if (mode == PropModeReplace)
-      {
-        int n;
-        char *data;
-
-        XDeleteProperty(nxagentDisplay, nxagentWindow(pWin), propertyX);
-
-        data = (char *) output;
-
-        while (nUnits > 0)
-        {
-          if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
-                  (MAX_REQUEST_SIZE << 2))
-          {
-            n = nUnits;
-          }
-          else
-          {
-            n = ((MAX_REQUEST_SIZE << 2) - sizeof(xChangePropertyReq)) /
-                    (format >> 3);
-          }
-
-          XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX,
-                              typeX, format, PropModeAppend, (void*) data, n);
-
-          nUnits -= n;
-
-          data = (char *) data + n * (format >> 3);
-        }
-      }
-      else
-      {
-        #ifdef WARNING
-        fprintf(stderr, "nxagentExportProperty: WARNING! "
-                    "Property [%lu] too long.\n", propertyX);
-        #endif
-
-        goto nxagentExportPropertyError;
-      }
-
+      XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX, format, mode, (void*)output, nUnits);
       nxagentAddPropertyToList(propertyX, pWin);
     }
   }
@@ -790,8 +715,6 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     #endif
   }
 
-  nxagentExportPropertyError:
-
   if (freeMem)
   {
     xfree(output);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
index 1ea258db3..5538b58ea 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 0a0d409eb..4f4160765 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -292,7 +292,7 @@ void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
 {
   XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
 
-  if (nxagentIpaq)
+  if(nxagentIpaq)
   {
     XMapWindow(nxagentDisplay, nxagentIconWindow);
     XIconifyWindow(nxagentDisplay, nxagentIconWindow,
@@ -307,7 +307,7 @@ void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
 
 void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
 {
-  if (nxagentIpaq)
+  if(nxagentIpaq)
   {
     XUnmapWindow(nxagentDisplay, nxagentIconWindow);
 
@@ -334,7 +334,7 @@ FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWind
     for (i = 0; i < 100 && nxagentWMIsRunning; i++)
     {
       #ifdef TEST
-      fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
+      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
       #endif
 
       if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
@@ -977,10 +977,6 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
 
     nxagentChangeOption(Fullscreen, False);
 
-    nxagentChangeOption(AllScreens, False);
-
-    nxagentFullscreenWindow = 0;
-
     resetAgentPosition = True;
   }
 
@@ -1384,13 +1380,10 @@ N/A
       nxagentChangeOption(Height, gattributes.height);
     }
 
-    if (nxagentOption(AllScreens))
-    {
-      attributes.override_redirect = True; 
-    }
-
     if (nxagentOption(Fullscreen))
     {
+      attributes.override_redirect = True;
+
       /*
        * We need to disable the host's screensaver or
        * it will otherwise grab the screen even if it
@@ -1617,7 +1610,7 @@ N/A
           nxagentReconnectTrap == 1)
   {
     valuemask = CWBackPixel | CWEventMask | CWColormap |
-                    (nxagentOption(AllScreens) == 1 ? CWOverrideRedirect : 0);
+                    (nxagentOption(Fullscreen) == 1 ? CWOverrideRedirect : 0);
 
     attributes.background_pixel = nxagentBlackPixel;
 
@@ -1625,13 +1618,10 @@ N/A
 
     attributes.colormap = nxagentDefaultVisualColormap(nxagentDefaultVisual(pScreen));
 
-    if (nxagentOption(AllScreens) == 1)
+    if (nxagentOption(Fullscreen) == 1)
     {
       attributes.override_redirect = True;
-    }
 
-    if (nxagentOption(Fullscreen) == 1)
-    {
       if (nxagentReconnectTrap)
       {
         /*
@@ -1764,7 +1754,7 @@ N/A
     sizeHints.width = nxagentOption(RootWidth);
     sizeHints.height = nxagentOption(RootHeight);
 
-    if (nxagentOption(DesktopResize) == 1 || nxagentOption(Fullscreen) == 1)
+    if (nxagentOption(DesktopResize) == 1)
     {
       sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
       sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
@@ -1809,14 +1799,30 @@ N/A
 
     XClearWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
 
-    if (nxagentOption(AllScreens))
+    if (nxagentOption(Fullscreen))
+    {
+      valuemask = CWBackPixmap | CWColormap | CWOverrideRedirect;
+    }
+    else
+    {
+      valuemask = CWBackPixmap | CWColormap;
+    }
+
+    attributes.background_pixmap = nxagentScreenSaverPixmap;
+    attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
+
+    if (nxagentOption(Fullscreen))
     {
+      attributes.override_redirect = False;
       if (nxagentReconnectTrap)
       {
         XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, True, GrabModeAsync,
                       GrabModeAsync, CurrentTime);
       }
+    }
 
+    if (nxagentOption(Fullscreen))
+    {
       nxagentIconWindow = nxagentCreateIconWindow();
     }
     else
@@ -1874,6 +1880,13 @@ N/A
        */
 
       XSetWMProtocols(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &deleteWMatom, 1);
+
+      /*
+      if (nxagentOption(Fullscreen))
+      {
+        XSetWMProtocols(nxagentDisplay, nxagentIconWindow, &deleteWMatom, 1);
+      }
+      */
     }
     else
     {
@@ -2172,6 +2185,8 @@ Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
   int oldMmWidth;
   int oldMmHeight;
 
+  RegionPtr pRootWinSize;
+
   #ifdef TEST
   nxagentPrintAgentGeometry("Before Resize Screen", "nxagentResizeScreen:");
   #endif
@@ -2251,10 +2266,13 @@ FIXME: We should try to restore the previously
 
   if (nxagentOption(Fullscreen))
   {
-    nxagentChangeOption(RootX, (nxagentOption(Width) -
-                            nxagentOption(RootWidth)) / 2);
-    nxagentChangeOption(RootY, (nxagentOption(Height) -
-                            nxagentOption(RootHeight)) / 2);
+    nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+    nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+    nxagentChangeOption(RootX, (WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
+                            - nxagentOption(RootWidth)) / 2);
+    nxagentChangeOption(RootY,  (HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
+                            - nxagentOption(RootHeight)) / 2);
   }
   else
   {
@@ -2265,6 +2283,62 @@ FIXME: We should try to restore the previously
   nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
   nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
 
+  /*
+   * Change agent window size and size hints.
+   */
+
+  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);
+
+  if (nxagentOption(Fullscreen))
+  {
+    XResizeWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+    XResizeWindow(nxagentDisplay, nxagentInputWindows[pScreen -> myNum],
+                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+  }
+  else
+  {
+    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.
    */
@@ -2286,6 +2360,8 @@ FIXME: We should try to restore the previously
 
   (*pScreen -> PositionWindow)(WindowTable[pScreen -> myNum], 0, 0);
 
+  pRootWinSize = &WindowTable[pScreen -> myNum] -> winSize;
+
   nxagentSetRootClip(pScreen, 1);
 
   XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[0]),
@@ -2293,12 +2369,6 @@ FIXME: We should try to restore the previously
 
   nxagentMoveViewport(pScreen, 0, 0);
 
-  /*
-   * Update pointer bounds.
-   */
-
-  ScreenRestructured(pScreen);
-
   #ifdef TEST
   nxagentPrintAgentGeometry("After Resize Screen", "nxagentResizeScreen:");
   #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 5b1957755..ab8c01a73 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -48,7 +48,6 @@ extern ScreenPtr nxagentDefaultScreen;
 extern Pixmap nxagentPixmapLogo;
 
 extern Window nxagentIconWindow;
-
 extern Window nxagentFullscreenWindow;
 
 extern RegionRec nxagentShadowUpdateRegion;
@@ -62,8 +61,6 @@ extern short nxagentShadowUid;
 void nxagentSetScreenInfo(ScreenInfo *screenInfo);
 void nxagentSetPixmapFormats(ScreenInfo *screenInfo);
 
-void nxagentPrintGeometry();
-
 extern Window nxagentDefaultWindows[MAXSCREENS];
 extern Window nxagentInputWindows[MAXSCREENS];
 extern Window nxagentScreenSaverWindows[MAXSCREENS];
@@ -90,7 +87,6 @@ extern int nxagentBitsPerPixel(int depth);
 void nxagentSetScreenSaverTime(void);
 
 void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
-
 void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
 
 Window nxagentCreateIconWindow(void);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
index 235c48c23..54b355762 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.h b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
index f7ba6c2e2..a677f209b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.c b/nx-X11/programs/Xserver/hw/nxagent/Split.c
index 4cc2ea607..061ab8c45 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.h b/nx-X11/programs/Xserver/hw/nxagent/Split.h
index 2be449a18..88e55485c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
index 6bce2eaeb..17e6a89e1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
index f5e6bde0e..c6f62c43f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
index 9258e3b67..13bbf65c7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Utils.h b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
index f5bd55d8b..bf2aa1c26 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Utils.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.c b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
index b086c0e9a..46fe90f39 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.h b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
index 8436f79ad..d60f0d824 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 3e6d41d04..2abfd5ea0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -691,73 +691,6 @@ void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
 }
 
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
-{
-  XEvent e;
-
-  if (nxagentOption(Rootless) == 1)
-  {
-    return;
-  }
-
-  if (switchOn == 0)
-  {
-    nxagentWMDetect();
-
-    /*
-     * The smart scheduler could be stopped while
-     * waiting for the reply. In this case we need
-     * to yield explicitly to avoid to be stuck in
-     * the dispatch loop forever.
-     */
-
-    isItTimeToYield = 1;
-
-    if (nxagentWMIsRunning == 0)
-    {
-      #ifdef WARNING
-      fprintf(stderr, "Warning: Can't switch to window mode, no window manager "
-                  "has been detected.\n");
-      #endif
-
-      return;
-    }
-  }
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentSwitchFullscreen: Switching to %s mode.\n",
-              switchOn ? "fullscreen" : "windowed");
-  #endif
-
-  nxagentChangeOption(Fullscreen, switchOn);
-
-  memset(&e, 0, sizeof(e));
-
-  e.xclient.type = ClientMessage;
-  e.xclient.message_type = nxagentAtoms[13]; /* _NET_WM_STATE */
-  e.xclient.display = nxagentDisplay;
-  e.xclient.window = nxagentDefaultWindows[pScreen -> myNum];
-  e.xclient.format = 32;
-  e.xclient.data.l[0] = nxagentOption(Fullscreen) ? 1 : 0;
-  e.xclient.data.l[1] = nxagentAtoms[14]; /* _NET_WM_STATE_FULLSCREEN */
-
-  XSendEvent(nxagentDisplay, DefaultRootWindow(nxagentDisplay), False,
-                 SubstructureRedirectMask, &e);
-
-  if (switchOn == 1)
-  {
-    nxagentFullscreenWindow = nxagentDefaultWindows[pScreen -> myNum];
-
-    nxagentGrabPointerAndKeyboard(NULL);
-  }
-  else
-  {
-    nxagentFullscreenWindow = None;
-
-    nxagentUngrabPointerAndKeyboard(NULL);
-  } 
-}
-
-void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
 {
   Window w;
   XSetWindowAttributes attributes;
@@ -788,8 +721,6 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
   XUnmapWindow(nxagentDisplay, w);
   XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
 
-  XReparentWindow(nxagentDisplay, w, DefaultRootWindow(nxagentDisplay), 0, 0);
-
   if (switchOn)
   {
     /*
@@ -807,7 +738,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
     for (i = 0; i < 100 && nxagentWMIsRunning; i++)
     {
       #ifdef TEST
-      fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Going to wait for the ReparentNotify event.\n");
+      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
       #endif
 
       if (XCheckTypedWindowEvent(nxagentDisplay, w, ReparentNotify, &e))
@@ -836,8 +767,6 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
        */
 
       nxagentChangeOption(Fullscreen, True);
-      nxagentChangeOption(AllScreens, True);
-      
 
       /*
        * Save the window-mode configuration.
@@ -916,9 +845,9 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
        */
 
       #ifdef WARNING
-      fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Expected ReparentNotify event missing.\n");
+      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Expected ReparentNotify event missing.\n");
       #endif
- 
+
       nxagentWMIsRunning = False;
       attributes.override_redirect = False;
       XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
@@ -932,6 +861,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
      * It could be necessary:
      * - To restore screensaver.
      * - To set or reset nxagentForceBackingStore flag.
+     * - To grab keyboard.
      * - To propagate device settings to the X server if no WM is running.
      */
 
@@ -940,10 +870,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
      */
 
     nxagentChangeOption(Fullscreen, False);
-    nxagentChangeOption(AllScreens, False);
-
     XDestroyWindow(nxagentDisplay, nxagentIconWindow);
-
     nxagentIconWindow = nxagentFullscreenWindow = None;
 
     if (nxagentOption(DesktopResize) == 1)
@@ -957,19 +884,8 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
       }
     }
 
-    if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0)
-    {
-      nxagentChangeOption(X, nxagentOption(SavedX) -
-                              nxagentOption(WMBorderWidth));
-      nxagentChangeOption(Y, nxagentOption(SavedY) -
-                              nxagentOption(WMTitleHeight));
-    }
-    else
-    {
-      nxagentChangeOption(X, nxagentOption(SavedX));
-      nxagentChangeOption(Y, nxagentOption(SavedY));
-    }
-
+    nxagentChangeOption(X, nxagentOption(SavedX));
+    nxagentChangeOption(Y, nxagentOption(SavedY));
     nxagentChangeOption(Width, nxagentOption(SavedWidth));
     nxagentChangeOption(Height, nxagentOption(SavedHeight));
 
@@ -993,7 +909,7 @@ void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
   XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
                         nxagentOption(Width), nxagentOption(Height));
 
-  nxagentSetPrintGeometry(pScreen -> myNum); 
+  nxagentSetPrintGeometry(pScreen -> myNum);
 }
 
 #ifdef VIEWPORT_FRAME
@@ -2495,11 +2411,6 @@ void nxagentMapDefaultWindows()
         #endif
 
         XMapWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
-
-        if (nxagentOption(Fullscreen) == 1 && nxagentWMIsRunning == 1)
-        {
-          nxagentMaximizeToFullScreen(pScreen);
-        }
       }
 
       /*
@@ -2986,13 +2897,6 @@ FIXME: Do we need to set save unders attribute here?
       XSizeHints *props, hints;
       unsigned char *data = NULL;
 
-      #ifdef _XSERVER64
-
-      unsigned char *data64 = NULL;
-      unsigned int i;
-
-      #endif
-
       hints.flags = 0;
 
       ret = GetWindowProperty(pWin,
@@ -3001,13 +2905,10 @@ FIXME: Do we need to set save unders attribute here?
                                           False, XA_WM_SIZE_HINTS,
                                               &type, &format, &nItems, &bytesLeft, &data);
 
-      /*
-       * 72 is the number of bytes returned by
-       * sizeof(XSizeHints) on 32 bit platforms.
-       */
+      props = (XSizeHints*) data;
 
       if (ret == Success &&
-              ((format >> 3) * nItems) == 72 &&
+              ((format >> 3) * nItems) == sizeof(XSizeHints) &&
                   bytesLeft == 0 &&
                       type == XA_WM_SIZE_HINTS)
       {
@@ -3016,30 +2917,6 @@ FIXME: Do we need to set save unders attribute here?
                     (void*)pWin, pWin -> drawable.id, nxagentWindow(pWin));
         #endif
 
-        #ifdef _XSERVER64
-
-        data64 = (unsigned char *) malloc(sizeof(XSizeHints) + 4);
-
-        for (i = 0; i < 4; i++)
-        {
-          *(data64 + i) = *(data + i);
-        }
-
-        *(((int *) data64) + 1) = 0;
-
-        for (i = 8; i < sizeof(XSizeHints) + 4; i++)
-        {
-          *(data64 + i) = *(data + i - 4);
-        }
-
-        props = (XSizeHints *) data64;
-
-        #else
-
-        props = (XSizeHints *) data;
-
-        #endif   /* _XSERVER64 */
-
         hints = *props;
       }
       else
@@ -3058,15 +2935,6 @@ FIXME: Do we need to set save unders attribute here?
       XSetWMNormalHints(nxagentDisplay,
                            nxagentWindow(pWin),
                               &hints);
-
-      #ifdef _XSERVER64
-
-      if (data64 != NULL)
-      {
-        free(data64);
-      }
-
-      #endif
     }
   }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
index 3ca74ba8e..f77db372d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Windows.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -222,8 +222,6 @@ void nxagentSetTopLevelEventMask(WindowPtr pWin);
 
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn);
 
-void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn);
-
 void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift);
 
 #ifdef VIEWPORT_FRAME
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
index cf5d48ba2..967c5656e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
index cf5d48ba2..967c5656e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index 69ad30d2d..d9da23738 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -513,6 +513,17 @@ Dispatch(void)
      * completed. We can now handle our clients.
      */
 
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      #ifdef NX_DEBUG_INPUT
+      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+      #else
+      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+      #endif
+
+      nxagentSessionState = SESSION_UP;
+    }
+
     #ifdef XKB
 
     nxagentInitXkbWrapper();
@@ -596,21 +607,6 @@ Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
           clientReady[1] = NXAGENT_WAKEUP;
         }
 
-        if (serverGeneration > nxagentMaxAllowedResets &&
-                nxagentSessionState == SESSION_STARTING &&
-                    (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
-        {
-          #ifdef NX_DEBUG_INPUT
-          fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
-                      GetTimeAsString(), GetTimeInMillis());
-          #else
-          fprintf(stderr, "Session: Session started at '%s'.\n",
-                      GetTimeAsString());
-          #endif
-
-          nxagentSessionState = SESSION_UP;
-        }
-
         #ifdef BLOCKS
         fprintf(stderr, "[End dispatch]\n");
         #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index 69ad30d2d..d9da23738 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -513,6 +513,17 @@ Dispatch(void)
      * completed. We can now handle our clients.
      */
 
+    if (serverGeneration > nxagentMaxAllowedResets)
+    {
+      #ifdef NX_DEBUG_INPUT
+      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
+      #else
+      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
+      #endif
+
+      nxagentSessionState = SESSION_UP;
+    }
+
     #ifdef XKB
 
     nxagentInitXkbWrapper();
@@ -596,21 +607,6 @@ Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
           clientReady[1] = NXAGENT_WAKEUP;
         }
 
-        if (serverGeneration > nxagentMaxAllowedResets &&
-                nxagentSessionState == SESSION_STARTING &&
-                    (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
-        {
-          #ifdef NX_DEBUG_INPUT
-          fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
-                      GetTimeAsString(), GetTimeInMillis());
-          #else
-          fprintf(stderr, "Session: Session started at '%s'.\n",
-                      GetTimeAsString());
-          #endif
-
-          nxagentSessionState = SESSION_UP;
-        }
-
         #ifdef BLOCKS
         fprintf(stderr, "[End dispatch]\n");
         #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
index 04fc047fc..4361985fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
index 04fc047fc..4361985fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index c5593adbb..467381054 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index c5593adbb..467381054 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
index ead9b9d28..9bfb28426 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
index ead9b9d28..9bfb28426 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
index 51c547984..3d021a0c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
index 51c547984..3d021a0c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index cd65fdc0e..577659a82 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index cd65fdc0e..577659a82 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
index 7a1d813b3..b11b10fb9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
index 7a1d813b3..b11b10fb9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
index fa6b5fb02..b6d563c6b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
index fa6b5fb02..b6d563c6b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
index 3fc73cf3b..652b85dd7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
index 3fc73cf3b..652b85dd7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
index 5f32334ae..4eabd17f9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
index 5f32334ae..4eabd17f9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
index f418654b4..124356427 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
index f418654b4..124356427 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
index 190294979..d486d19c5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
index 190294979..d486d19c5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
index d9054b4b6..5cd3e5073 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -62,7 +62,6 @@
 #include "Screen.h"
 #include "Pixmaps.h"
 #include "Drawable.h"
-#include "Render.h"
 
 #define PANIC
 #define WARNING
@@ -873,9 +872,6 @@ AllocatePicture (ScreenPtr  pScreen)
 	else
 	    ppriv->ptr = (pointer)NULL;
     }
-
-    nxagentPicturePriv(pPicture) -> picture = 0;
-
     return pPicture;
 }
 
@@ -1067,49 +1063,7 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
 static PicturePtr createSourcePicture(void)
 {
     PicturePtr pPicture;
-
-    extern int nxagentPicturePrivateIndex;
-
-    unsigned int totalPictureSize;
-
-    DevUnion *ppriv;
-
-    char *privPictureRecAddr;
-
-    int i;
-
-    /*
-     * Compute size of entire PictureRect, plus privates.
-     */
-
-    totalPictureSize = sizeof(PictureRec) +
-                           picturePrivateCount * sizeof(DevUnion) +
-                               sizeof(nxagentPrivPictureRec);
-
-    pPicture = (PicturePtr) xalloc(totalPictureSize);
-
-    if (pPicture != NULL)
-    {
-      ppriv = (DevUnion *) (pPicture + 1);
-
-      for (i = 0; i < picturePrivateCount; ++i)
-      {
-        /*
-         * Other privates are inaccessible.
-         */
-
-        ppriv[i].ptr = NULL;
-      }
-
-      privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
-
-      ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
-
-      pPicture -> devPrivates = ppriv;
-
-      nxagentPicturePriv(pPicture) -> picture = 0;
-    }
-
+    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
     pPicture->pDrawable = 0;
     pPicture->pFormat = 0;
     pPicture->pNext = 0;
@@ -1743,10 +1697,6 @@ FreePicture (pointer	value,
 
     if (--pPicture->refcnt == 0)
     {
-#ifdef NXAGENT_SERVER
-        nxagentDestroyPicture(pPicture);
-#endif
-
 	if (pPicture->transform)
 	    xfree (pPicture->transform);
         if (!pPicture->pDrawable) {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
index d9054b4b6..5cd3e5073 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -62,7 +62,6 @@
 #include "Screen.h"
 #include "Pixmaps.h"
 #include "Drawable.h"
-#include "Render.h"
 
 #define PANIC
 #define WARNING
@@ -873,9 +872,6 @@ AllocatePicture (ScreenPtr  pScreen)
 	else
 	    ppriv->ptr = (pointer)NULL;
     }
-
-    nxagentPicturePriv(pPicture) -> picture = 0;
-
     return pPicture;
 }
 
@@ -1067,49 +1063,7 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
 static PicturePtr createSourcePicture(void)
 {
     PicturePtr pPicture;
-
-    extern int nxagentPicturePrivateIndex;
-
-    unsigned int totalPictureSize;
-
-    DevUnion *ppriv;
-
-    char *privPictureRecAddr;
-
-    int i;
-
-    /*
-     * Compute size of entire PictureRect, plus privates.
-     */
-
-    totalPictureSize = sizeof(PictureRec) +
-                           picturePrivateCount * sizeof(DevUnion) +
-                               sizeof(nxagentPrivPictureRec);
-
-    pPicture = (PicturePtr) xalloc(totalPictureSize);
-
-    if (pPicture != NULL)
-    {
-      ppriv = (DevUnion *) (pPicture + 1);
-
-      for (i = 0; i < picturePrivateCount; ++i)
-      {
-        /*
-         * Other privates are inaccessible.
-         */
-
-        ppriv[i].ptr = NULL;
-      }
-
-      privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
-
-      ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
-
-      pPicture -> devPrivates = ppriv;
-
-      nxagentPicturePriv(pPicture) -> picture = 0;
-    }
-
+    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
     pPicture->pDrawable = 0;
     pPicture->pFormat = 0;
     pPicture->pNext = 0;
@@ -1743,10 +1697,6 @@ FreePicture (pointer	value,
 
     if (--pPicture->refcnt == 0)
     {
-#ifdef NXAGENT_SERVER
-        nxagentDestroyPicture(pPicture);
-#endif
-
 	if (pPicture->transform)
 	    xfree (pPicture->transform);
         if (!pPicture->pDrawable) {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
index 0d1a8e1d8..d11e1fe21 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
index 0d1a8e1d8..d11e1fe21 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
index cd1ec6ddd..ac61552f0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
index cd1ec6ddd..ac61552f0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
index 5f460f23e..fa40a4921 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
index 5f460f23e..fa40a4921 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index 89e790135..7c60d856c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -116,6 +116,7 @@ int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
 void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
 int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
 int  nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
 void nxagentChangePicture(PicturePtr, Mask);
 int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
 void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
@@ -131,28 +132,6 @@ void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
 void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
                            INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
 
-void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
-
-void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
-                                           xPointFixed *p2, int nStops,
-                                               xFixed *stops,
-                                                   xRenderColor *colors);
-
-void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
-                                           xPointFixed *outer,
-                                               xFixed innerRadius,
-                                                   xFixed outerRadius,
-                                                       int nStops,
-                                                           xFixed *stops,
-                                                               xRenderColor *colors);
-
-void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
-                                            xPointFixed *center,
-                                                xFixed angle, int nStops, 
-                                                    xFixed *stops, 
-                                                        xRenderColor *colors);
-
-
 /*
  * The void pointer is actually a XGlyphElt8.
  */
@@ -844,6 +823,8 @@ ProcRenderFreePicture (ClientPtr client)
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
 		    RenderErrBase + BadPicture);
 
+    nxagentDestroyPicture(pPicture);
+
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -945,16 +926,9 @@ ProcRenderComposite (ClientPtr client)
 		    RenderErrBase + BadPicture);
     VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
 		  RenderErrBase + BadPicture);
-/*
-FIXME: Imported change from newest version of Xorg. Changed pSrc to pDst.
-
     if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
 	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
 	return BadMatch;
-*/
-    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
-	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
-	return BadMatch;
 
     ValidatePicture (pSrc);
     if (pMask)
@@ -2362,11 +2336,6 @@ static int ProcRenderCreateSolidFill(ClientPtr client)
     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2398,12 +2367,6 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
-                                          stuff->nStops, stops, colors);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2434,14 +2397,6 @@ static int ProcRenderCreateRadialGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
-                                          stuff->inner_radius,
-                                              stuff->outer_radius, 
-                                                  stuff->nStops, stops, colors);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2471,13 +2426,6 @@ static int ProcRenderCreateConicalGradient (ClientPtr client)
                                              stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
-                                           stuff->angle, stuff->nStops, stops,
-                                               colors);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index 89e790135..7c60d856c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
@@ -116,6 +116,7 @@ int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
 void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
 int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
 int  nxagentCreatePicture(PicturePtr, Mask);
+void nxagentDestroyPicture(PicturePtr pPicture);
 void nxagentChangePicture(PicturePtr, Mask);
 int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
 void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
@@ -131,28 +132,6 @@ void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
 void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
                            INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
 
-void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
-
-void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
-                                           xPointFixed *p2, int nStops,
-                                               xFixed *stops,
-                                                   xRenderColor *colors);
-
-void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
-                                           xPointFixed *outer,
-                                               xFixed innerRadius,
-                                                   xFixed outerRadius,
-                                                       int nStops,
-                                                           xFixed *stops,
-                                                               xRenderColor *colors);
-
-void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
-                                            xPointFixed *center,
-                                                xFixed angle, int nStops, 
-                                                    xFixed *stops, 
-                                                        xRenderColor *colors);
-
-
 /*
  * The void pointer is actually a XGlyphElt8.
  */
@@ -844,6 +823,8 @@ ProcRenderFreePicture (ClientPtr client)
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
 		    RenderErrBase + BadPicture);
 
+    nxagentDestroyPicture(pPicture);
+
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -945,16 +926,9 @@ ProcRenderComposite (ClientPtr client)
 		    RenderErrBase + BadPicture);
     VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
 		  RenderErrBase + BadPicture);
-/*
-FIXME: Imported change from newest version of Xorg. Changed pSrc to pDst.
-
     if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
 	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
 	return BadMatch;
-*/
-    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
-	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
-	return BadMatch;
 
     ValidatePicture (pSrc);
     if (pMask)
@@ -2362,11 +2336,6 @@ static int ProcRenderCreateSolidFill(ClientPtr client)
     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2398,12 +2367,6 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
-                                          stuff->nStops, stops, colors);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2434,14 +2397,6 @@ static int ProcRenderCreateRadialGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
-                                          stuff->inner_radius,
-                                              stuff->outer_radius, 
-                                                  stuff->nStops, stops, colors);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2471,13 +2426,6 @@ static int ProcRenderCreateConicalGradient (ClientPtr client)
                                              stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
-    /* AGENT SERVER */
-
-    nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
-                                           stuff->angle, stuff->nStops, stops,
-                                               colors);
-
-    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
index d1c8325f2..cffe8008b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index d1c8325f2..cffe8008b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index eaaa92041..ef830b73f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index eaaa92041..ef830b73f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
index 76e86fd2a..ea133eaae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
index 76e86fd2a..ea133eaae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
index f6dad312a..497a62fe0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
index f6dad312a..497a62fe0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
index dd8be6cb3..5023265e9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
index 854e0a611..3fce57ff7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
index 9ec7e6bc8..f4d0a2d55 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2009 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/screensaver b/nx-X11/programs/Xserver/hw/nxagent/screensaver
index ef7cd661a..2fcf5dc87 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/screensaver
+++ b/nx-X11/programs/Xserver/hw/nxagent/screensaver
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2003 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      */
-- 
cgit v1.2.3


From c078024019d334eb96fbfaf922c64297c9a0c6e0 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:59 +0200
Subject: Imported nxagent-3.4.0-5.tar.gz

Summary: Imported nxagent-3.4.0-5.tar.gz
Keywords:

Imported nxagent-3.4.0-5.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Agent.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  28 +++++
 nx-X11/programs/Xserver/hw/nxagent/Client.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Client.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 134 ++++++++++++++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.c    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.h    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GC.c            |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCs.h           |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |   5 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Icons.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  54 ++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/LICENSE         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Literals.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c    |   2 +-
 .../Xserver/hw/nxagent/NXdispatch.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c    |   2 +-
 .../Xserver/hw/nxagent/NXdixfonts.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXevents.c      |   2 +-
 .../Xserver/hw/nxagent/NXevents.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXextension.c   |   2 +-
 .../Xserver/hw/nxagent/NXextension.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c       |   2 +-
 .../Xserver/hw/nxagent/NXglyph.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c   |   2 +-
 .../Xserver/hw/nxagent/NXglyphcurs.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h    |   2 +-
 .../Xserver/hw/nxagent/NXglyphstr.h.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c     |   2 +-
 .../Xserver/hw/nxagent/NXmiglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c     |   2 +-
 .../Xserver/hw/nxagent/NXpicture.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h  |   2 +-
 .../Xserver/hw/nxagent/NXpicturestr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c    |   2 +-
 .../Xserver/hw/nxagent/NXproperty.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c       |   2 +-
 .../Xserver/hw/nxagent/NXrandr.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrender.c      |   2 +-
 .../Xserver/hw/nxagent/NXrender.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c      |   2 +-
 .../Xserver/hw/nxagent/NXwindow.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |   8 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |   5 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmap.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/TestExt.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Utils.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Window.c        |  64 +++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Windows.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXdamage.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |  28 +++--
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |  28 +++--
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXdixfonts.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c |   2 +-
 .../Xserver/hw/nxagent/X/NXextension.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXglxext.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h  |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphstr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiexpose.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c   |   2 +-
 .../Xserver/hw/nxagent/X/NXmiglyph.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXmitrap.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiwindow.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c   |   2 +-
 .../Xserver/hw/nxagent/X/NXpicture.c.NX.original   |   2 +-
 .../programs/Xserver/hw/nxagent/X/NXpicturestr.h   |   2 +-
 .../hw/nxagent/X/NXpicturestr.h.NX.original        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXrandr.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   2 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXwindow.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXxvdisp.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/os2Stub.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/screensaver     |   2 +-
 160 files changed, 476 insertions(+), 190 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Agent.h b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
index 13f87c96e..3f2c93fdb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Agent.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 0588f43d6..c2e58bd58 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -1208,7 +1208,7 @@ static void nxagentParseOptions(char *name, char *value)
     {
       nxagentChangeOption(ClientOs, ClientOsSolaris);
     }
-    else if (strcmp(value, "mac") == 0)
+    else if (strcmp(value, "macosx") == 0)
     {
       nxagentChangeOption(ClientOs, ClientOsMac);
     }
@@ -1512,7 +1512,7 @@ N/A
       int splitMode = 0;
       int splitSize = 0;
 
-      unsigned int packMethod  = PACK_NONE;
+      unsigned int packMethod = PACK_NONE;
       unsigned int packQuality = 9;
 
       int dataLevel   = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
index 2aac8e387..92650a4a0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
index 13f9b8082..7f12406f5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
index 842b820db..d8acb9442 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.c b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
index 4fb5224fb..34433bd2b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.h b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
index c4daeea8c..e0da3e357 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 4e964d0ad..1a82e9abf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,33 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
index b0db1df0f..acfaab7c0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
index 4b12ed127..45f87fc66 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index 442b1c871..eb830234d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
index 5a592a4da..2750ddfd2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
index d9a979a42..259aa3b24 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
index a8e225460..8321e8038 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
index 44bab3cf9..b0640ff11 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.h b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
index c5dede9eb..fb1d6d8e9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
index 7e4385712..141ba3a64 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
index 7b4e6beac..11e407efd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
index c6f8a9104..2f807b1dc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
index 5c71fad87..aa845c7c2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index c1a80b391..1a57788e6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h
index 4c04c5ba8..35b7857ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index ddd7f13ca..75057097a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
index 6ce0e3156..146610efb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.c b/nx-X11/programs/Xserver/hw/nxagent/Error.c
index 2a8173019..963cfa287 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.h b/nx-X11/programs/Xserver/hw/nxagent/Error.h
index f7a53cbd1..2d6083d4e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 83665ff90..ca21423aa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -679,6 +679,30 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
             break;
           }
+          case doViewportMoveUp:
+          {
+            nxagentMoveViewport(pScreen, 0, -nxagentOption(Height));
+
+            break;
+          }
+          case doViewportMoveDown:
+          {
+            nxagentMoveViewport(pScreen, 0, nxagentOption(Height));
+
+            break;
+          }
+          case doViewportMoveLeft:
+          {
+            nxagentMoveViewport(pScreen, -nxagentOption(Width), 0);
+
+            break;
+          }
+          case doViewportMoveRight:
+          {
+            nxagentMoveViewport(pScreen, nxagentOption(Width), 0);
+
+            break;
+          }
           case doViewportUp:
           {
             nxagentMoveViewport(pScreen, 0, -nextinc(viewportInc));
@@ -763,6 +787,20 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
       case KeyRelease:
       {
         enum HandleEventResult result;
+        int sendKey = 0;
+
+/*
+FIXME: Don't enqueue the KeyRelease event if the key was
+       not already pressed. This workaround avoids a fake
+       KeyPress is enqueued by the XKEYBOARD extension.
+       Another solution would be to let the events are
+       enqueued and to remove the KeyPress afterwards.
+*/
+
+        if (inputInfo.keyboard -> key -> down[X.xkey.keycode >> 3] & (1 << (X.xkey.keycode & 7)))
+        {
+          sendKey = 1;
+        }
 
         #ifdef TEST
         fprintf(stderr, "nxagentDispatchEvents: Going to handle new KeyRelease event.\n");
@@ -808,7 +846,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           x.u.keyButtonPointer.time = nxagentLastEventTime;
         }
 
-        if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)))
+        if (!(nxagentCheckSpecialKeystroke(&X.xkey, &result)) && sendKey == 1)
         {
           mieqEnqueue(&x);
 
@@ -3101,6 +3139,8 @@ int nxagentHandleReparentNotify(XEvent* X)
           #ifdef WARNING
           fprintf(stderr, "nxagentHandleReparentNotify: WARNING! Failed QueryTree request.\n");
           #endif
+
+          break;
         }
 
         if (result && children_return)
@@ -3153,6 +3193,96 @@ int nxagentHandleReparentNotify(XEvent* X)
 
     return 1;
   }
+  else if (nxagentWMIsRunning == 1 && nxagentOption(Fullscreen) == 0 &&
+               nxagentOption(WMBorderWidth) == -1)
+  {
+    XlibWindow w;
+    XlibWindow rootReturn = 0;
+    XlibWindow parentReturn = 0;
+    XlibWindow junk;
+    XlibWindow *childrenReturn = NULL;
+    unsigned int nchildrenReturn = 0;
+    Status result;
+    XSizeHints hints;
+    XWindowAttributes attributes;
+    int x, y;
+    int xParent, yParent;
+
+    /*
+     * Calculate the absolute upper-left X e Y 
+     */
+
+    if ((XGetWindowAttributes(nxagentDisplay, X -> xreparent.window,
+                                  &attributes) == 0))
+    {
+      #ifdef WARNING
+      fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
+                  "XGetWindowAttributes failed.\n");
+      #endif
+
+      return 1;
+    }
+
+    x = attributes.x;
+    y = attributes.y;
+
+    XTranslateCoordinates(nxagentDisplay, X -> xreparent.window,
+                              attributes.root, -attributes.border_width,
+                                  -attributes.border_width, &x, &y, &junk);
+
+   /*
+    * Calculate the parent X and parent Y.
+    */
+
+    w = X -> xreparent.parent;
+
+    if (w != DefaultRootWindow(nxagentDisplay))
+    {
+      do
+      {
+        result = XQueryTree(nxagentDisplay, w, &rootReturn, &parentReturn,
+                                &childrenReturn, &nchildrenReturn);
+    
+        if (parentReturn == rootReturn || parentReturn == 0 || result == 0)
+        {
+          break;
+        }
+
+        if (result == 1 && childrenReturn != NULL)
+        {
+          XFree(childrenReturn);
+        }
+    
+        w = parentReturn;
+      }
+      while (True);
+
+      /*
+       * WM reparented. Find edge of the frame.
+       */
+
+      if (XGetWindowAttributes(nxagentDisplay, w, &attributes) == 0)
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentHandleReparentNotify: WARNING! "
+                    "XGetWindowAttributes failed for parent window.\n");
+        #endif
+
+        return 1;
+      }
+
+      xParent = attributes.x;
+      yParent = attributes.y;
+
+      /*
+       * Difference between Absolute X and Parent X gives thickness of side frame.
+       * Difference between Absolute Y and Parent Y gives thickness of title bar. 
+       */
+
+      nxagentChangeOption(WMBorderWidth, (x - xParent));
+      nxagentChangeOption(WMTitleHeight, (y - yParent));
+    }
+  }
 
   return 1;
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index 3e04222a2..238a229f9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -32,6 +32,10 @@ enum HandleEventResult
   doCloseSession,
   doStartKbd,
   doSwitchFullscreen,
+  doViewportMoveUp,
+  doViewportMoveLeft,
+  doViewportMoveRight,
+  doViewportMoveDown,
   doViewportLeft,
   doViewportUp,
   doViewportRight,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
index 748afa53e..e76cbb4ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
index 06185170e..620645d00 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index b14dc883b..13b819322 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.h b/nx-X11/programs/Xserver/hw/nxagent/Font.h
index d95cbdc83..75ae3f6f5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GC.c b/nx-X11/programs/Xserver/hw/nxagent/GC.c
index 55a0a0031..c53e3b9f7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GC.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GC.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index d2cc58400..85730797e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
index 666a098bf..7ae6d9923 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCs.h b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
index 460469696..bec290088 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCs.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index e43fbb931..be407f160 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -527,7 +527,8 @@ void nxagentBlockHandler(pointer data, struct timeval **timeout, pointer mask)
                 synchronize, nxagentReady);
     #endif
 
-    if (nxagentQueuedEvents(nxagentDisplay) > 0)
+    if (NXDisplayError(nxagentDisplay) == 0 &&
+            nxagentQueuedEvents(nxagentDisplay) > 0)
     {
       #ifdef WARNING
       fprintf(stderr, "nxagentBlockHandler: WARNING! Forcing a null timeout with events queued.\n");
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
index 8cf92b219..fe8aeef36 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.c b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
index 02fde6782..a9ac77c09 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.h b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
index 469da223d..9896aeead 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Icons.h b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
index 350e76487..4d0e216cd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Icons.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com.          */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index ec7a60a96..e8405ed3a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.h b/nx-X11/programs/Xserver/hw/nxagent/Image.h
index bd6d4c948..7805b0312 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index f60d7c457..64b6583bf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -193,7 +193,7 @@ void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
   if (serverGeneration <= 1)
   {
     fprintf(stderr, "\nNXAGENT - Version " NXAGENT_VERSION "\n\n");
-    fprintf(stderr, "Copyright (C) 2001, 2007 NoMachine.\n");
+    fprintf(stderr, "Copyright (C) 2001, 2010 NoMachine.\n");
     fprintf(stderr, "See http://www.nomachine.com/ for more information.\n\n");
 
     fprintf(stderr, "Info: Agent running with pid '%d'.\n", getpid());
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
index 16c74ea99..576c1a74d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index a4729e9b7..b0aeabeea 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index 4c7395a43..1a953358a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index eee13db2d..a2e4fb06f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -264,6 +264,58 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       #endif
     }
   }
+  else if ((X -> state & nxagentAltMetaMask) &&
+               ((X -> state & (ControlMask | ShiftMask)) == (ControlMask |
+                   ShiftMask)))
+  {
+    switch (sym)
+    {
+      case XK_Left:
+      case XK_KP_Left:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveLeft;
+        }
+
+        break;
+      }
+      case XK_Up:
+      case XK_KP_Up:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveUp;
+        }
+
+        break;
+      }
+      case XK_Right:
+      case XK_KP_Right:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveRight;
+        }
+
+        break;
+      }
+      case XK_Down:
+      case XK_KP_Down:
+      {
+        if (nxagentOption(Rootless) == 0 &&
+                nxagentOption(DesktopResize) == 0)
+        {
+          *result = doViewportMoveDown;
+        }
+
+        break;
+      }
+    }
+  }
 
   return (*result == doNothing) ? 0 : 1;
 }
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index fea97975c..e9ca59ff2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/LICENSE b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
index 451196c1a..141ca13ea 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/LICENSE
+++ b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2001, 2009 NoMachine - http://www.nomachine.com/.
+Copyright (c) 2001, 2010 NoMachine - http://www.nomachine.com/.
 
 NXAGENT and NX extensions to X are copyright of NoMachine.
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
index 21c27afa1..377dd7e25 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Literals.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.c b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
index e275b985f..bde85f090 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.h b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
index 9b6d879d7..2125eca3e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index e189b9539..5106ffa8c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
index e189b9539..5106ffa8c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
index b57401ceb..0d8584218 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
index b57401ceb..0d8584218 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
index b01e4a452..cd8ced7a6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
index b01e4a452..cd8ced7a6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
index 9bb868f2b..852ad1503 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
index 9bb868f2b..852ad1503 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
index 6ec64afae..55248195f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
index 6ec64afae..55248195f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
index 6352c88d1..614d2db39 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
index 6352c88d1..614d2db39 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
index 0874f0fef..08ffb35b0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
index 0874f0fef..08ffb35b0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
index e0f6d1cdf..806cf2900 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
index e0f6d1cdf..806cf2900 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
index 95178d362..a9c501b34 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
index 95178d362..a9c501b34 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
index 90a31d36f..26a95fe9f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
index 90a31d36f..26a95fe9f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
index 06d6074ad..14b6136d4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
index 06d6074ad..14b6136d4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
index 179cc1ab0..b7039e1e0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
index 179cc1ab0..b7039e1e0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
index a670c3521..0940a3602 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
index a670c3521..0940a3602 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
index a0d4cd6ee..0954cf8ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
index a0d4cd6ee..0954cf8ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
index a8aa254ff..8d05175ff 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
index 8ceb49418..4e800e96d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
index 727161648..ae3a03d86 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index 955be61bc..1f04b0daf 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -63,6 +63,9 @@ void nxagentInitOptions()
   nxagentOptions.Height      = 0;
   nxagentOptions.BorderWidth = 0;
 
+  nxagentOptions.WMBorderWidth = -1;
+  nxagentOptions.WMTitleHeight = -1;
+
   nxagentOptions.SavedX      = 0;
   nxagentOptions.SavedY      = 0;
   nxagentOptions.SavedWidth  = 0;
@@ -168,6 +171,9 @@ void nxagentResetOptions()
 
   nxagentOptions.TileWidth  = UNDEFINED;
   nxagentOptions.TileHeight = UNDEFINED;
+
+  nxagentOptions.WMBorderWidth = -1;
+  nxagentOptions.WMTitleHeight = -1;
 }
 
 void nxagentSaveOptions()
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index 7126338a8..1bc7eaa4c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -126,6 +126,9 @@ typedef struct _AgentOptions
    * screen.
    */
 
+  int WMBorderWidth;
+  int WMTitleHeight;
+
   int SavedX;
   int SavedY;
   int SavedWidth;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
index eb8daf8f3..10c705dfc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
index cd2df1fa6..e046771cc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
index 9a4776192..1718c7363 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
index 93df4d444..234650dd4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
index 8a6702d18..34012d3d5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
index 3d8899bbe..0807b08ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index c656f2912..598ffc188 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
index 6a3b56fc7..12d0742df 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index 5c6503e64..6bc54c86e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
index 77e842d16..81ba3369d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index 53f4df41e..a8ce4c7cd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
index 5538b58ea..ece4c9d31 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 4f4160765..bdd30afee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index ab8c01a73..6ffebe0ea 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
index 54b355762..24dbf1413 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.h b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
index a677f209b..86920ad8b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.c b/nx-X11/programs/Xserver/hw/nxagent/Split.c
index 061ab8c45..bf7f705b9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.h b/nx-X11/programs/Xserver/hw/nxagent/Split.h
index 88e55485c..60be29b39 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
index 17e6a89e1..1d5fdee20 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
index c6f62c43f..22de3bc1b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
index 13bbf65c7..aa6937e70 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Utils.h b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
index bf2aa1c26..830b2753f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Utils.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.c b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
index 46fe90f39..f38931677 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.h b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
index d60f0d824..c682f92dd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 2abfd5ea0..449458ade 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -884,8 +884,19 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
       }
     }
 
-    nxagentChangeOption(X, nxagentOption(SavedX));
-    nxagentChangeOption(Y, nxagentOption(SavedY));
+    if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0)
+    {
+      nxagentChangeOption(X, nxagentOption(SavedX) -
+                              nxagentOption(WMBorderWidth));
+      nxagentChangeOption(Y, nxagentOption(SavedY) -
+                              nxagentOption(WMTitleHeight));
+    }
+    else
+    {
+      nxagentChangeOption(X, nxagentOption(SavedX));
+      nxagentChangeOption(Y, nxagentOption(SavedY));
+    }
+
     nxagentChangeOption(Width, nxagentOption(SavedWidth));
     nxagentChangeOption(Height, nxagentOption(SavedHeight));
 
@@ -2897,6 +2908,13 @@ FIXME: Do we need to set save unders attribute here?
       XSizeHints *props, hints;
       unsigned char *data = NULL;
 
+      #ifdef _XSERVER64
+
+      unsigned char *data64 = NULL;
+      unsigned int i;
+
+      #endif
+
       hints.flags = 0;
 
       ret = GetWindowProperty(pWin,
@@ -2905,10 +2923,13 @@ FIXME: Do we need to set save unders attribute here?
                                           False, XA_WM_SIZE_HINTS,
                                               &type, &format, &nItems, &bytesLeft, &data);
 
-      props = (XSizeHints*) data;
+      /*
+       * 72 is the number of bytes returned by
+       * sizeof(XSizeHints) on 32 bit platforms.
+       */
 
       if (ret == Success &&
-              ((format >> 3) * nItems) == sizeof(XSizeHints) &&
+              ((format >> 3) * nItems) == 72 &&
                   bytesLeft == 0 &&
                       type == XA_WM_SIZE_HINTS)
       {
@@ -2917,6 +2938,30 @@ FIXME: Do we need to set save unders attribute here?
                     (void*)pWin, pWin -> drawable.id, nxagentWindow(pWin));
         #endif
 
+        #ifdef _XSERVER64
+
+        data64 = (unsigned char *) malloc(sizeof(XSizeHints) + 4);
+
+        for (i = 0; i < 4; i++)
+        {
+          *(data64 + i) = *(data + i);
+        }
+
+        *(((int *) data64) + 1) = 0;
+
+        for (i = 8; i < sizeof(XSizeHints) + 4; i++)
+        {
+          *(data64 + i) = *(data + i - 4);
+        }
+
+        props = (XSizeHints *) data64;
+
+        #else
+
+        props = (XSizeHints *) data;
+
+        #endif   /* _XSERVER64 */
+
         hints = *props;
       }
       else
@@ -2935,6 +2980,15 @@ FIXME: Do we need to set save unders attribute here?
       XSetWMNormalHints(nxagentDisplay,
                            nxagentWindow(pWin),
                               &hints);
+
+      #ifdef _XSERVER64
+
+      if (data64 != NULL)
+      {
+        free(data64);
+      }
+
+      #endif
     }
   }
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
index f77db372d..6fc97b341 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Windows.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
index 967c5656e..7bc1c74cb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
index 967c5656e..7bc1c74cb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index d9da23738..ba4e1e662 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -513,17 +513,6 @@ Dispatch(void)
      * completed. We can now handle our clients.
      */
 
-    if (serverGeneration > nxagentMaxAllowedResets)
-    {
-      #ifdef NX_DEBUG_INPUT
-      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
-      #else
-      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
-      #endif
-
-      nxagentSessionState = SESSION_UP;
-    }
-
     #ifdef XKB
 
     nxagentInitXkbWrapper();
@@ -607,6 +596,21 @@ Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
           clientReady[1] = NXAGENT_WAKEUP;
         }
 
+        if (serverGeneration > nxagentMaxAllowedResets &&
+                nxagentSessionState == SESSION_STARTING &&
+                    (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
+        {
+          #ifdef NX_DEBUG_INPUT
+          fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
+                      GetTimeAsString(), GetTimeInMillis());
+          #else
+          fprintf(stderr, "Session: Session started at '%s'.\n",
+                      GetTimeAsString());
+          #endif
+
+          nxagentSessionState = SESSION_UP;
+        }
+
         #ifdef BLOCKS
         fprintf(stderr, "[End dispatch]\n");
         #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index d9da23738..ba4e1e662 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
@@ -513,17 +513,6 @@ Dispatch(void)
      * completed. We can now handle our clients.
      */
 
-    if (serverGeneration > nxagentMaxAllowedResets)
-    {
-      #ifdef NX_DEBUG_INPUT
-      fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n", GetTimeAsString(), GetTimeInMillis());
-      #else
-      fprintf(stderr, "Session: Session started at '%s'.\n", GetTimeAsString());
-      #endif
-
-      nxagentSessionState = SESSION_UP;
-    }
-
     #ifdef XKB
 
     nxagentInitXkbWrapper();
@@ -607,6 +596,21 @@ Reply   Total	Cached	Bits In			Bits Out		Bits/Reply	  Ratio
           clientReady[1] = NXAGENT_WAKEUP;
         }
 
+        if (serverGeneration > nxagentMaxAllowedResets &&
+                nxagentSessionState == SESSION_STARTING &&
+                    (nxagentOption(Xdmcp) == 0 || nxagentXdmcpUp == 1))
+        {
+          #ifdef NX_DEBUG_INPUT
+          fprintf(stderr, "Session: Session started at '%s' timestamp [%lu].\n",
+                      GetTimeAsString(), GetTimeInMillis());
+          #else
+          fprintf(stderr, "Session: Session started at '%s'.\n",
+                      GetTimeAsString());
+          #endif
+
+          nxagentSessionState = SESSION_UP;
+        }
+
         #ifdef BLOCKS
         fprintf(stderr, "[End dispatch]\n");
         #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
index 4361985fd..225ecdaf8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
index 4361985fd..225ecdaf8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index 467381054..8e87d58c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index 467381054..8e87d58c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
index 9bfb28426..6e67b7ffe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
index 9bfb28426..6e67b7ffe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
index 3d021a0c4..172252b32 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
index 3d021a0c4..172252b32 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index 577659a82..6340de537 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index 577659a82..6340de537 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
index b11b10fb9..d6cd96631 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
index b11b10fb9..d6cd96631 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
index b6d563c6b..e78a1bf14 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
index b6d563c6b..e78a1bf14 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
index 652b85dd7..c71ea8142 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
index 652b85dd7..c71ea8142 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
index 4eabd17f9..efb295861 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
index 4eabd17f9..efb295861 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
index 124356427..d2bead0bc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
index 124356427..d2bead0bc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
index d486d19c5..be1096c6c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
index d486d19c5..be1096c6c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
index 5cd3e5073..18697a576 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
index 5cd3e5073..18697a576 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
index d11e1fe21..b6cee91f1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
index d11e1fe21..b6cee91f1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
index ac61552f0..d02f3f015 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
index ac61552f0..d02f3f015 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
index fa40a4921..e1bb44148 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
index fa40a4921..e1bb44148 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index 7c60d856c..ffc199704 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index 7c60d856c..ffc199704 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
index cffe8008b..8c69217e7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index cffe8008b..8c69217e7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index ef830b73f..b99cbe3e3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index ef830b73f..b99cbe3e3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
index ea133eaae..4022bc397 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
index ea133eaae..4022bc397 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
index 497a62fe0..aa902226e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
index 497a62fe0..aa902226e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
index 5023265e9..5955f1705 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
index 3fce57ff7..e7dee27b1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
index f4d0a2d55..80419d871 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2009 NoMachine, http://www.nomachine.com/.         */
+/* Copyright (c) 2001, 2010 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/screensaver b/nx-X11/programs/Xserver/hw/nxagent/screensaver
index 2fcf5dc87..4c5c10620 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/screensaver
+++ b/nx-X11/programs/Xserver/hw/nxagent/screensaver
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2003 NoMachine, http://www.nomachine.com.          */
+/* Copyright (c) 2001, 2010 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      */
-- 
cgit v1.2.3


From b7494f082ad56049c24927afdf89abc852fe06bb Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:58:59 +0200
Subject: Imported nxagent-3.4.0-8.tar.gz

Summary: Imported nxagent-3.4.0-8.tar.gz
Keywords:

Imported nxagent-3.4.0-8.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |  28 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  56 +++
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 553 +++++++++++++++++----
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |   1 +
 nx-X11/programs/Xserver/hw/nxagent/Imakefile       |   3 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  12 +
 nx-X11/programs/Xserver/hw/nxagent/Pixels.h        |  18 +
 nx-X11/programs/Xserver/hw/nxagent/Pointer.c       |  34 ++
 nx-X11/programs/Xserver/hw/nxagent/Pointer.h       |   9 +
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |   4 +
 nx-X11/programs/Xserver/hw/nxagent/Render.c        | 281 ++++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Render.h        |   2 +
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      |  43 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        | 234 +--------
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |   3 -
 nx-X11/programs/Xserver/hw/nxagent/Window.c        | 269 ++--------
 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c   |  47 +-
 .../Xserver/hw/nxagent/X/NXpicture.c.NX.original   |  47 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |  58 ++-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |  58 ++-
 21 files changed, 1179 insertions(+), 583 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
index 7f12406f5..171df95a9 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -66,19 +66,21 @@ Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
 static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
 {
-  "NX_IDENTITY",          /* 0  */
-  "WM_PROTOCOLS",         /* 1  */
-  "WM_DELETE_WINDOW",     /* 2  */
-  "WM_NX_READY",          /* 3  */
-  "MCOPGLOBALS",          /* 4  */
-  "NX_CUT_BUFFER_SERVER", /* 5  */
-  "TARGETS",              /* 6  */
-  "TEXT",                 /* 7  */
-  "NX_AGENT_SIGNATURE",   /* 8  */
-  "NXDARWIN",             /* 9  */
-  "CLIPBOARD",            /* 10 */
-  "TIMESTAMP",            /* 11 */
-  "UTF8_STRING",          /* 12 */
+  "NX_IDENTITY",              /* 0  */
+  "WM_PROTOCOLS",             /* 1  */
+  "WM_DELETE_WINDOW",         /* 2  */
+  "WM_NX_READY",              /* 3  */
+  "MCOPGLOBALS",              /* 4  */
+  "NX_CUT_BUFFER_SERVER",     /* 5  */
+  "TARGETS",                  /* 6  */
+  "TEXT",                     /* 7  */
+  "NX_AGENT_SIGNATURE",       /* 8  */
+  "NXDARWIN",                 /* 9  */
+  "CLIPBOARD",                /* 10 */
+  "TIMESTAMP",                /* 11 */
+  "UTF8_STRING",              /* 12 */
+  "_NET_WM_STATE",            /* 13 */
+  "_NET_WM_STATE_FULLSCREEN", /* 14 */
   NULL,
   NULL
 };
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
index d8acb9442..f49f2751e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -22,7 +22,7 @@
 #include "../../include/window.h"
 #include "screenint.h"
 
-#define NXAGENT_NUMBER_OF_ATOMS  14
+#define NXAGENT_NUMBER_OF_ATOMS  16
 
 extern Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 1a82e9abf..9e067d407 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,61 @@
 ChangeLog:
 
+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.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index ca21423aa..33eafa55b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -76,7 +76,9 @@
 #include "input.h"
 #endif
 
+#define Time XlibXID
 #include "XKBlib.h"
+#undef Time
 
 #define GC     XlibGC
 #define Font   XlibFont
@@ -203,6 +205,8 @@ CARD32 nxagentLastEventTime     = 0;
 CARD32 nxagentLastKeyPressTime  = 0;
 Time   nxagentLastServerTime    = 0;
 
+int nxagentPointerAndKeyboardGrabbed = 0;
+
 /*
  * Used for storing windows that need to
  * receive expose events from the agent.
@@ -218,6 +222,16 @@ static void nxagentForwardRemoteExpose(void);
 
 static int nxagentClipAndSendExpose(WindowPtr pWin, pointer ptr);
 
+/*
+ * This is from NXproperty.c.
+ */
+
+int GetWindowProperty(WindowPtr pWin, Atom property, long longOffset,
+                          long longLength, Bool delete, Atom type,
+                              Atom *actualType, int *format, unsigned
+                                  long *nItems, unsigned long *bytesAfter,
+                                      unsigned char **propData);
+
 /*
  * Associate a resource to a drawable and
  * store the region affected by the split
@@ -274,6 +288,280 @@ void ProcessInputEvents()
   mieqProcessInputEvents();
 }
 
+#ifdef DEBUG_TREE
+
+/*
+ * Print ID and name of window.
+ */
+
+void nxagentRemoteWindowID(Window window, Bool newline)
+{
+#ifdef NO_I18N
+    char *winName;
+#else
+    XTextProperty tp;
+#endif
+
+  fprintf(stderr, "0x%lx", window);
+
+  if (!window)
+  {
+    fprintf(stderr, " (none) ");
+  }
+  else
+  {
+    if (window == DefaultRootWindow(nxagentDisplay))
+    {
+      fprintf(stderr, " (the root window) ");
+    }
+
+#ifdef NO_I18N
+
+    if (!XFetchName(nxagentDisplay, window, &winName))
+    {
+      fprintf(stderr, " (has no name) ");
+    }
+    else if (winName)
+    {
+      fprintf(stderr, " \"%s\" ", winName);
+      XFree(winName);
+    }
+
+#else
+
+    if (XGetWMName(nxagentDisplay, window, &tp) != 0)
+    {
+      fprintf(stderr, " (has no name) ");
+    }
+    else if (tp.nitems > 0)
+    {
+      int count = 0;
+      int i, ret;
+      char **list = NULL;
+
+      fprintf(stderr, " \"");
+
+      ret = XmbTextPropertyToTextList(nxagentDisplay, &tp, &list, &count);
+
+      if ((ret == Success || ret > 0) && list != NULL)
+      {
+        for (i = 0; i < count; i++)
+        {
+          fprintf(stderr, "%s", list[i]);
+        }
+
+        XFreeStringList(list);
+      }
+      else
+      {
+        fprintf(stderr, "%s", tp.value);
+      }
+
+      fprintf(stderr, "\" ");
+    }
+
+#endif
+
+    else
+    {
+      fprintf(stderr, " (has no name) ");
+    }
+  }
+
+  if (newline == TRUE)
+  {
+    fprintf(stderr, "\n");
+  }
+
+  return;
+}
+
+/*
+ * Print info about remote window.
+ */
+
+void nxagentRemoteWindowInfo(Window win, int indent, Bool newLine)
+{
+  XWindowAttributes attributes;
+  int i;
+
+  if (XGetWindowAttributes(nxagentDisplay, win, &attributes) == 0)
+  {
+    return;
+  }
+
+  for (i = 0; i < indent; i++)
+  {
+    fprintf(stderr, " ");
+  }
+
+  fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
+             "override_redirect=%s\n", attributes.x, attributes.y,
+                 attributes.width, attributes.height, (attributes.class == 0) ?
+                     "InputOutput" : "InputOnly", (attributes.map_state == 0) ?
+                         "IsUnmapped" : (attributes.map_state == 1 ?
+                             "IsUnviewable" : "IsViewable"),
+                                 (attributes.override_redirect == 0) ?
+                                     "No" : "Yes" );
+
+  if (newLine == TRUE)
+  {
+    fprintf(stderr, "\n");
+  }
+}
+
+/*
+ * Walk remote windows tree.
+ */
+
+void nxagentRemoteWindowsTree(Window window, int level)
+{
+  int i, j;
+  Window rootWin, parentWin;
+  unsigned int numChildren;
+  Window *childList;
+
+  if (!XQueryTree(nxagentDisplay, window, &rootWin, &parentWin, &childList,
+                      &numChildren))
+  {
+    fprintf(stderr, "nxagentRemoteWindowsTree - XQueryTree failed.\n");
+
+    return;
+  }
+
+  if (level == 0)
+  {
+    fprintf(stderr, "\n");
+
+    fprintf(stderr, "  Root Window ID: ");
+    nxagentRemoteWindowID(rootWin, TRUE);
+
+    fprintf(stderr, "  Parent window ID: ");
+    nxagentRemoteWindowID(parentWin, TRUE);
+  }
+
+  if (level == 0 || numChildren > 0)
+  {
+    fprintf(stderr, "     ");
+
+    for (j = 0; j < level; j++)
+    {
+      fprintf(stderr, "    ");
+    }
+
+    fprintf(stderr, "%d child%s%s\n", numChildren, (numChildren == 1) ? "" :
+               "ren", (numChildren == 1) ? ":" : ".");
+  }
+
+  for (i = (int) numChildren - 1; i >= 0; i--)
+  {
+    fprintf(stderr, "      ");
+
+    for (j = 0; j < level; j++)
+    {
+      fprintf(stderr, "     ");
+    }
+
+    nxagentRemoteWindowID(childList[i], TRUE);
+
+    nxagentRemoteWindowInfo(childList[i], (level * 5) + 6, TRUE);
+
+    nxagentRemoteWindowsTree(childList[i], level + 1);
+  }
+
+  if (childList)
+  {
+    XFree((char *) childList);
+  }
+}
+
+/*
+ * Print info about internal window.
+ */
+
+void nxagentInternalWindowInfo(WindowPtr pWin, int indent, Bool newLine)
+{
+  int i;
+  int result;
+  unsigned long ulReturnItems;
+  unsigned long ulReturnBytesLeft;
+  Atom          atomReturnType;
+  int           iReturnFormat;
+  unsigned char *pszReturnData = NULL;
+
+  fprintf(stderr, "Window ID=[0x%lx] Remote ID=[0x%lx] ", pWin -> drawable.id,
+             nxagentWindow(pWin));
+
+  result = GetWindowProperty(pWin, MakeAtom("WM_NAME", 7, False) , 0,
+                                sizeof(CARD32), False, AnyPropertyType,
+                                    &atomReturnType, &iReturnFormat,
+                                        &ulReturnItems, &ulReturnBytesLeft,
+                                            &pszReturnData);
+
+  fprintf(stderr, "Name: ");
+
+  if (result == Success && pszReturnData != NULL)
+  {
+    pszReturnData[ulReturnItems] = '\0';
+
+    fprintf(stderr, "\"%s\"\n", (char *) pszReturnData);
+  }
+  else
+  {
+    fprintf(stderr, "%s\n", "( has no name )");
+  }
+
+  for (i = 0; i < indent; i++)
+  {
+    fprintf(stderr, " ");
+  }
+
+  fprintf(stderr, "x=%d y=%d width=%d height=%d class=%s map_state=%s "
+             "override_redirect=%s", pWin -> drawable.x, pWin -> drawable.y,
+                 pWin -> drawable.width, pWin -> drawable.height,
+                     (pWin -> drawable.class == 0) ? "InputOutput" :
+                         "InputOnly", (pWin -> mapped == 0) ?
+                             "IsUnmapped" : (pWin -> mapped == 1 ?
+                                 "IsUnviewable" : "IsViewable"),
+                                     (pWin -> overrideRedirect == 0) ?
+                                         "No" : "Yes");
+
+  if (newLine == TRUE)
+  {
+    fprintf(stderr, "\n");
+  }
+}
+
+/*
+ * Walk internal windows tree.
+ */
+
+void nxagentInternalWindowsTree(WindowPtr pWin, int indent)
+{
+  WindowPtr pChild;
+  int i;
+
+  while (pWin)
+  {
+    pChild = pWin -> firstChild;
+
+    for (i = 0; i < indent; i++)
+    {
+      fprintf(stderr, " ");
+    }
+
+    nxagentInternalWindowInfo(pWin, indent, TRUE);
+
+    fprintf(stderr, "\n");
+
+    nxagentInternalWindowsTree(pChild, indent + 4);
+
+    pWin = pWin -> nextSib;
+  }
+}
+
+#endif /* DEBUG_TREE */
+
 void nxagentSwitchResizeMode(ScreenPtr pScreen)
 {
   XSizeHints sizeHints;
@@ -290,8 +578,11 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentLaunchDialog(DIALOG_DISABLE_DESKTOP_RESIZE_MODE);
 
-    sizeHints.max_width = nxagentOption(RootWidth);
-    sizeHints.max_height = nxagentOption(RootHeight);
+    if (nxagentOption(Fullscreen) == 0)
+    {
+      sizeHints.max_width = nxagentOption(RootWidth);
+      sizeHints.max_height = nxagentOption(RootHeight);
+    }
   }
   else
   {
@@ -299,8 +590,6 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentLaunchDialog(DIALOG_ENABLE_DESKTOP_RESIZE_MODE);
 
-    nxagentRRSetScreenConfig(pScreen, nxagentOption(Width), nxagentOption(Height));
-
     if (nxagentOption(ClientOs) == ClientOsWinnt)
     {
       NXSetExposeParameters(nxagentDisplay, 0, 0, 0);
@@ -655,6 +944,22 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
           {
             break;
           }
+
+          #ifdef DEBUG_TREE
+
+          case doDebugTree:
+          {
+            fprintf(stderr, "\n ========== nxagentRemoteWindowsTree ==========\n");
+            nxagentRemoteWindowsTree(nxagentWindow(WindowTable[0]), 0);
+
+            fprintf(stderr, "\n========== nxagentInternalWindowsTree ==========\n");
+            nxagentInternalWindowsTree(WindowTable[0], 0);
+
+            break;
+          }
+
+          #endif /* DEBUG_TREE */
+
           case doCloseSession:
           {
             closeSession = TRUE;
@@ -797,7 +1102,8 @@ FIXME: Don't enqueue the KeyRelease event if the key was
        enqueued and to remove the KeyPress afterwards.
 */
 
-        if (inputInfo.keyboard -> key -> down[X.xkey.keycode >> 3] & (1 << (X.xkey.keycode & 7)))
+        if (BitIsOn(inputInfo.keyboard -> key -> down,
+                       nxagentConvertKeycode(X.xkey.keycode)))
         {
           sendKey = 1;
         }
@@ -871,6 +1177,23 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
         nxagentInputEvent = 1;
 
+        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
+        {
+          x.u.u.type = ButtonPress;
+          x.u.u.detail = inputInfo.pointer -> button -> map[3];
+          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+          mieqEnqueue(&x);
+
+          x.u.u.type = ButtonRelease;
+          x.u.u.detail = inputInfo.pointer -> button -> map[3];
+          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
+
+          mieqEnqueue(&x);
+
+          break;
+        }
+
         if (nxagentOption(Fullscreen))
         {
           if (nxagentMagicPixelZone(X.xbutton.x, X.xbutton.y))
@@ -917,7 +1240,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
                     X.xbutton.subwindow == None))
         {
           x.u.u.type = ButtonPress;
-          x.u.u.detail = X.xbutton.button;
+          x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]];
           x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
 
           if (nxagentOption(Rootless))
@@ -974,6 +1297,11 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
         nxagentInputEvent = 1;
 
+        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
+        {
+          break;
+        }
+
         if (viewportCursor)
         {
           /*
@@ -990,7 +1318,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
         if (minimize != True)
         {
           x.u.u.type = ButtonRelease;
-          x.u.u.detail = X.xbutton.button;
+          x.u.u.detail = inputInfo.pointer -> button -> map[nxagentReversePointerMap[X.xbutton.button - 1]];
           x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
 
           if (nxagentOption(Rootless))
@@ -1344,10 +1672,11 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           nxagentScreenTrap = 0;
         }
 
-        if (nxagentOption(Fullscreen))
+        if (nxagentOption(Fullscreen) == 1)
         {
-          if (X.xcrossing.window == nxagentFullscreenWindow &&
-                  X.xcrossing.detail != NotifyInferior)
+          if (X.xcrossing.window == nxagentDefaultWindows[0] &&
+                  X.xcrossing.detail != NotifyInferior &&
+                      X.xcrossing.mode == NotifyNormal)
           {
             nxagentGrabPointerAndKeyboard(&X);
           }
@@ -1399,9 +1728,9 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           nxagentLastEnteredWindow = NULL;
         }
 
-        if (nxagentOption(Fullscreen))
+        if (nxagentPointerAndKeyboardGrabbed == 1)
         {
-          if (X.xcrossing.window == nxagentFullscreenWindow &&
+          if (X.xcrossing.window == nxagentDefaultWindows[0] &&
                   X.xcrossing.detail != NotifyInferior &&
                       X.xcrossing.mode == NotifyNormal)
           {
@@ -1660,7 +1989,7 @@ FIXME: Don't enqueue the KeyRelease event if the key was
         }
 
         if (nxagentUseNXTrans == 1 && nxagentOption(Rootless) == 0 &&
-                nxagentOption(Nested) == 0 && X.xmap.window != nxagentIconWindow)
+                nxagentOption(Nested) == 0)
         {
           nxagentVisibility = VisibilityFullyObscured;
         }
@@ -1701,12 +2030,6 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
         if (nxagentOption(Fullscreen) == 1)
         {
-          if (X.xmap.window == nxagentIconWindow)
-          {
-            pScreen = nxagentScreen(X.xmap.window);
-            nxagentMaximizeToFullScreen(pScreen);
-          }
-
           nxagentVisibility = VisibilityUnobscured;
           nxagentVisibilityStop = False;
           nxagentVisibilityTimeout = GetTimeInMillis() + 2000;
@@ -1716,10 +2039,17 @@ FIXME: Don't enqueue the KeyRelease event if the key was
       }
       case MappingNotify:
       {
+        XMappingEvent *mappingEvent = (XMappingEvent *) &X;
+
         #ifdef DEBUG
         fprintf(stderr, "nxagentDispatchEvents: WARNING! Going to handle new MappingNotify event.\n");
         #endif
 
+        if (mappingEvent -> request == MappingPointer)
+        {
+            nxagentInitPointerMap();
+        }
+
         break;
       }
       default:
@@ -1959,8 +2289,16 @@ int nxagentHandleKeyPress(XEvent *X, enum HandleEventResult *result)
     return 1;
   }
 
-  nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
+  if (X -> xkey.keycode == 66)
+  {
+    nxagentXkbState.Caps = (~nxagentXkbState.Caps & 1);
+  }
+  else if (X -> xkey.keycode == 77)
+  {
+    nxagentXkbState.Num = (~nxagentXkbState.Num & 1);
+  }
 
+  nxagentLastEventTime = nxagentLastKeyPressTime = GetTimeInMillis();
   
   x.u.u.type = KeyPress;
   x.u.u.detail = nxagentConvertKeycode(X -> xkey.keycode);
@@ -2270,7 +2608,6 @@ int nxagentHandleGraphicsExposeEvent(XEvent *X)
 
 int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
 {
-  ScreenPtr pScreen;
   WindowPtr pWin;
   xEvent x;
 
@@ -2386,19 +2723,8 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         fprintf(stderr, "Events: WM_DELETE_WINDOW arrived Atom = %ld.\n", wmAtom);
         #endif
 
-        if (X -> xclient.window == nxagentIconWindow)
-        {
-          pScreen = nxagentScreen(X -> xmap.window);
-
-          XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
-
-          XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                             DefaultScreen(nxagentDisplay));
-
-        }
-
-        if (X -> xclient.window == (nxagentOption(Fullscreen) ?
-              nxagentIconWindow : nxagentDefaultWindows[0]))
+        if (X -> xclient.window == nxagentDefaultWindows[0] ||
+                nxagentWMIsRunning == 0)
         {
           *result = doCloseSession;
         }
@@ -2995,85 +3321,110 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
     if (X -> xconfigure.window == nxagentDefaultWindows[pScreen -> myNum])
     {
-      if (nxagentOption(Fullscreen) == 0)
+      if (nxagentOption(DesktopResize) == 1)
       {
-        if (nxagentOption(DesktopResize) == 1)
+        if (nxagentOption(Width) != X -> xconfigure.width ||
+              nxagentOption(Height) != X -> xconfigure.height)
         {
-          if (nxagentOption(Width) != X -> xconfigure.width ||
-                nxagentOption(Height) != X -> xconfigure.height)
-          {
-            Bool newEvents = False;
+          Bool newEvents = False;
 
-            doRandR = True;
+          doRandR = True;
 
-            NXFlushDisplay(nxagentDisplay, NXFlushLink);
+          NXFlushDisplay(nxagentDisplay, NXFlushLink);
 
-            do
-            {
-              newEvents = False;
+          do
+          {
+            newEvents = False;
 
-              timeout.tv_sec  = 0;
-              timeout.tv_usec = 500 * 1000;
+            timeout.tv_sec  = 0;
+            timeout.tv_usec = 500 * 1000;
 
-              nxagentWaitEvents(nxagentDisplay, &timeout);
+            nxagentWaitEvents(nxagentDisplay, &timeout);
 
-              /*
-               * This should also flush
-               * the NX link for us.
-               */
+            /*
+             * This should also flush
+             * the NX link for us.
+             */
 
-              XSync(nxagentDisplay, 0);
+            XSync(nxagentDisplay, 0);
 
-              while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
-                                              ConfigureNotify, X))
-              {
-                newEvents = True;
-              }
+            while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+                                            ConfigureNotify, X))
+            {
+              newEvents = True;
+            }
 
-            } while (newEvents);
-          }
+          } while (newEvents);
         }
+      }
 
-        if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
-        {
-          nxagentChangeOption(X, X -> xconfigure.x);
-          nxagentChangeOption(Y, X -> xconfigure.y);
-        }
+      if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
+      {
+        nxagentChangeOption(X, X -> xconfigure.x);
+        nxagentChangeOption(Y, X -> xconfigure.y);
+      }
 
-        if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
-                (nxagentOption(Width) != X -> xconfigure.width ||
-                    nxagentOption(Height) != X -> xconfigure.height))
-        {
-          nxagentShadowResize = 1;
-        }
+      if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
+              (nxagentOption(Width) != X -> xconfigure.width ||
+                  nxagentOption(Height) != X -> xconfigure.height))
+      {
+        nxagentShadowResize = 1;
+      }
 
-        nxagentChangeOption(Width, X -> xconfigure.width);
-        nxagentChangeOption(Height, X -> xconfigure.height);
+      nxagentChangeOption(Width, X -> xconfigure.width);
+      nxagentChangeOption(Height, X -> xconfigure.height);
 
-        nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
-                                (int) nxagentOption(RootWidth));
-        nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
-                                (int) nxagentOption(RootHeight));
+      nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
+                              (int) nxagentOption(RootWidth));
+      nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
+                              (int) nxagentOption(RootHeight));
 
-        nxagentMoveViewport(pScreen, 0, 0);
+      nxagentMoveViewport(pScreen, 0, 0);
 
-        if (nxagentOption(Shadow) == 1 ||
-                (nxagentOption(Width) == nxagentOption(RootWidth) &&
-                    nxagentOption(Height) == nxagentOption(RootHeight)))
-        {
-          doRandR = 0;
-        }
+      if (nxagentOption(Shadow) == 1 ||
+              (nxagentOption(Width) == nxagentOption(RootWidth) &&
+                  nxagentOption(Height) == nxagentOption(RootHeight)))
+      {
+        doRandR = 0;
+      }
 
-        if (doRandR)
-        {
-          #ifdef TEST
-          fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
-                      nxagentOption(Width), nxagentOption(Height));
-          #endif
+      nxagentChangeOption(Width, X -> xconfigure.width);
+      nxagentChangeOption(Height, X -> xconfigure.height);
 
-          nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
-                                     nxagentOption(Width), nxagentOption(Height));
-        }
+      XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+                            X -> xconfigure.width, X -> xconfigure.height);
+
+      if (nxagentOption(Fullscreen) == 0)
+      {
+        nxagentMoveViewport(pScreen, 0, 0);
+      }
+      else
+      {
+        nxagentChangeOption(RootX, (nxagentOption(Width) -
+                                nxagentOption(RootWidth)) / 2);
+        nxagentChangeOption(RootY, (nxagentOption(Height) -
+                                nxagentOption(RootHeight)) / 2);
+        nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
+                                nxagentOption(RootWidth));
+        nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
+                                nxagentOption(RootHeight));
+
+        nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
+                                       nxagentOption(RootHeight));
+
+        XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                        nxagentOption(RootX), nxagentOption(RootY));
+      }
+
+      if (doRandR)
+      {
+        #ifdef TEST
+        fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
+                    nxagentOption(Width), nxagentOption(Height));
+        #endif
+
+        nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
+                                   nxagentOption(Width), nxagentOption(Height));
       }
 
       return 1;
@@ -3085,8 +3436,6 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
 int nxagentHandleReparentNotify(XEvent* X)
 {
-  ScreenPtr pScreen = nxagentScreen(X -> xreparent.window);
-
   #ifdef TEST
   fprintf(stderr, "nxagentHandleReparentNotify: Going to handle a new reparent event.\n");
   #endif
@@ -3203,7 +3552,6 @@ int nxagentHandleReparentNotify(XEvent* X)
     XlibWindow *childrenReturn = NULL;
     unsigned int nchildrenReturn = 0;
     Status result;
-    XSizeHints hints;
     XWindowAttributes attributes;
     int x, y;
     int xParent, yParent;
@@ -3464,6 +3812,15 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
   XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
                     True, GrabModeAsync, GrabModeAsync, now);
 
+  /*
+   * The smart scheduler could be stopped while
+   * waiting for the reply. In this case we need
+   * to yield explicitly to avoid to be stuck in
+   * the dispatch loop forever.
+   */
+
+  isItTimeToYield = 1;
+
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the pointer in context [B2].\n");
   #endif
@@ -3491,6 +3848,8 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
     XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
                        RevertToParent, now);
   }
+
+  nxagentPointerAndKeyboardGrabbed = 1;
 }
 
 void nxagentUngrabPointerAndKeyboard(XEvent *X)
@@ -3522,6 +3881,8 @@ void nxagentUngrabPointerAndKeyboard(XEvent *X)
   #endif
 
   XUngrabPointer(nxagentDisplay, now);
+
+  nxagentPointerAndKeyboardGrabbed = 0;
 }
 
 void nxagentDeactivatePointerGrab()
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index 238a229f9..109475c16 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -29,6 +29,7 @@ enum HandleEventResult
 {
   doNothing = 0,
   doMinimize,
+  doDebugTree,
   doCloseSession,
   doStartKbd,
   doSwitchFullscreen,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
index 633e17a22..51173e410 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile
+++ b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
@@ -206,7 +206,8 @@ DEFINES = -g $(OS_DEFINES) $(EXT_DEFINES) $(UPG_DEFINES) \
           -DNXAGENT_SPLASH \
           -DNXAGENT_ARTSD \
           -UNX_DEBUG_INPUT \
-          -UPANORAMIX
+          -UPANORAMIX \
+          -UDEBUG_TREE
 
 all:: $(OBJS)
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index a2e4fb06f..de1da8654 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -92,6 +92,18 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
   {
     switch (sym)
     {
+      #ifdef DEBUG_TREE
+
+      case XK_q:
+      case XK_Q:
+      {
+        *result = doDebugTree;
+
+        break;
+      }
+
+      #endif /* DEBUG_TREE */
+
       case XK_t:
       case XK_T:
       {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
index e046771cc..ea7c375ee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -108,6 +108,12 @@ FIXME: The condition checking for the render
        avoid problems with the render composi-
        te on XFree86 remote server.
 */
+/*
+FIXME: Changed macro: NXAGENT_SHOULD_DEFER_COMPOSITE
+       to handle situation, when pSrc -> pDrawable
+       is NULL. This case happens with gradients
+       and solid fill.
+
 #define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)                 \
     ((nxagentRenderVersionMajor == 0 &&                                   \
      nxagentRenderVersionMinor == 8 &&                                \
@@ -118,6 +124,18 @@ FIXME: The condition checking for the render
           nxagentOption(DeferLevel) == 1) ||               \
              (nxagentOption(DeferLevel) >= 2 &&           \
               nxagentOption(LinkType) < LINK_TYPE_ADSL))
+*/
+#define NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)                                                \
+    ((nxagentRenderVersionMajor == 0 &&                                                                  \
+      nxagentRenderVersionMinor == 8 &&                                                                  \
+      (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP) ||                                                 \
+         (nxagentOption(DeferLevel) >= 2 &&                                                              \
+          nxagentOption(LinkType) < LINK_TYPE_ADSL) ||                                                   \
+             (nxagentOption(DeferLevel) == 1 &&                                                          \
+              (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP &&                                          \
+              (((pSrc) -> pDrawable && nxagentDrawableStatus((pSrc) -> pDrawable) == NotSynchronized) || \
+              ((pMask) && nxagentDrawableStatus((pMask) -> pDrawable) == NotSynchronized))))
+
 
 #define NXAGENT_SHOULD_DEFER_PUTIMAGE(pDrawable) \
     (nxagentSplitTrap == 0 &&                    \
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
index 34012d3d5..9c1bfaace 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -57,6 +57,13 @@ is" without express or implied warranty.
 #undef  TEST
 #undef  DEBUG
 
+/*
+ * The nxagentReversePointerMap array is used to
+ * memorize remote display pointer map.
+ */
+
+unsigned char nxagentReversePointerMap[MAXBUTTONS];
+
 void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl)
 {
   /*
@@ -125,6 +132,8 @@ int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
         return Success;
       }
 
+      nxagentInitPointerMap();
+
       nxagentEnablePointerEvents();
 
       break;
@@ -155,3 +164,28 @@ int nxagentPointerProc(DeviceIntPtr pDev, int onoff)
 
   return Success;
 }
+
+void nxagentInitPointerMap(void)
+{
+  int numButtons;
+
+  int i;
+
+  unsigned char pointerMap[MAXBUTTONS];
+
+  #ifdef DEBUG
+  fprintf(stderr, "nxagentInitPointerMap: Going to retrieve the "
+              "pointer map from remote display.\n");
+  #endif
+
+  numButtons = XGetPointerMapping(nxagentDisplay, pointerMap, MAXBUTTONS);
+
+  /*
+   * Computing revers pointer map.
+   */
+
+  for (i = 1; i <= numButtons; i++)
+  {
+    nxagentReversePointerMap[pointerMap[i - 1] - 1] = i;
+  }
+}
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
index 0807b08ae..b0bb3f99c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -38,8 +38,17 @@ is" without express or implied warranty.
   (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
        EnterWindowMask | LeaveWindowMask)
 
+/*
+ * The nxagentReversePointerMap array is used to
+ * memorize remote display pointer map.
+ */
+
+extern unsigned char nxagentReversePointerMap[MAXBUTTONS];
+
 void nxagentChangePointerControl(DeviceIntPtr pDev, PtrCtrl *ctrl);
 
 int nxagentPointerProc(DeviceIntPtr pDev, int onoff);
 
+void nxagentInitPointerMap(void);
+
 #endif /* __Pointer_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index 598ffc188..e63b481b2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -81,6 +81,8 @@ extern Bool nxagentUninstallFontServerPath(void);
 
 extern void nxagentRemoveXConnection(void);
 
+extern void nxagentInitPointerMap(void);
+
 static char *nxagentGetReconnectError(void);
 
 void nxagentInitializeRecLossyLevel(void);
@@ -584,6 +586,8 @@ Bool nxagentReconnectSession(void)
     nxagentOldKeyboard = NULL;
   }
 
+  nxagentInitPointerMap();
+
   nxagentDeactivatePointerGrab();
 
   nxagentWakeupByReconnect();
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index 6bc54c86e..4f0f76474 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -147,8 +147,6 @@ void nxagentCursorPostSaveRenderInfo(CursorPtr pCursor, ScreenPtr pScreen,
 
 int nxagentCreatePicture(PicturePtr pPicture, Mask mask);
 
-void nxagentDestroyPicture(PicturePtr pPicture);
-
 int nxagentChangePictureClip(PicturePtr pPicture, int clipType, int nRects,
                                  xRectangle *rects, int xOrigin, int yOrigin);
 
@@ -1010,12 +1008,15 @@ void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pD
 
   #ifdef DEBUG
 
-  fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
-              nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
-              (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
-                   nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
-                       pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
-                           (void *) pSrc -> pDrawable);
+  if (pSrc -> pDrawable != NULL)
+  {
+    fprintf(stderr, "nxagentComposite: Source Picture [%lu][%p] with drawable [%s%s][%p].\n",
+                nxagentPicturePriv(pSrc) -> picture, (void *) pSrc,
+                (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                     nxagentIsShmPixmap((PixmapPtr) pSrc -> pDrawable)) ? "Shared " : "",
+                         pSrc -> pDrawable -> type == DRAWABLE_PIXMAP ? "Pixmap" : "Window",
+                             (void *) pSrc -> pDrawable);
+  }
 
   fprintf(stderr, "nxagentComposite: Destination Picture [%lu][%p] with drawable [%s%s][%p].\n",
               nxagentPicturePriv(pDst) -> picture, (void *) pDst,
@@ -1064,16 +1065,19 @@ void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pD
    * the wrong data.
    */
 
-  nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
-
-  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  if (pSrc -> pDrawable != NULL)
   {
-    #ifdef TEST
-    fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
-                (void *) pSrc -> pDrawable);
-    #endif
+    nxagentSynchronizeShmPixmap(pSrc -> pDrawable, xSrc, ySrc, width, height);
 
-    nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+    if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentComposite: Synchronizing the source drawable [%p].\n",
+                  (void *) pSrc -> pDrawable);
+      #endif
+
+      nxagentSynchronizeDrawable(pSrc -> pDrawable, DO_WAIT, NEVER_BREAK, NULL);
+    }
   }
 
   if (pDst -> pDrawable != pSrc -> pDrawable)
@@ -2811,3 +2815,248 @@ Bool nxagentDisconnectAllPicture()
   return True;
 }
 
+void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color)
+{
+  Picture id;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateSolidFill: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (color == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateSolidFill: WARNING! color pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+             sizeof(XRenderPictureAttributes_));
+
+  id = XRenderCreateSolidFill(nxagentDisplay, (XRenderColor *) color);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateSolidFill: Created solid fill xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+                                           xPointFixed *p2, int nStops,
+                                               xFixed *stops,
+                                                   xRenderColor *colors)
+{
+  Picture id;
+
+  XLinearGradient linearGradient;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateLinearGradient: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (p1 == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p1 pointer is NULL.\n");
+  }
+
+  if (p2 == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! p2 pointer is NULL.\n");
+  }
+
+  if (stops == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! stops pointer is NULL.\n");
+  }
+
+  if (colors == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateLinearGradient: WARNING! colors pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+             sizeof(XRenderPictureAttributes_));
+
+  linearGradient.p1.x = (XFixed) p1 -> x;
+  linearGradient.p1.y = (XFixed) p1 -> y;
+  linearGradient.p2.x = (XFixed) p2 -> x;
+  linearGradient.p2.y = (XFixed) p2 -> y;
+
+  id = XRenderCreateLinearGradient(nxagentDisplay, &linearGradient,
+                                      (XFixed *) stops,
+                                          (XRenderColor *) colors, nStops);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateLinearGradient: Created linear gradient xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+                                           xPointFixed *outer,
+                                               xFixed innerRadius,
+                                                   xFixed outerRadius,
+                                                       int nStops,
+                                                           xFixed *stops,
+                                                               xRenderColor *colors)
+{
+  Picture id;
+
+  XRadialGradient radialGradient;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateRadialGradient: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (inner == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! inner pointer is NULL.\n");
+  }
+
+  if (outer == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! outer pointer is NULL.\n");
+  }
+
+  if (stops == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! stops pointer is NULL.\n");
+  }
+
+  if (colors == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateRadialGradient: WARNING! colors pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+               sizeof(XRenderPictureAttributes_));
+
+  radialGradient.inner.x = (XFixed) inner -> x;
+  radialGradient.inner.y = (XFixed) inner -> y;
+  radialGradient.inner.radius = (XFixed) innerRadius;
+  radialGradient.outer.x = (XFixed) outer -> x;
+  radialGradient.outer.y = (XFixed) outer -> y;
+  radialGradient.outer.radius = (XFixed) outerRadius;
+
+  id = XRenderCreateRadialGradient(nxagentDisplay, &radialGradient,
+                                       (XFixed *) stops,
+                                           (XRenderColor *) colors, nStops);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateRadialGradient: Created radial gradient xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
+void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+                                            xPointFixed *center,
+                                                xFixed angle, int nStops, 
+                                                    xFixed *stops, 
+                                                        xRenderColor *colors)
+{
+  Picture id;
+
+  XConicalGradient conicalGradient;
+
+  if (nxagentRenderEnable == False)
+  {
+    return;
+  }
+
+  #ifdef DEBUG
+
+  fprintf(stderr, "nxagentRenderCreateConicalGradient: Got called.\n");
+
+  if (pPicture == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! pPicture pointer is NULL.\n");
+  }
+
+  if (center == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! center pointer is NULL.\n");
+  }
+
+  if (stops == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! stops pointer is NULL.\n");
+  }
+
+  if (colors == NULL)
+  {
+    fprintf(stderr, "nxagentRenderCreateConicalGradient: WARNING! colors pointer is NULL.\n");
+  }
+
+  #endif /* #ifdef DEBUG */
+
+  memset(&(nxagentPicturePriv(pPicture) -> lastServerValues), 0,
+             sizeof(XRenderPictureAttributes_));
+
+  conicalGradient.center.x = (XFixed) center -> x;
+  conicalGradient.center.y = (XFixed) center -> y;
+  conicalGradient.angle = (XFixed) angle;
+
+  id = XRenderCreateConicalGradient(nxagentDisplay, &conicalGradient,
+                                        (XFixed *) stops,
+                                            (XRenderColor *) colors, nStops);
+
+  #ifdef DEBUG
+  XSync(nxagentDisplay, 0);
+  #endif
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentRenderCreateConicalGradient: Created conical gradient xid [%lu].\n", id);
+  #endif
+
+  nxagentPicturePriv(pPicture) -> picture = id;
+}
+
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
index 81ba3369d..4346a4e1e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -105,4 +105,6 @@ void nxagentDisconnectPicture(pointer p0, XID x1, void* p2);
 
 void nxagentReconnectGlyphSet(void* p0, XID x1, void *p2);
 
+void nxagentDestroyPicture(PicturePtr pPicture);
+
 #endif /* __Render_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index a8ce4c7cd..612e71cf7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -626,6 +626,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     XlibAtom *atoms = malloc(nUnits * sizeof(*atoms));
     Atom *input = value;
     int i;
+    int j = 0;
 
     freeMem = True;
     export = True;
@@ -633,16 +634,40 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
 
     for (i = 0; i < nUnits; i++)
     {
-       atoms[i] = nxagentLocalToRemoteAtom(input[i]);
-
-       if (atoms[i] == None)
-       {
-         #ifdef WARNING
-         fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
-                     (long int) input[i], validateString(NameForAtom(input[i])));
-         #endif
-       }
+      /*
+       * Exporting the _NET_WM_PING property could
+       * result in rootless windows being grayed out
+       * when the compiz window manager is running.
+       *
+       * Better solution would probably be to handle
+       * the communication with the window manager
+       * instead of just getting rid of the property.
+       */
+
+      if (strcmp(NameForAtom(input[i]), "_NET_WM_PING") != 0)
+      {
+        atoms[j] = nxagentLocalToRemoteAtom(input[i]);
+
+        if (atoms[j] == None)
+        {
+          #ifdef WARNING
+          fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
+                      (long int) input[i], validateString(NameForAtom(input[i])));
+          #endif
+        }
+
+        j++;
+      }
+      #ifdef TEST
+      else
+      {
+        fprintf(stderr, "nxagentExportProperty: WARNING! "
+                    "Not exporting the _NET_WM_PING property.\n");
+      }
+      #endif
     }
+
+    nUnits = j;
   }
   else if (strcmp(typeS, "WINDOW") == 0)
   {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index bdd30afee..3522d7e2e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -160,7 +160,6 @@ void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
 
 #endif
 
-Window nxagentIconWindow = None;
 Window nxagentFullscreenWindow = None;
 
 #ifdef VIEWPORT_FRAME
@@ -291,33 +290,16 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
 void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
 {
   XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
-
-  if(nxagentIpaq)
-  {
-    XMapWindow(nxagentDisplay, nxagentIconWindow);
-    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                       DefaultScreen(nxagentDisplay));
-  }
-  else
-  {
-    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                       DefaultScreen(nxagentDisplay));
-  }
 }
 
 void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
 {
   if(nxagentIpaq)
   {
-    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
-
     XMapWindow(nxagentDisplay, nxagentFullscreenWindow);
   }
   else
   {
-/*
-    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
-*/
 /*
 FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWindow()
        in order to avoid the session window is iconified.
@@ -352,100 +334,8 @@ FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWind
 
     XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
 
-    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                       DefaultScreen(nxagentDisplay));
-
     while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
-/*
-    XMapWindow(nxagentDisplay, nxagentIconWindow);
-*/
-  }
-}
-
-Window nxagentCreateIconWindow()
-{
-  XSetWindowAttributes attributes;
-  unsigned long valuemask;
-  char* window_name;
-  XTextProperty windowName;
-  XSizeHints sizeHints;
-  XWMHints wmHints;
-  Window w;
-  Mask mask;
-
-  /*
-   * Create icon window.
-   */
-
-  attributes.override_redirect = False;
-  attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
-  attributes.background_pixmap = nxagentScreenSaverPixmap;
-  valuemask = CWOverrideRedirect | CWBackPixmap | CWColormap;
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentCreateIconWindow: Going to create new icon window.\n");
-  #endif
-
-  w = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
-                        0, 0, 1, 1, 0,
-                            DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)),
-                                InputOutput,
-                                    DefaultVisual(nxagentDisplay, DefaultScreen(nxagentDisplay)),
-                                        valuemask, &attributes);
-
-  #ifdef TEST
-  fprintf(stderr, "nxagentCreateIconWindow: Created new icon window with id [%ld].\n",
-              nxagentIconWindow);
-  #endif
-
-  /*
-   *  Set hints to the window manager for the icon window.
-   */
-
-  window_name = nxagentWindowName;
-  XStringListToTextProperty(&window_name, 1, &windowName);
-  sizeHints.flags = PMinSize | PMaxSize;
-  sizeHints.min_width = sizeHints.max_width = 1;
-  sizeHints.min_height = sizeHints.max_height = 1;
-  wmHints.flags = IconPixmapHint | IconMaskHint;
-  wmHints.initial_state = IconicState;
-  wmHints.icon_pixmap = nxagentIconPixmap;
-
-  if (useXpmIcon)
-  {
-    wmHints.icon_mask = nxagentIconShape;
-    wmHints.flags = IconPixmapHint | IconMaskHint;
   }
-  else
-  {
-    wmHints.flags = StateHint | IconPixmapHint;
-  }
-
-  XSetWMProperties(nxagentDisplay, w,
-                      &windowName, &windowName,
-                          NULL , 0 , &sizeHints, &wmHints, NULL);
-
-  /*
-   * Enable events from the icon window.
-   */
-
-  nxagentGetDefaultEventMask(&mask);
-
-  XSelectInput(nxagentDisplay, w, (mask & ~(KeyPressMask |
-                   KeyReleaseMask)) | StructureNotifyMask);
-
-  /*
-   * Notify to client if user closes icon window.
-   */
-
-  if (nxagentWMIsRunning && !nxagentOption(Rootless))
-  {
-    XlibAtom deleteWMAtom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
-
-    XSetWMProtocols(nxagentDisplay, w, &deleteWMAtom, 1);
-  }
-
-  return w;
 }
 
 Bool nxagentMagicPixelZone(int x, int y)
@@ -977,6 +867,8 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
 
     nxagentChangeOption(Fullscreen, False);
 
+    nxagentFullscreenWindow = 0;
+
     resetAgentPosition = True;
   }
 
@@ -1382,8 +1274,6 @@ N/A
 
     if (nxagentOption(Fullscreen))
     {
-      attributes.override_redirect = True;
-
       /*
        * We need to disable the host's screensaver or
        * it will otherwise grab the screen even if it
@@ -1609,8 +1499,7 @@ N/A
   if (nxagentDoFullGeneration == 1 ||
           nxagentReconnectTrap == 1)
   {
-    valuemask = CWBackPixel | CWEventMask | CWColormap |
-                    (nxagentOption(Fullscreen) == 1 ? CWOverrideRedirect : 0);
+    valuemask = CWBackPixel | CWEventMask | CWColormap;
 
     attributes.background_pixel = nxagentBlackPixel;
 
@@ -1620,8 +1509,6 @@ N/A
 
     if (nxagentOption(Fullscreen) == 1)
     {
-      attributes.override_redirect = True;
-
       if (nxagentReconnectTrap)
       {
         /*
@@ -1754,7 +1641,7 @@ N/A
     sizeHints.width = nxagentOption(RootWidth);
     sizeHints.height = nxagentOption(RootHeight);
 
-    if (nxagentOption(DesktopResize) == 1)
+    if (nxagentOption(DesktopResize) == 1 || nxagentOption(Fullscreen) == 1)
     {
       sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
       sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
@@ -1799,37 +1686,6 @@ N/A
 
     XClearWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
 
-    if (nxagentOption(Fullscreen))
-    {
-      valuemask = CWBackPixmap | CWColormap | CWOverrideRedirect;
-    }
-    else
-    {
-      valuemask = CWBackPixmap | CWColormap;
-    }
-
-    attributes.background_pixmap = nxagentScreenSaverPixmap;
-    attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
-
-    if (nxagentOption(Fullscreen))
-    {
-      attributes.override_redirect = False;
-      if (nxagentReconnectTrap)
-      {
-        XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, True, GrabModeAsync,
-                      GrabModeAsync, CurrentTime);
-      }
-    }
-
-    if (nxagentOption(Fullscreen))
-    {
-      nxagentIconWindow = nxagentCreateIconWindow();
-    }
-    else
-    {
-      nxagentIconWindow = 0;
-    }
-
     /*
      * When we don't have window manager we grab keyboard
      * to let nxagent get keyboard events.
@@ -1880,13 +1736,6 @@ N/A
        */
 
       XSetWMProtocols(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum], &deleteWMatom, 1);
-
-      /*
-      if (nxagentOption(Fullscreen))
-      {
-        XSetWMProtocols(nxagentDisplay, nxagentIconWindow, &deleteWMatom, 1);
-      }
-      */
     }
     else
     {
@@ -2266,13 +2115,10 @@ FIXME: We should try to restore the previously
 
   if (nxagentOption(Fullscreen))
   {
-    nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-    nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-
-    nxagentChangeOption(RootX, (WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
-                            - nxagentOption(RootWidth)) / 2);
-    nxagentChangeOption(RootY,  (HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay))
-                            - nxagentOption(RootHeight)) / 2);
+    nxagentChangeOption(RootX, (nxagentOption(Width) -
+                            nxagentOption(RootWidth)) / 2);
+    nxagentChangeOption(RootY, (nxagentOption(Height) -
+                            nxagentOption(RootHeight)) / 2);
   }
   else
   {
@@ -2283,62 +2129,6 @@ FIXME: We should try to restore the previously
   nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
   nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
 
-  /*
-   * Change agent window size and size hints.
-   */
-
-  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);
-
-  if (nxagentOption(Fullscreen))
-  {
-    XResizeWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
-                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
-                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-
-    XResizeWindow(nxagentDisplay, nxagentInputWindows[pScreen -> myNum],
-                      WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
-                          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-  }
-  else
-  {
-    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.
    */
@@ -2360,8 +2150,6 @@ FIXME: We should try to restore the previously
 
   (*pScreen -> PositionWindow)(WindowTable[pScreen -> myNum], 0, 0);
 
-  pRootWinSize = &WindowTable[pScreen -> myNum] -> winSize;
-
   nxagentSetRootClip(pScreen, 1);
 
   XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[0]),
@@ -2369,6 +2157,12 @@ FIXME: We should try to restore the previously
 
   nxagentMoveViewport(pScreen, 0, 0);
 
+  /*
+   * Update pointer bounds.
+   */
+
+  ScreenRestructured(pScreen);
+
   #ifdef TEST
   nxagentPrintAgentGeometry("After Resize Screen", "nxagentResizeScreen:");
   #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 6ffebe0ea..3bf66b2f5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -47,7 +47,6 @@ extern ScreenPtr nxagentDefaultScreen;
 
 extern Pixmap nxagentPixmapLogo;
 
-extern Window nxagentIconWindow;
 extern Window nxagentFullscreenWindow;
 
 extern RegionRec nxagentShadowUpdateRegion;
@@ -89,8 +88,6 @@ void nxagentSetScreenSaverTime(void);
 void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
 void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
 
-Window nxagentCreateIconWindow(void);
-
 Bool nxagentMagicPixelZone(int x, int y);
 
 Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 449458ade..2403390b8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -692,235 +692,87 @@ void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
 
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 {
-  Window w;
-  XSetWindowAttributes attributes;
-  unsigned long valuemask;
+  XEvent e;
+  XSizeHints sizeHints;
 
-  if (nxagentOption(Rootless))
+  if (nxagentOption(Rootless) == 1)
   {
     return;
   }
 
-  if (!switchOn)
+  if (switchOn == 0)
   {
     nxagentWMDetect();
 
-    if (!nxagentWMIsRunning)
-    {
-      #ifdef WARNING
-      fprintf(stderr, "Warning: Can't switch to window mode, no window manager has been detected.\n");
-      #endif
-
-      return;
-    }
-  }
-
-  w = nxagentDefaultWindows[pScreen -> myNum];
-  attributes.override_redirect = switchOn;
-  valuemask = CWOverrideRedirect;
-  XUnmapWindow(nxagentDisplay, w);
-  XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
-
-  if (switchOn)
-  {
-    /*
-     * Change to fullscreen mode.
-     */
-
-    struct timeval timeout;
-    int i;
-    XEvent e;
-
     /*
-     * Wait for window manager reparenting the default window.
+     * The smart scheduler could be stopped while
+     * waiting for the reply. In this case we need
+     * to yield explicitly to avoid to be stuck in
+     * the dispatch loop forever.
      */
 
-    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
-      #endif
-
-      if (XCheckTypedWindowEvent(nxagentDisplay, w, ReparentNotify, &e))
-      {
-        break;
-      }
-
-      /*
-       * This should also flush
-       * the NX link for us.
-       */
-
-      XSync(nxagentDisplay, 0);
-
-      timeout.tv_sec  = 0;
-      timeout.tv_usec = 50 * 1000;
-
-      nxagentWaitEvents(nxagentDisplay, &timeout);
-    }
-
-    if (i < 100)
-    {
-      /*
-       * The window manager has done with the reparent
-       * operation. We can resize and map the window.
-       */
-
-      nxagentChangeOption(Fullscreen, True);
-
-      /*
-       * Save the window-mode configuration.
-       */
-
-      nxagentChangeOption(SavedX, nxagentOption(X));
-      nxagentChangeOption(SavedY, nxagentOption(Y));
-      nxagentChangeOption(SavedWidth, nxagentOption(Width));
-      nxagentChangeOption(SavedHeight, nxagentOption(Height));
-      nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
-      nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
-
-      /*
-       * Reconf the Default window.
-       */
-
-      nxagentChangeOption(X, 0);
-      nxagentChangeOption(Y, 0);
-      nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-      nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-
-      /*
-       * Move the root window.
-       */
-
-      nxagentChangeOption(RootX, (nxagentOption(Width) - nxagentOption(RootWidth)) / 2);
-      nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) / 2);
-      nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
-      nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
-
-      XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
-                            nxagentOption(Width), nxagentOption(Height));
-
-      nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight));
-
-      XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
-                      nxagentOption(RootX), nxagentOption(RootY));
-
-      /*
-       * We disable the screensaver when changing
-       * mode to fullscreen. Is it really needed?
-       */
-
-      XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+    isItTimeToYield = 1;
 
-      if (nxagentIconWindow == None)
-      {
-        nxagentIconWindow = nxagentCreateIconWindow();
-
-        XMapWindow(nxagentDisplay, nxagentIconWindow);
-      }
-
-      XMapRaised(nxagentDisplay, w);
-      XSetInputFocus(nxagentDisplay, w, RevertToParent, CurrentTime);
-      XCheckTypedWindowEvent(nxagentDisplay, w, LeaveNotify, &e);
-      nxagentFullscreenWindow = w;
-
-      if (nxagentOption(DesktopResize) == 1)
-      {
-        if (nxagentOption(Shadow) == 0)
-        {
-          nxagentRRSetScreenConfig(pScreen, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
-                                       HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
-        }
-        else
-        {
-          nxagentShadowAdaptToRatio();
-        }
-      }
-    }
-    else
+    if (nxagentWMIsRunning == 0)
     {
-      /*
-       * We have waited for a reparent event unsuccessfully.
-       * Something happened to the window manager.
-       */
-
       #ifdef WARNING
-      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Expected ReparentNotify event missing.\n");
+      fprintf(stderr, "Warning: Can't switch to window mode, no window manager "
+                  "has been detected.\n");
       #endif
 
-      nxagentWMIsRunning = False;
-      attributes.override_redirect = False;
-      XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
-      XMapWindow(nxagentDisplay, w);
+      return;
     }
   }
-  else
-  {
-    /*
-     * FIXME:
-     * It could be necessary:
-     * - To restore screensaver.
-     * - To set or reset nxagentForceBackingStore flag.
-     * - To grab keyboard.
-     * - To propagate device settings to the X server if no WM is running.
-     */
-
-    /*
-     * Change to windowed mode.
-     */
 
-    nxagentChangeOption(Fullscreen, False);
-    XDestroyWindow(nxagentDisplay, nxagentIconWindow);
-    nxagentIconWindow = nxagentFullscreenWindow = None;
+  #ifdef TEST
+  fprintf(stderr, "nxagentSwitchFullscreen: Switching to %s mode.\n",
+              switchOn ? "fullscreen" : "windowed");
+  #endif
 
-    if (nxagentOption(DesktopResize) == 1)
-    {
-      nxagentChangeOption(RootWidth, nxagentOption(SavedRootWidth));
-      nxagentChangeOption(RootHeight, nxagentOption(SavedRootHeight));
+  nxagentChangeOption(Fullscreen, switchOn);
 
-      if (nxagentOption(Shadow) == 0)
-      {
-        nxagentRRSetScreenConfig(pScreen, nxagentOption(RootWidth), nxagentOption(RootHeight));
-      }
-    }
+  if (nxagentOption(DesktopResize) == 1)
+  {
+    sizeHints.flags = PSize;
 
-    if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0)
+    if (switchOn == 1)
     {
-      nxagentChangeOption(X, nxagentOption(SavedX) -
-                              nxagentOption(WMBorderWidth));
-      nxagentChangeOption(Y, nxagentOption(SavedY) -
-                              nxagentOption(WMTitleHeight));
+      sizeHints.width =
+          WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
+      sizeHints.height =
+          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
     }
     else
     {
-      nxagentChangeOption(X, nxagentOption(SavedX));
-      nxagentChangeOption(Y, nxagentOption(SavedY));
+      sizeHints.width = nxagentOption(RootWidth);
+      sizeHints.height = nxagentOption(RootHeight);
     }
 
-    nxagentChangeOption(Width, nxagentOption(SavedWidth));
-    nxagentChangeOption(Height, nxagentOption(SavedHeight));
-
-    if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1)
-    {
-      nxagentShadowAdaptToRatio();
-    }
+    XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+                         &sizeHints);
+  }
 
-    XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
-                          nxagentOption(Width), nxagentOption(Height));
+  memset(&e, 0, sizeof(e));
 
-    nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height));
+  e.xclient.type = ClientMessage;
+  e.xclient.message_type = nxagentAtoms[13]; /* _NET_WM_STATE */
+  e.xclient.display = nxagentDisplay;
+  e.xclient.window = nxagentDefaultWindows[pScreen -> myNum];
+  e.xclient.format = 32;
+  e.xclient.data.l[0] = nxagentOption(Fullscreen) ? 1 : 0;
+  e.xclient.data.l[1] = nxagentAtoms[14]; /* _NET_WM_STATE_FULLSCREEN */
 
-    XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), 0, 0);
-    XMapWindow(nxagentDisplay, w);
+  XSendEvent(nxagentDisplay, DefaultRootWindow(nxagentDisplay), False,
+                 SubstructureRedirectMask, &e);
 
-    nxagentChangeOption(RootX, 0);
-    nxagentChangeOption(RootY, 0);
+  if (switchOn == 1)
+  {
+    nxagentFullscreenWindow = nxagentDefaultWindows[pScreen -> myNum];
   }
-
-  XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
-                        nxagentOption(Width), nxagentOption(Height));
-
-  nxagentSetPrintGeometry(pScreen -> myNum);
+  else
+  {
+    nxagentFullscreenWindow = None;
+  } 
 }
 
 #ifdef VIEWPORT_FRAME
@@ -2422,6 +2274,11 @@ void nxagentMapDefaultWindows()
         #endif
 
         XMapWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
+
+        if (nxagentOption(Fullscreen) == 1 && nxagentWMIsRunning == 1)
+        {
+          nxagentSwitchFullscreen(pScreen, 1);
+        }
       }
 
       /*
@@ -2451,26 +2308,6 @@ void nxagentMapDefaultWindows()
                            nxagentDefaultWindows[i], CurrentTime);
   }
 
-  /*
-   * Map the icon window.
-   */
-
-  if (nxagentIconWindow != 0)
-  {
-    #ifdef TEST
-    fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
-                nxagentIconWindow);
-    #endif
-
-    XMapWindow(nxagentDisplay, nxagentIconWindow);
-
-    if (nxagentIpaq != 0)
-    {
-      XIconifyWindow(nxagentDisplay, nxagentIconWindow,
-                         DefaultScreen(nxagentDisplay));
-    }
-  }
-
   /*
    * Ensure that the fullscreen window gets the focus.
    */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
index 18697a576..be961c400 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -62,6 +62,7 @@
 #include "Screen.h"
 #include "Pixmaps.h"
 #include "Drawable.h"
+#include "Render.h"
 
 #define PANIC
 #define WARNING
@@ -1063,7 +1064,47 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
 static PicturePtr createSourcePicture(void)
 {
     PicturePtr pPicture;
-    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+
+    extern int nxagentPicturePrivateIndex;
+
+    unsigned int totalPictureSize;
+
+    DevUnion *ppriv;
+
+    char *privPictureRecAddr;
+
+    int i;
+
+    /*
+     * Compute size of entire PictureRect, plus privates.
+     */
+
+    totalPictureSize = sizeof(PictureRec) +
+                           picturePrivateCount * sizeof(DevUnion) +
+                               sizeof(nxagentPrivPictureRec);
+
+    pPicture = (PicturePtr) xalloc(totalPictureSize);
+
+    if (pPicture != NULL)
+    {
+      ppriv = (DevUnion *) (pPicture + 1);
+
+      for (i = 0; i < picturePrivateCount; ++i)
+      {
+        /*
+         * Other privates are inaccessible.
+         */
+
+        ppriv[i].ptr = NULL;
+      }
+
+      privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
+
+      ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
+
+      pPicture -> devPrivates = ppriv;
+    }
+
     pPicture->pDrawable = 0;
     pPicture->pFormat = 0;
     pPicture->pNext = 0;
@@ -1697,6 +1738,10 @@ FreePicture (pointer	value,
 
     if (--pPicture->refcnt == 0)
     {
+#ifdef NXAGENT_SERVER
+        nxagentDestroyPicture(pPicture);
+#endif
+
 	if (pPicture->transform)
 	    xfree (pPicture->transform);
         if (!pPicture->pDrawable) {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
index 18697a576..be961c400 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -62,6 +62,7 @@
 #include "Screen.h"
 #include "Pixmaps.h"
 #include "Drawable.h"
+#include "Render.h"
 
 #define PANIC
 #define WARNING
@@ -1063,7 +1064,47 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
 static PicturePtr createSourcePicture(void)
 {
     PicturePtr pPicture;
-    pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
+
+    extern int nxagentPicturePrivateIndex;
+
+    unsigned int totalPictureSize;
+
+    DevUnion *ppriv;
+
+    char *privPictureRecAddr;
+
+    int i;
+
+    /*
+     * Compute size of entire PictureRect, plus privates.
+     */
+
+    totalPictureSize = sizeof(PictureRec) +
+                           picturePrivateCount * sizeof(DevUnion) +
+                               sizeof(nxagentPrivPictureRec);
+
+    pPicture = (PicturePtr) xalloc(totalPictureSize);
+
+    if (pPicture != NULL)
+    {
+      ppriv = (DevUnion *) (pPicture + 1);
+
+      for (i = 0; i < picturePrivateCount; ++i)
+      {
+        /*
+         * Other privates are inaccessible.
+         */
+
+        ppriv[i].ptr = NULL;
+      }
+
+      privPictureRecAddr = (char *) &ppriv[picturePrivateCount];
+
+      ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
+
+      pPicture -> devPrivates = ppriv;
+    }
+
     pPicture->pDrawable = 0;
     pPicture->pFormat = 0;
     pPicture->pNext = 0;
@@ -1697,6 +1738,10 @@ FreePicture (pointer	value,
 
     if (--pPicture->refcnt == 0)
     {
+#ifdef NXAGENT_SERVER
+        nxagentDestroyPicture(pPicture);
+#endif
+
 	if (pPicture->transform)
 	    xfree (pPicture->transform);
         if (!pPicture->pDrawable) {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index ffc199704..562cd2c66 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -116,7 +116,6 @@ int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
 void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
 int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
 int  nxagentCreatePicture(PicturePtr, Mask);
-void nxagentDestroyPicture(PicturePtr pPicture);
 void nxagentChangePicture(PicturePtr, Mask);
 int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
 void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
@@ -132,6 +131,28 @@ void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
 void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
                            INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
 
+void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
+
+void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+                                           xPointFixed *p2, int nStops,
+                                               xFixed *stops,
+                                                   xRenderColor *colors);
+
+void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+                                           xPointFixed *outer,
+                                               xFixed innerRadius,
+                                                   xFixed outerRadius,
+                                                       int nStops,
+                                                           xFixed *stops,
+                                                               xRenderColor *colors);
+
+void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+                                            xPointFixed *center,
+                                                xFixed angle, int nStops, 
+                                                    xFixed *stops, 
+                                                        xRenderColor *colors);
+
+
 /*
  * The void pointer is actually a XGlyphElt8.
  */
@@ -823,8 +844,6 @@ ProcRenderFreePicture (ClientPtr client)
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
 		    RenderErrBase + BadPicture);
 
-    nxagentDestroyPicture(pPicture);
-
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -926,9 +945,16 @@ ProcRenderComposite (ClientPtr client)
 		    RenderErrBase + BadPicture);
     VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
 		  RenderErrBase + BadPicture);
+/*
+FIXME: Imported change from newest version of Xorg. Changed pSrc to pDst.
+
     if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
 	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
 	return BadMatch;
+*/
+    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
 
     ValidatePicture (pSrc);
     if (pMask)
@@ -2336,6 +2362,11 @@ static int ProcRenderCreateSolidFill(ClientPtr client)
     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2367,6 +2398,12 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
+                                          stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2397,6 +2434,14 @@ static int ProcRenderCreateRadialGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
+                                          stuff->inner_radius,
+                                              stuff->outer_radius, 
+                                                  stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2426,6 +2471,13 @@ static int ProcRenderCreateConicalGradient (ClientPtr client)
                                              stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
+                                           stuff->angle, stuff->nStops, stops,
+                                               colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index ffc199704..562cd2c66 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -116,7 +116,6 @@ int  nxagentCursorSaveRenderInfo(ScreenPtr, CursorPtr);
 void nxagentCursorPostSaveRenderInfo(CursorPtr, ScreenPtr, PicturePtr, int, int);
 int  nxagentRenderRealizeCursor(ScreenPtr, CursorPtr);
 int  nxagentCreatePicture(PicturePtr, Mask);
-void nxagentDestroyPicture(PicturePtr pPicture);
 void nxagentChangePicture(PicturePtr, Mask);
 int  nxagentChangePictureClip(PicturePtr, int, int, xRectangle *, int, int);
 void nxagentComposite(CARD8, PicturePtr, PicturePtr, PicturePtr, INT16, INT16,
@@ -132,6 +131,28 @@ void nxagentSetPictureFilter(PicturePtr pPicture, char *filter, int name_size,
 void nxagentTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst, PictFormatPtr maskFormat,
                            INT16 xSrc, INT16 ySrc, int ntrap, xTrapezoid *traps);
 
+void nxagentRenderCreateSolidFill(PicturePtr pPicture, xRenderColor *color);
+
+void nxagentRenderCreateLinearGradient(PicturePtr pPicture, xPointFixed *p1,
+                                           xPointFixed *p2, int nStops,
+                                               xFixed *stops,
+                                                   xRenderColor *colors);
+
+void nxagentRenderCreateRadialGradient(PicturePtr pPicture, xPointFixed *inner,
+                                           xPointFixed *outer,
+                                               xFixed innerRadius,
+                                                   xFixed outerRadius,
+                                                       int nStops,
+                                                           xFixed *stops,
+                                                               xRenderColor *colors);
+
+void nxagentRenderCreateConicalGradient(PicturePtr pPicture,
+                                            xPointFixed *center,
+                                                xFixed angle, int nStops, 
+                                                    xFixed *stops, 
+                                                        xRenderColor *colors);
+
+
 /*
  * The void pointer is actually a XGlyphElt8.
  */
@@ -823,8 +844,6 @@ ProcRenderFreePicture (ClientPtr client)
     VERIFY_PICTURE (pPicture, stuff->picture, client, SecurityDestroyAccess,
 		    RenderErrBase + BadPicture);
 
-    nxagentDestroyPicture(pPicture);
-
     FreeResource (stuff->picture, RT_NONE);
     return(client->noClientException);
 }
@@ -926,9 +945,16 @@ ProcRenderComposite (ClientPtr client)
 		    RenderErrBase + BadPicture);
     VERIFY_ALPHA (pMask, stuff->mask, client, SecurityReadAccess, 
 		  RenderErrBase + BadPicture);
+/*
+FIXME: Imported change from newest version of Xorg. Changed pSrc to pDst.
+
     if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
 	(pMask && pMask->pDrawable && pSrc->pDrawable->pScreen != pMask->pDrawable->pScreen))
 	return BadMatch;
+*/
+    if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) ||
+	(pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen))
+	return BadMatch;
 
     ValidatePicture (pSrc);
     if (pMask)
@@ -2336,6 +2362,11 @@ static int ProcRenderCreateSolidFill(ClientPtr client)
     pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateSolidFill(pPicture, &stuff -> color);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2367,6 +2398,12 @@ static int ProcRenderCreateLinearGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateLinearGradient(pPicture, &stuff->p1, &stuff->p2,
+                                          stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2397,6 +2434,14 @@ static int ProcRenderCreateRadialGradient (ClientPtr client)
                                             stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateRadialGradient(pPicture, &stuff->inner, &stuff->outer,
+                                          stuff->inner_radius,
+                                              stuff->outer_radius, 
+                                                  stuff->nStops, stops, colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
@@ -2426,6 +2471,13 @@ static int ProcRenderCreateConicalGradient (ClientPtr client)
                                              stuff->nStops, stops, colors, &error);
     if (!pPicture)
 	return error;
+    /* AGENT SERVER */
+
+    nxagentRenderCreateConicalGradient(pPicture, &stuff->center,
+                                           stuff->angle, stuff->nStops, stops,
+                                               colors);
+
+    /* AGENT SERVER */
     if (!AddResource (stuff->pid, PictureType, (pointer)pPicture))
 	return BadAlloc;
     return Success;
-- 
cgit v1.2.3


From e6db7e93608570765b3b6133ebb60d746c81aeeb Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:59:00 +0200
Subject: Imported nxagent-3.4.0-9.tar.gz

Summary: Imported nxagent-3.4.0-9.tar.gz
Keywords:

Imported nxagent-3.4.0-9.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG |  8 +++++
 nx-X11/programs/Xserver/hw/nxagent/Events.c  | 31 +++++++++--------
 nx-X11/programs/Xserver/hw/nxagent/Screen.c  | 51 ----------------------------
 nx-X11/programs/Xserver/hw/nxagent/Screen.h  |  5 ++-
 nx-X11/programs/Xserver/hw/nxagent/Window.c  |  4 +++
 5 files changed, 30 insertions(+), 69 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 9e067d407..7310959ef 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,13 @@
 ChangeLog:
 
+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
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 33eafa55b..40b30308c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -1728,14 +1728,11 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           nxagentLastEnteredWindow = NULL;
         }
 
-        if (nxagentPointerAndKeyboardGrabbed == 1)
+        if (X.xcrossing.window == nxagentDefaultWindows[0] &&
+                X.xcrossing.detail != NotifyInferior &&
+                    X.xcrossing.mode == NotifyNormal)
         {
-          if (X.xcrossing.window == nxagentDefaultWindows[0] &&
-                  X.xcrossing.detail != NotifyInferior &&
-                      X.xcrossing.mode == NotifyNormal)
-          {
-            nxagentUngrabPointerAndKeyboard(&X);
-          }
+          nxagentUngrabPointerAndKeyboard(&X);
         }
 
         if (X.xcrossing.detail != NotifyInferior)
@@ -2123,14 +2120,8 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
     if (nxagentWMIsRunning)
     {
-      if (nxagentOption(Fullscreen))
-      {
-        nxagentMinimizeFromFullScreen(pScreen);
-      }
-      else
-      {
-        XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0], DefaultScreen(nxagentDisplay));
-      }
+      XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
+                         DefaultScreen(nxagentDisplay));
     }
   }
 
@@ -3791,6 +3782,11 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
 
   int resource;
 
+  if (nxagentPointerAndKeyboardGrabbed == 1)
+  {
+    return;
+  }
+
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Grabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
@@ -3856,6 +3852,11 @@ void nxagentUngrabPointerAndKeyboard(XEvent *X)
 {
   unsigned long now;
 
+  if (nxagentPointerAndKeyboardGrabbed == 0)
+  {
+    return;
+  }
+
   #ifdef TEST
   fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Ungrabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 3522d7e2e..2db7df8fe 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -287,57 +287,6 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
   }
 }
 
-void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
-{
-  XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
-}
-
-void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
-{
-  if(nxagentIpaq)
-  {
-    XMapWindow(nxagentDisplay, nxagentFullscreenWindow);
-  }
-  else
-  {
-/*
-FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWindow()
-       in order to avoid the session window is iconified.
-       We could avoid the sesssion window is iconified when a LeaveNotify event is received,
-       so this check would be unnecessary.
-*/
-    struct timeval timeout;
-    int i;
-    XEvent e;
-
-    XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
-                        RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
-
-    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
-    {
-      #ifdef TEST
-      fprintf(stderr, "nxagentSwitchFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
-      #endif
-
-      if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
-      {
-        break;
-      }
-
-      XSync(nxagentDisplay, 0);
-
-      timeout.tv_sec = 0;
-      timeout.tv_usec = 50 * 1000;
-
-      nxagentWaitEvents(nxagentDisplay, &timeout);
-    }
-
-    XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
-
-    while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
-  }
-}
-
 Bool nxagentMagicPixelZone(int x, int y)
 {
   return (x >= nxagentOption(Width) - 1 && y < 1);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 3bf66b2f5..1ab6caad2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -60,6 +60,8 @@ extern short nxagentShadowUid;
 void nxagentSetScreenInfo(ScreenInfo *screenInfo);
 void nxagentSetPixmapFormats(ScreenInfo *screenInfo);
 
+void nxagentPrintGeometry();
+
 extern Window nxagentDefaultWindows[MAXSCREENS];
 extern Window nxagentInputWindows[MAXSCREENS];
 extern Window nxagentScreenSaverWindows[MAXSCREENS];
@@ -85,9 +87,6 @@ extern int nxagentBitsPerPixel(int depth);
 
 void nxagentSetScreenSaverTime(void);
 
-void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
-void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
-
 Bool nxagentMagicPixelZone(int x, int y);
 
 Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 2403390b8..2da21b91c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -768,10 +768,14 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
   if (switchOn == 1)
   {
     nxagentFullscreenWindow = nxagentDefaultWindows[pScreen -> myNum];
+
+    nxagentGrabPointerAndKeyboard(NULL);
   }
   else
   {
     nxagentFullscreenWindow = None;
+
+    nxagentUngrabPointerAndKeyboard(NULL);
   } 
 }
 
-- 
cgit v1.2.3


From 39b738a67a14dde67b2a811d56ac84934fcef52d Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:59:00 +0200
Subject: Imported nxagent-3.5.0-2.tar.gz

Summary: Imported nxagent-3.5.0-2.tar.gz
Keywords:

Imported nxagent-3.5.0-2.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Agent.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |  15 +-
 nx-X11/programs/Xserver/hw/nxagent/Args.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Atoms.c         |  32 +--
 nx-X11/programs/Xserver/hw/nxagent/Atoms.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Binder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |  88 ++++++
 nx-X11/programs/Xserver/hw/nxagent/Client.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Client.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Clipboard.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Colormap.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Composite.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Cursor.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Dialog.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Drawable.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Error.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Events.c        | 317 ++++++++++++---------
 nx-X11/programs/Xserver/hw/nxagent/Events.h        |   3 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.c    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.h    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.c          |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/Font.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GC.c            |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCOps.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/GCs.h           |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Handlers.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Holder.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Icons.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Image.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |   6 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keyboard.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.c     |  14 +-
 nx-X11/programs/Xserver/hw/nxagent/Keystroke.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/LICENSE         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Literals.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Millis.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c    |   2 +-
 .../Xserver/hw/nxagent/NXdispatch.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c    |   2 +-
 .../Xserver/hw/nxagent/NXdixfonts.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXevents.c      |   2 +-
 .../Xserver/hw/nxagent/NXevents.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXextension.c   |   2 +-
 .../Xserver/hw/nxagent/NXextension.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyph.c       |   2 +-
 .../Xserver/hw/nxagent/NXglyph.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c   |   2 +-
 .../Xserver/hw/nxagent/NXglyphcurs.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h    |   2 +-
 .../Xserver/hw/nxagent/NXglyphstr.h.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c     |   2 +-
 .../Xserver/hw/nxagent/NXmiglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicture.c     |   2 +-
 .../Xserver/hw/nxagent/NXpicture.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h  |   2 +-
 .../Xserver/hw/nxagent/NXpicturestr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXproperty.c    |   2 +-
 .../Xserver/hw/nxagent/NXproperty.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c       |   2 +-
 .../Xserver/hw/nxagent/NXrandr.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXrender.c      |   2 +-
 .../Xserver/hw/nxagent/NXrender.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXwindow.c      |   2 +-
 .../Xserver/hw/nxagent/NXwindow.c.NX.original      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Options.h       |   9 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixels.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmap.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Pointer.h       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.h     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.c        |  12 +-
 nx-X11/programs/Xserver/hw/nxagent/Render.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.c      |  62 +++-
 nx-X11/programs/Xserver/hw/nxagent/Rootless.h      |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        | 195 ++++++++++++-
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |  10 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Splash.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.c         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Split.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/TestExt.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.c          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Trap.h          |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Utils.h         |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.c        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Visual.h        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/Window.c        | 285 ++++++++++++++++--
 nx-X11/programs/Xserver/hw/nxagent/Windows.h       |   4 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXdamage.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXdispatch.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXdixfonts.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXevents.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c |   2 +-
 .../Xserver/hw/nxagent/X/NXextension.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXglxext.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXglyph.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h  |   2 +-
 .../Xserver/hw/nxagent/X/NXglyphstr.h.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiexpose.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c   |   2 +-
 .../Xserver/hw/nxagent/X/NXmiglyph.c.NX.original   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXmitrap.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXmiwindow.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c   |   7 +-
 .../Xserver/hw/nxagent/X/NXpicture.c.NX.original   |   7 +-
 .../programs/Xserver/hw/nxagent/X/NXpicturestr.h   |   2 +-
 .../hw/nxagent/X/NXpicturestr.h.NX.original        |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXproperty.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c     |   2 +-
 .../Xserver/hw/nxagent/X/NXrandr.c.NX.original     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXrender.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c  |   2 +-
 .../Xserver/hw/nxagent/X/NXresource.c.NX.original  |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c       |   2 +-
 .../Xserver/hw/nxagent/X/NXshm.c.NX.original       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXwindow.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c    |   2 +-
 .../Xserver/hw/nxagent/X/NXxvdisp.c.NX.original    |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm     |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm   |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/os2Stub.c       |   2 +-
 nx-X11/programs/Xserver/hw/nxagent/screensaver     |   2 +-
 160 files changed, 1007 insertions(+), 349 deletions(-)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Agent.h b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
index 3f2c93fdb..dbed1e0d8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Agent.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Agent.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index c2e58bd58..8fbb275a6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -562,11 +562,15 @@ int ddxProcessArgument(int argc, char *argv[], int i)
       if (!strcmp(argv[i],"fullscreen"))
       {
         nxagentChangeOption(Fullscreen, True);
+
+        nxagentChangeOption(AllScreens, True);
       }
       else if (!strcmp(argv[i],"ipaq"))
       {
         nxagentChangeOption(Fullscreen, True);
 
+        nxagentChangeOption(AllScreens, True);
+
         nxagentIpaq = True;
       }
       else
@@ -1071,10 +1075,14 @@ static void nxagentParseOptions(char *name, char *value)
     else if (!strcmp(value, "1"))
     {
       nxagentChangeOption(Fullscreen, True);
+
+      nxagentChangeOption(AllScreens, True);
     }
     else if (!strcmp(value, "0"))
     {
       nxagentChangeOption(Fullscreen, False);
+
+      nxagentChangeOption(AllScreens, False);
     }
     else
     {
@@ -1680,6 +1688,11 @@ N/A
       nxagentChangeOption(Fullscreen, False);
     }
 
+    if (nxagentOption(AllScreens) == UNDEFINED)
+    {
+      nxagentChangeOption(AllScreens, False);
+    }
+
     if (nxagentOption(Binder) == UNDEFINED)
     {
       nxagentChangeOption(Binder, False);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
index 92650a4a0..9cb97ca03 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Args.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
index 171df95a9..578731f07 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -66,21 +66,21 @@ Atom nxagentAtoms[NXAGENT_NUMBER_OF_ATOMS];
 
 static char *nxagentAtomNames[NXAGENT_NUMBER_OF_ATOMS + 1] =
 {
-  "NX_IDENTITY",              /* 0  */
-  "WM_PROTOCOLS",             /* 1  */
-  "WM_DELETE_WINDOW",         /* 2  */
-  "WM_NX_READY",              /* 3  */
-  "MCOPGLOBALS",              /* 4  */
-  "NX_CUT_BUFFER_SERVER",     /* 5  */
-  "TARGETS",                  /* 6  */
-  "TEXT",                     /* 7  */
-  "NX_AGENT_SIGNATURE",       /* 8  */
-  "NXDARWIN",                 /* 9  */
-  "CLIPBOARD",                /* 10 */
-  "TIMESTAMP",                /* 11 */
-  "UTF8_STRING",              /* 12 */
-  "_NET_WM_STATE",            /* 13 */
-  "_NET_WM_STATE_FULLSCREEN", /* 14 */
+  "NX_IDENTITY",                 /* 0  */
+  "WM_PROTOCOLS",                /* 1  */
+  "WM_DELETE_WINDOW",            /* 2  */
+  "WM_NX_READY",                 /* 3  */
+  "MCOPGLOBALS",                 /* 4  */
+  "NX_CUT_BUFFER_SERVER",        /* 5  */
+  "TARGETS",                     /* 6  */
+  "TEXT",                        /* 7  */
+  "NX_AGENT_SIGNATURE",          /* 8  */
+  "NXDARWIN",                    /* 9  */
+  "CLIPBOARD",                   /* 10 */
+  "TIMESTAMP",                   /* 11 */
+  "UTF8_STRING",                 /* 12 */
+  "_NET_WM_STATE",               /* 13 */
+  "_NET_WM_STATE_FULLSCREEN",    /* 14 */
   NULL,
   NULL
 };
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
index f49f2751e..d5b7fe5aa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Atoms.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.c b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
index 34433bd2b..d40aaebe6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Binder.h b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
index e0da3e357..f28a82b9f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Binder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Binder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 7310959ef..5f4b561ca 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
@@ -1,5 +1,93 @@
 ChangeLog:
 
+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.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.c b/nx-X11/programs/Xserver/hw/nxagent/Client.c
index acfaab7c0..63ed0e134 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Client.h b/nx-X11/programs/Xserver/hw/nxagent/Client.h
index 45f87fc66..a9b06c845 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Client.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Client.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
index eb830234d..2742e147f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
index 2750ddfd2..43189df81 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Clipboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
index 259aa3b24..b0f0507b5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
index 8321e8038..b2960590c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Colormap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.c b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
index b0640ff11..c79104fc1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Composite.h b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
index fb1d6d8e9..e875d0051 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Composite.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Composite.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
index 141ba3a64..9ed7c233f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
index 11e407efd..df7dc44f7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Cursor.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
index 2f807b1dc..0fb9491a4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
index aa845c7c2..bd12f3097 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Dialog.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index 1a57788e6..87be98116 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h
index 35b7857ad..454150d6e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
index 75057097a..9c167743f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
index 146610efb..c987fa119 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Drawable.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.c b/nx-X11/programs/Xserver/hw/nxagent/Error.c
index 963cfa287..43bf85900 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Error.h b/nx-X11/programs/Xserver/hw/nxagent/Error.h
index 2d6083d4e..e55fd71a5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Error.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Error.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index 40b30308c..b9da934d6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -205,8 +205,6 @@ CARD32 nxagentLastEventTime     = 0;
 CARD32 nxagentLastKeyPressTime  = 0;
 Time   nxagentLastServerTime    = 0;
 
-int nxagentPointerAndKeyboardGrabbed = 0;
-
 /*
  * Used for storing windows that need to
  * receive expose events from the agent.
@@ -582,6 +580,9 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
     {
       sizeHints.max_width = nxagentOption(RootWidth);
       sizeHints.max_height = nxagentOption(RootHeight);
+
+      XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                            &sizeHints);
     }
   }
   else
@@ -590,6 +591,9 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     nxagentLaunchDialog(DIALOG_ENABLE_DESKTOP_RESIZE_MODE);
 
+    nxagentRRSetScreenConfig(pScreen, nxagentOption(Width),
+                                 nxagentOption(Height));
+
     if (nxagentOption(ClientOs) == ClientOsWinnt)
     {
       NXSetExposeParameters(nxagentDisplay, 0, 0, 0);
@@ -597,10 +601,10 @@ void nxagentSwitchResizeMode(ScreenPtr pScreen)
 
     sizeHints.max_width = WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
     sizeHints.max_height = HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
-  }
 
-  XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
-                       &sizeHints);
+    XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum],
+                          &sizeHints);
+  }
 }
 
 void nxagentShadowSwitchResizeMode(ScreenPtr pScreen)
@@ -800,6 +804,7 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
   Bool startKbd = False;
   Bool closeSession = False;
   Bool switchFullscreen = False;
+  Bool switchAllScreens = False;
 
   /*
    * Last entered top level window.
@@ -984,6 +989,12 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
             break;
           }
+          case doSwitchAllScreens:
+          {
+            switchAllScreens = TRUE;
+
+            break;
+          }
           case doViewportMoveUp:
           {
             nxagentMoveViewport(pScreen, 0, -nxagentOption(Height));
@@ -1084,6 +1095,8 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
 
         if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow) == 1 && result == doNothing)
         {
+          X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
+
           NXShadowEvent(nxagentDisplay, X);
         }
 
@@ -1094,6 +1107,13 @@ void nxagentDispatchEvents(PredicateFuncPtr predicate)
         enum HandleEventResult result;
         int sendKey = 0;
 
+/*
+FIXME: If we don't flush the queue here, it could happen
+       that the inputInfo structure will not be up to date
+       when we perform the following check on down keys.
+*/
+        ProcessInputEvents();
+
 /*
 FIXME: Don't enqueue the KeyRelease event if the key was
        not already pressed. This workaround avoids a fake
@@ -1101,7 +1121,6 @@ FIXME: Don't enqueue the KeyRelease event if the key was
        Another solution would be to let the events are
        enqueued and to remove the KeyPress afterwards.
 */
-
         if (BitIsOn(inputInfo.keyboard -> key -> down,
                        nxagentConvertKeycode(X.xkey.keycode)))
         {
@@ -1160,6 +1179,8 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
           if (nxagentOption(ViewOnly) == 0 && nxagentOption(Shadow))
           {
+            X.xkey.keycode = nxagentConvertKeycode(X.xkey.keycode);
+
             NXShadowEvent(nxagentDisplay, X);
           }
         }
@@ -1177,23 +1198,6 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
         nxagentInputEvent = 1;
 
-        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
-        {
-          x.u.u.type = ButtonPress;
-          x.u.u.detail = inputInfo.pointer -> button -> map[3];
-          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
-
-          mieqEnqueue(&x);
-
-          x.u.u.type = ButtonRelease;
-          x.u.u.detail = inputInfo.pointer -> button -> map[3];
-          x.u.keyButtonPointer.time = nxagentLastEventTime = GetTimeInMillis();
-
-          mieqEnqueue(&x);
-
-          break;
-        }
-
         if (nxagentOption(Fullscreen))
         {
           if (nxagentMagicPixelZone(X.xbutton.x, X.xbutton.y))
@@ -1297,11 +1301,6 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
         nxagentInputEvent = 1;
 
-        if (nxagentOption(ClientOs) == ClientOsMac && (X.xbutton.state & ControlMask) == ControlMask)
-        {
-          break;
-        }
-
         if (viewportCursor)
         {
           /*
@@ -1672,14 +1671,11 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           nxagentScreenTrap = 0;
         }
 
-        if (nxagentOption(Fullscreen) == 1)
+        if (nxagentOption(Fullscreen) == 1 &&
+                X.xcrossing.window == nxagentFullscreenWindow &&
+                    X.xcrossing.detail != NotifyInferior)
         {
-          if (X.xcrossing.window == nxagentDefaultWindows[0] &&
-                  X.xcrossing.detail != NotifyInferior &&
-                      X.xcrossing.mode == NotifyNormal)
-          {
-            nxagentGrabPointerAndKeyboard(&X);
-          }
+          nxagentGrabPointerAndKeyboard(&X);
         }
 
         if (X.xcrossing.detail != NotifyInferior)
@@ -1986,7 +1982,8 @@ FIXME: Don't enqueue the KeyRelease event if the key was
         }
 
         if (nxagentUseNXTrans == 1 && nxagentOption(Rootless) == 0 &&
-                nxagentOption(Nested) == 0)
+                nxagentOption(Nested) == 0 &&
+                    X.xmap.window != nxagentIconWindow)
         {
           nxagentVisibility = VisibilityFullyObscured;
         }
@@ -2025,6 +2022,15 @@ FIXME: Don't enqueue the KeyRelease event if the key was
           }
         }
 
+        if (nxagentOption(AllScreens) == 1)
+        {
+          if (X.xmap.window == nxagentIconWindow)
+          {
+            pScreen = nxagentScreen(X.xmap.window);
+            nxagentMaximizeToFullScreen(pScreen);
+          }
+        }
+
         if (nxagentOption(Fullscreen) == 1)
         {
           nxagentVisibility = VisibilityUnobscured;
@@ -2120,14 +2126,40 @@ FIXME: Don't enqueue the KeyRelease event if the key was
 
     if (nxagentWMIsRunning)
     {
-      XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
-                         DefaultScreen(nxagentDisplay));
+      if (nxagentOption(AllScreens))
+      {
+        nxagentMinimizeFromFullScreen(pScreen);
+      }
+      else
+      {
+        XIconifyWindow(nxagentDisplay, nxagentDefaultWindows[0],
+                           DefaultScreen(nxagentDisplay));
+      }
     }
   }
 
   if (switchFullscreen)
   {
-    nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
+    if (nxagentOption(AllScreens) == 1 && nxagentOption(Fullscreen) == 1)
+    {
+      nxagentSwitchAllScreens(pScreen, 0);
+    }
+    else
+    {
+      nxagentSwitchFullscreen(pScreen, !nxagentOption(Fullscreen));
+    }
+  }
+
+  if (switchAllScreens)
+  {
+    if (nxagentOption(AllScreens) == 0 && nxagentOption(Fullscreen) == 1)
+    {
+      nxagentSwitchFullscreen(pScreen, 0);
+    }
+    else
+    {
+      nxagentSwitchAllScreens(pScreen, !nxagentOption(AllScreens));
+    }
   }
 
   if (startKbd)
@@ -2599,6 +2631,7 @@ int nxagentHandleGraphicsExposeEvent(XEvent *X)
 
 int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
 {
+  ScreenPtr pScreen;
   WindowPtr pWin;
   xEvent x;
 
@@ -2714,8 +2747,20 @@ int nxagentHandleClientMessageEvent(XEvent *X, enum HandleEventResult *result)
         fprintf(stderr, "Events: WM_DELETE_WINDOW arrived Atom = %ld.\n", wmAtom);
         #endif
 
-        if (X -> xclient.window == nxagentDefaultWindows[0] ||
-                nxagentWMIsRunning == 0)
+        if (X -> xclient.window == nxagentIconWindow)
+        {
+          pScreen = nxagentScreen(X -> xmap.window);
+
+          XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+          XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                             DefaultScreen(nxagentDisplay));
+
+        }
+
+        if (X -> xclient.window == (nxagentOption(Fullscreen) ?
+                nxagentIconWindow : nxagentDefaultWindows[0]) ||
+                    nxagentWMIsRunning == 0)
         {
           *result = doCloseSession;
         }
@@ -3312,110 +3357,113 @@ int nxagentHandleConfigureNotify(XEvent* X)
 
     if (X -> xconfigure.window == nxagentDefaultWindows[pScreen -> myNum])
     {
-      if (nxagentOption(DesktopResize) == 1)
+      if (nxagentOption(AllScreens) == 0)
       {
-        if (nxagentOption(Width) != X -> xconfigure.width ||
-              nxagentOption(Height) != X -> xconfigure.height)
+        if (nxagentOption(DesktopResize) == 1)
         {
-          Bool newEvents = False;
+          if (nxagentOption(Width) != X -> xconfigure.width ||
+                nxagentOption(Height) != X -> xconfigure.height)
+          {
+            Bool newEvents = False;
 
-          doRandR = True;
+            doRandR = True;
 
-          NXFlushDisplay(nxagentDisplay, NXFlushLink);
+            NXFlushDisplay(nxagentDisplay, NXFlushLink);
 
-          do
-          {
-            newEvents = False;
+            do
+            {
+              newEvents = False;
 
-            timeout.tv_sec  = 0;
-            timeout.tv_usec = 500 * 1000;
+              timeout.tv_sec  = 0;
+              timeout.tv_usec = 500 * 1000;
 
-            nxagentWaitEvents(nxagentDisplay, &timeout);
+              nxagentWaitEvents(nxagentDisplay, &timeout);
 
-            /*
-             * This should also flush
-             * the NX link for us.
-             */
+              /*
+               * This should also flush
+               * the NX link for us.
+               */
 
-            XSync(nxagentDisplay, 0);
+              XSync(nxagentDisplay, 0);
 
-            while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
-                                            ConfigureNotify, X))
-            {
-              newEvents = True;
-            }
+              while (XCheckTypedWindowEvent(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
+                                              ConfigureNotify, X))
+              {
+                newEvents = True;
+              }
 
-          } while (newEvents);
+            } while (newEvents);
+          }
         }
-      }
 
-      if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
-      {
-        nxagentChangeOption(X, X -> xconfigure.x);
-        nxagentChangeOption(Y, X -> xconfigure.y);
-      }
+        if (nxagentWMIsRunning == 0 || X -> xconfigure.send_event)
+        {
+          nxagentChangeOption(X, X -> xconfigure.x);
+          nxagentChangeOption(Y, X -> xconfigure.y);
+        }
 
-      if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
-              (nxagentOption(Width) != X -> xconfigure.width ||
-                  nxagentOption(Height) != X -> xconfigure.height))
-      {
-        nxagentShadowResize = 1;
-      }
+        if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1 &&
+                (nxagentOption(Width) != X -> xconfigure.width ||
+                    nxagentOption(Height) != X -> xconfigure.height))
+        {
+          nxagentShadowResize = 1;
+        }
 
-      nxagentChangeOption(Width, X -> xconfigure.width);
-      nxagentChangeOption(Height, X -> xconfigure.height);
+        nxagentChangeOption(Width, X -> xconfigure.width);
+        nxagentChangeOption(Height, X -> xconfigure.height);
 
-      nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
-                              (int) nxagentOption(RootWidth));
-      nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
-                              (int) nxagentOption(RootHeight));
+        nxagentChangeOption(ViewportXSpan, (int) X -> xconfigure.width -
+                                (int) nxagentOption(RootWidth));
+        nxagentChangeOption(ViewportYSpan, (int) X -> xconfigure.height -
+                                (int) nxagentOption(RootHeight));
 
-      nxagentMoveViewport(pScreen, 0, 0);
+        nxagentMoveViewport(pScreen, 0, 0);
 
-      if (nxagentOption(Shadow) == 1 ||
-              (nxagentOption(Width) == nxagentOption(RootWidth) &&
-                  nxagentOption(Height) == nxagentOption(RootHeight)))
-      {
-        doRandR = 0;
-      }
+        if (nxagentOption(Shadow) == 1 ||
+                (nxagentOption(Width) == nxagentOption(RootWidth) &&
+                    nxagentOption(Height) == nxagentOption(RootHeight)))
+        {
+          doRandR = 0;
+        }
 
-      nxagentChangeOption(Width, X -> xconfigure.width);
-      nxagentChangeOption(Height, X -> xconfigure.height);
+        nxagentChangeOption(Width, X -> xconfigure.width);
+        nxagentChangeOption(Height, X -> xconfigure.height);
 
-      XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
-                            X -> xconfigure.width, X -> xconfigure.height);
+        XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+                              X -> xconfigure.width, X -> xconfigure.height);
 
-      if (nxagentOption(Fullscreen) == 0)
-      {
-        nxagentMoveViewport(pScreen, 0, 0);
-      }
-      else
-      {
-        nxagentChangeOption(RootX, (nxagentOption(Width) -
-                                nxagentOption(RootWidth)) / 2);
-        nxagentChangeOption(RootY, (nxagentOption(Height) -
-                                nxagentOption(RootHeight)) / 2);
-        nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
-                                nxagentOption(RootWidth));
-        nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
-                                nxagentOption(RootHeight));
-
-        nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
-                                       nxagentOption(RootHeight));
-
-        XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
-                        nxagentOption(RootX), nxagentOption(RootY));
-      }
+        if (nxagentOption(Fullscreen) == 0)
+        {
+          nxagentMoveViewport(pScreen, 0, 0);
+        }
+        else
+        {
+          nxagentChangeOption(RootX, (nxagentOption(Width) -
+                                  nxagentOption(RootWidth)) / 2);
+          nxagentChangeOption(RootY, (nxagentOption(Height) -
+                                  nxagentOption(RootHeight)) / 2);
+          nxagentChangeOption(ViewportXSpan, nxagentOption(Width) -
+                                  nxagentOption(RootWidth));
+          nxagentChangeOption(ViewportYSpan, nxagentOption(Height) -
+                                  nxagentOption(RootHeight));
+
+          nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth),
+                                         nxagentOption(RootHeight));
+
+          XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                          nxagentOption(RootX), nxagentOption(RootY));
+        }
 
-      if (doRandR)
-      {
-        #ifdef TEST
-        fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
-                    nxagentOption(Width), nxagentOption(Height));
-        #endif
+        if (doRandR)
+        {
+          #ifdef TEST
+          fprintf(stderr,"nxagentHandleConfigureNotify: Width %d Height %d.\n",
+                      nxagentOption(Width), nxagentOption(Height));
+          #endif
 
-        nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
-                                   nxagentOption(Width), nxagentOption(Height));
+          nxagentRRSetScreenConfig(screenInfo.screens[DefaultScreen(nxagentDisplay)],
+                                     nxagentOption(Width), nxagentOption(Height));
+        }
       }
 
       return 1;
@@ -3782,10 +3830,7 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
 
   int resource;
 
-  if (nxagentPointerAndKeyboardGrabbed == 1)
-  {
-    return;
-  }
+  int result;
 
   #ifdef TEST
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Grabbing pointer and keyboard with event at [%p].\n",
@@ -3805,8 +3850,13 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
   fprintf(stderr, "nxagentGrabPointerAndKeyboard: Going to grab the keyboard in context [B1].\n");
   #endif
 
-  XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
-                    True, GrabModeAsync, GrabModeAsync, now);
+  result = XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow,
+                             True, GrabModeAsync, GrabModeAsync, now);
+
+  if (result != GrabSuccess)
+  {
+    return;
+  }
 
   /*
    * The smart scheduler could be stopped while
@@ -3844,19 +3894,12 @@ void nxagentGrabPointerAndKeyboard(XEvent *X)
     XSetInputFocus(nxagentDisplay, nxagentFullscreenWindow,
                        RevertToParent, now);
   }
-
-  nxagentPointerAndKeyboardGrabbed = 1;
 }
 
 void nxagentUngrabPointerAndKeyboard(XEvent *X)
 {
   unsigned long now;
 
-  if (nxagentPointerAndKeyboardGrabbed == 0)
-  {
-    return;
-  }
-
   #ifdef TEST
   fprintf(stderr, "nxagentUngrabPointerAndKeyboard: Ungrabbing pointer and keyboard with event at [%p].\n",
               (void *) X);
@@ -3882,8 +3925,6 @@ void nxagentUngrabPointerAndKeyboard(XEvent *X)
   #endif
 
   XUngrabPointer(nxagentDisplay, now);
-
-  nxagentPointerAndKeyboardGrabbed = 0;
 }
 
 void nxagentDeactivatePointerGrab()
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index 109475c16..c74fa151f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -33,6 +33,7 @@ enum HandleEventResult
   doCloseSession,
   doStartKbd,
   doSwitchFullscreen,
+  doSwitchAllScreens,
   doViewportMoveUp,
   doViewportMoveLeft,
   doViewportMoveRight,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
index e76cbb4ad..aced24ff4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
index 620645d00..5335cf87c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Extensions.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.c b/nx-X11/programs/Xserver/hw/nxagent/Font.c
index 13b819322..178ed3cf7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -1269,7 +1269,7 @@ Bool nxagentReconnectFailedFonts(void *p0)
   const int maxAttempt = 5;
 
   char **fontPaths, **localFontPaths, **newFontPaths;
-  char fontServerPath[256];
+  char fontServerPath[256] = "";
   int nPaths = 0;
 
   Bool repeat = True;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Font.h b/nx-X11/programs/Xserver/hw/nxagent/Font.h
index 75ae3f6f5..63cb6aa24 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Font.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Font.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GC.c b/nx-X11/programs/Xserver/hw/nxagent/GC.c
index c53e3b9f7..71562d999 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GC.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GC.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
index 85730797e..e18b034eb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
index 7ae6d9923..fa4967aee 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCOps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/GCs.h b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
index bec290088..f7e13477a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/GCs.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/GCs.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
index be407f160..310b572cc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
index fe8aeef36..3d3b335c0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.c b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
index a9ac77c09..bfd907cde 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Holder.h b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
index 9896aeead..c39b98780 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Holder.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Holder.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Icons.h b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
index 4d0e216cd..0601584d4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Icons.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Icons.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.c b/nx-X11/programs/Xserver/hw/nxagent/Image.c
index e8405ed3a..e499b7a11 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Image.h b/nx-X11/programs/Xserver/hw/nxagent/Image.h
index 7805b0312..57272ab18 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Image.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Image.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 64b6583bf..4f675a630 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -74,7 +74,7 @@ is" without express or implied warranty.
 #undef  DEBUG
 #undef  DUMP
 
-#define NXAGENT_VERSION  "3.4.0"
+#define NXAGENT_VERSION  "3.5.0"
 
 /*
  * ProcVector array defined in tables.c.
@@ -193,7 +193,7 @@ void InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
   if (serverGeneration <= 1)
   {
     fprintf(stderr, "\nNXAGENT - Version " NXAGENT_VERSION "\n\n");
-    fprintf(stderr, "Copyright (C) 2001, 2010 NoMachine.\n");
+    fprintf(stderr, "Copyright (C) 2001, 2011 NoMachine.\n");
     fprintf(stderr, "See http://www.nomachine.com/ for more information.\n\n");
 
     fprintf(stderr, "Info: Agent running with pid '%d'.\n", getpid());
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
index 576c1a74d..cf154e86d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Init.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
index b0aeabeea..8db38892e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
index 1a953358a..0e11a8a13 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keyboard.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
index de1da8654..6c6e477ab 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -116,7 +116,7 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
       {
         if (nxagentOption(Rootless) == False)
         {
-          *result = doSwitchFullscreen;
+          *result = doSwitchAllScreens;
         }
 
         break;
@@ -282,6 +282,16 @@ int nxagentCheckSpecialKeystroke(XKeyEvent *X, enum HandleEventResult *result)
   {
     switch (sym)
     {
+      case XK_f:
+      case XK_F:
+      {
+        if (nxagentOption(Rootless) == 0)
+        {
+          *result = doSwitchFullscreen;
+        }
+
+        break;
+      }
       case XK_Left:
       case XK_KP_Left:
       {
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
index e9ca59ff2..ef71a8851 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Keystroke.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/LICENSE b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
index 141ca13ea..8446e6f55 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/LICENSE
+++ b/nx-X11/programs/Xserver/hw/nxagent/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2001, 2010 NoMachine - http://www.nomachine.com/.
+Copyright (c) 2001, 2011 NoMachine - http://www.nomachine.com/.
 
 NXAGENT and NX extensions to X are copyright of NoMachine.
 
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Literals.h b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
index 377dd7e25..aaa3430d6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Literals.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Literals.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.c b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
index bde85f090..e9c739eeb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Millis.h b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
index 2125eca3e..69d247bbc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Millis.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Millis.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
index 5106ffa8c..4f59b8098 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
index 5106ffa8c..4f59b8098 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
index 0d8584218..1cccfd972 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
index 0d8584218..1cccfd972 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXdixfonts.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
index cd8ced7a6..f697cf3ca 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
index cd8ced7a6..f697cf3ca 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
index 852ad1503..1d86bf870 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
index 852ad1503..1d86bf870 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXextension.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
index 55248195f..22483b3fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
index 55248195f..22483b3fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
index 614d2db39..9212bf438 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
index 614d2db39..9212bf438 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphcurs.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
index 08ffb35b0..0f122be4a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
index 08ffb35b0..0f122be4a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXglyphstr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
index 806cf2900..09901ba9c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
index 806cf2900..09901ba9c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXmiglyph.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
index a9c501b34..d32cdb6c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
index a9c501b34..d32cdb6c4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
index 26a95fe9f..91eab0125 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
index 26a95fe9f..91eab0125 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicturestr.h.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
index 14b6136d4..20a6bd6dc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
index 14b6136d4..20a6bd6dc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXproperty.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
index b7039e1e0..d593fa6aa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
index b7039e1e0..d593fa6aa 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
index 0940a3602..43607ac08 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
index 0940a3602..43607ac08 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXrender.c.NX.original
@@ -31,7 +31,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
index 0954cf8ae..95ecde951 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
index 0954cf8ae..95ecde951 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXwindow.c.NX.original
@@ -6,7 +6,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
index 8d05175ff..37b2c74fd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
index 4e800e96d..160dc6517 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
index ae3a03d86..97ae77e29 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXxrandrint.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.c b/nx-X11/programs/Xserver/hw/nxagent/Options.c
index 1f04b0daf..5d7855667 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Options.h b/nx-X11/programs/Xserver/hw/nxagent/Options.h
index 1bc7eaa4c..7850a0586 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Options.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Options.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -102,6 +102,13 @@ typedef struct _AgentOptions
 
   int Fullscreen;
 
+  /*
+   * True if the fullscreen NX session will
+   * extend on all available screens.
+   */
+
+  int AllScreens;
+
   /*
    * Set to the auto-disconnect timeout, if
    * the user activated this feature.
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
index 10c705dfc..d3ab9dd2f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
index ea7c375ee..918d74dc7 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixels.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
index 1718c7363..ad7e9c313 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
index 234650dd4..98d5666d1 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pixmaps.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
index 9c1bfaace..a751974af 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
index b0bb3f99c..3b9ccce15 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Pointer.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index e63b481b2..b78660240 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
index 12d0742df..c321bfada 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.c b/nx-X11/programs/Xserver/hw/nxagent/Render.c
index 4f0f76474..6c74c147f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -584,16 +584,16 @@ XRenderPictFormat *nxagentMatchingFormats(PictFormatPtr pFormat)
 
 void nxagentDestroyPicture(PicturePtr pPicture)
 {
+  if (pPicture == NULL || nxagentPicturePriv(pPicture) -> picture == 0)
+  {
+    return;
+  }
+
   #ifdef TEST
   fprintf(stderr, "nxagentDestroyPicture: Going to destroy picture at [%p].\n",
               (void *) pPicture);
   #endif
 
-  if (pPicture == NULL)
-  {
-    return;
-  }
-
   XRenderFreePicture(nxagentDisplay,
                      nxagentPicturePriv(pPicture) -> picture);
   
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Render.h b/nx-X11/programs/Xserver/hw/nxagent/Render.h
index 4346a4e1e..6f61ca85f 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
index 612e71cf7..74d2d1fe5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -625,6 +625,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
   {
     XlibAtom *atoms = malloc(nUnits * sizeof(*atoms));
     Atom *input = value;
+    char *atomName = NULL;
     int i;
     int j = 0;
 
@@ -644,7 +645,8 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
        * instead of just getting rid of the property.
        */
 
-      if (strcmp(NameForAtom(input[i]), "_NET_WM_PING") != 0)
+      if ((atomName = NameForAtom(input[i])) != NULL &&
+              strcmp(atomName, "_NET_WM_PING") != 0)
       {
         atoms[j] = nxagentLocalToRemoteAtom(input[i]);
 
@@ -652,7 +654,7 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
         {
           #ifdef WARNING
           fprintf(stderr, "nxagentExportProperty: WARNING! Failed to convert local atom %ld [%s].\n",
-                      (long int) input[i], validateString(NameForAtom(input[i])));
+                      (long int) input[i], validateString(atomName));
           #endif
         }
 
@@ -725,7 +727,57 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     }
     else
     {
-      XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX, format, mode, (void*)output, nUnits);
+      #ifdef TEST
+      fprintf(stderr, "nxagentExportProperty: Property [%lu] format [%i] "
+                  "units [%lu].\n", propertyX, format, nUnits);
+      #endif
+
+      if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
+              (MAX_REQUEST_SIZE << 2))
+      {
+        XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX, typeX,
+                            format, mode, (void*)output, nUnits);
+      }
+      else if (mode == PropModeReplace)
+      {
+        int n;
+        char *data;
+
+        XDeleteProperty(nxagentDisplay, nxagentWindow(pWin), propertyX);
+
+        data = (char *) output;
+
+        while (nUnits > 0)
+        {
+          if ((format >> 3) * nUnits + sizeof(xChangePropertyReq) <
+                  (MAX_REQUEST_SIZE << 2))
+          {
+            n = nUnits;
+          }
+          else
+          {
+            n = ((MAX_REQUEST_SIZE << 2) - sizeof(xChangePropertyReq)) /
+                    (format >> 3);
+          }
+
+          XChangeProperty(nxagentDisplay, nxagentWindow(pWin), propertyX,
+                              typeX, format, PropModeAppend, (void*) data, n);
+
+          nUnits -= n;
+
+          data = (char *) data + n * (format >> 3);
+        }
+      }
+      else
+      {
+        #ifdef WARNING
+        fprintf(stderr, "nxagentExportProperty: WARNING! "
+                    "Property [%lu] too long.\n", propertyX);
+        #endif
+
+        goto nxagentExportPropertyError;
+      }
+
       nxagentAddPropertyToList(propertyX, pWin);
     }
   }
@@ -740,6 +792,8 @@ int nxagentExportProperty(pWin, property, type, format, mode, nUnits, value)
     #endif
   }
 
+  nxagentExportPropertyError:
+
   if (freeMem)
   {
     xfree(output);
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
index ece4c9d31..1ea258db3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Rootless.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 2db7df8fe..0a0d409eb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -160,6 +160,7 @@ void nxagentPropagateArtsdProperties(ScreenPtr pScreen, char *port);
 
 #endif
 
+Window nxagentIconWindow = None;
 Window nxagentFullscreenWindow = None;
 
 #ifdef VIEWPORT_FRAME
@@ -287,6 +288,166 @@ void nxagentSetPixmapFormats(ScreenInfo *screenInfo)
   }
 }
 
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen)
+{
+  XUnmapWindow(nxagentDisplay, nxagentFullscreenWindow);
+
+  if (nxagentIpaq)
+  {
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+  }
+  else
+  {
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+  }
+}
+
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen)
+{
+  if (nxagentIpaq)
+  {
+    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+
+    XMapWindow(nxagentDisplay, nxagentFullscreenWindow);
+  }
+  else
+  {
+/*
+    XUnmapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+/*
+FIXME: We'll chech for ReparentNotify and LeaveNotify events after XReparentWindow()
+       in order to avoid the session window is iconified.
+       We could avoid the sesssion window is iconified when a LeaveNotify event is received,
+       so this check would be unnecessary.
+*/
+    struct timeval timeout;
+    int i;
+    XEvent e;
+
+    XReparentWindow(nxagentDisplay, nxagentFullscreenWindow,
+                        RootWindow(nxagentDisplay, DefaultScreen(nxagentDisplay)), 0, 0);
+
+    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentMaximizeToFullscreen: WARNING! Going to wait for the ReparentNotify event.\n");
+      #endif
+
+      if (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, ReparentNotify, &e))
+      {
+        break;
+      }
+
+      XSync(nxagentDisplay, 0);
+
+      timeout.tv_sec = 0;
+      timeout.tv_usec = 50 * 1000;
+
+      nxagentWaitEvents(nxagentDisplay, &timeout);
+    }
+
+    XMapRaised(nxagentDisplay, nxagentFullscreenWindow);
+
+    XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                       DefaultScreen(nxagentDisplay));
+
+    while (XCheckTypedWindowEvent(nxagentDisplay, nxagentFullscreenWindow, LeaveNotify, &e));
+/*
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+*/
+  }
+}
+
+Window nxagentCreateIconWindow()
+{
+  XSetWindowAttributes attributes;
+  unsigned long valuemask;
+  char* window_name;
+  XTextProperty windowName;
+  XSizeHints sizeHints;
+  XWMHints wmHints;
+  Window w;
+  Mask mask;
+
+  /*
+   * Create icon window.
+   */
+
+  attributes.override_redirect = False;
+  attributes.colormap = DefaultColormap(nxagentDisplay, DefaultScreen(nxagentDisplay));
+  attributes.background_pixmap = nxagentScreenSaverPixmap;
+  valuemask = CWOverrideRedirect | CWBackPixmap | CWColormap;
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateIconWindow: Going to create new icon window.\n");
+  #endif
+
+  w = XCreateWindow(nxagentDisplay, DefaultRootWindow(nxagentDisplay),
+                        0, 0, 1, 1, 0,
+                            DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+                                InputOutput,
+                                    DefaultVisual(nxagentDisplay, DefaultScreen(nxagentDisplay)),
+                                        valuemask, &attributes);
+
+  #ifdef TEST
+  fprintf(stderr, "nxagentCreateIconWindow: Created new icon window with id [%ld].\n",
+              nxagentIconWindow);
+  #endif
+
+  /*
+   *  Set hints to the window manager for the icon window.
+   */
+
+  window_name = nxagentWindowName;
+  XStringListToTextProperty(&window_name, 1, &windowName);
+  sizeHints.flags = PMinSize | PMaxSize;
+  sizeHints.min_width = sizeHints.max_width = 1;
+  sizeHints.min_height = sizeHints.max_height = 1;
+  wmHints.flags = IconPixmapHint | IconMaskHint;
+  wmHints.initial_state = IconicState;
+  wmHints.icon_pixmap = nxagentIconPixmap;
+
+  if (useXpmIcon)
+  {
+    wmHints.icon_mask = nxagentIconShape;
+    wmHints.flags = IconPixmapHint | IconMaskHint;
+  }
+  else
+  {
+    wmHints.flags = StateHint | IconPixmapHint;
+  }
+
+  XSetWMProperties(nxagentDisplay, w,
+                      &windowName, &windowName,
+                          NULL , 0 , &sizeHints, &wmHints, NULL);
+
+  /*
+   * Enable events from the icon window.
+   */
+
+  nxagentGetDefaultEventMask(&mask);
+
+  XSelectInput(nxagentDisplay, w, (mask & ~(KeyPressMask |
+                   KeyReleaseMask)) | StructureNotifyMask);
+
+  /*
+   * Notify to client if user closes icon window.
+   */
+
+  if (nxagentWMIsRunning && !nxagentOption(Rootless))
+  {
+    XlibAtom deleteWMAtom = nxagentAtoms[2]; /* WM_DELETE_WINDOW */
+
+    XSetWMProtocols(nxagentDisplay, w, &deleteWMAtom, 1);
+  }
+
+  return w;
+}
+
 Bool nxagentMagicPixelZone(int x, int y)
 {
   return (x >= nxagentOption(Width) - 1 && y < 1);
@@ -816,6 +977,8 @@ Bool nxagentOpenScreen(int index, ScreenPtr pScreen,
 
     nxagentChangeOption(Fullscreen, False);
 
+    nxagentChangeOption(AllScreens, False);
+
     nxagentFullscreenWindow = 0;
 
     resetAgentPosition = True;
@@ -1221,6 +1384,11 @@ N/A
       nxagentChangeOption(Height, gattributes.height);
     }
 
+    if (nxagentOption(AllScreens))
+    {
+      attributes.override_redirect = True; 
+    }
+
     if (nxagentOption(Fullscreen))
     {
       /*
@@ -1448,7 +1616,8 @@ N/A
   if (nxagentDoFullGeneration == 1 ||
           nxagentReconnectTrap == 1)
   {
-    valuemask = CWBackPixel | CWEventMask | CWColormap;
+    valuemask = CWBackPixel | CWEventMask | CWColormap |
+                    (nxagentOption(AllScreens) == 1 ? CWOverrideRedirect : 0);
 
     attributes.background_pixel = nxagentBlackPixel;
 
@@ -1456,6 +1625,11 @@ N/A
 
     attributes.colormap = nxagentDefaultVisualColormap(nxagentDefaultVisual(pScreen));
 
+    if (nxagentOption(AllScreens) == 1)
+    {
+      attributes.override_redirect = True;
+    }
+
     if (nxagentOption(Fullscreen) == 1)
     {
       if (nxagentReconnectTrap)
@@ -1635,6 +1809,21 @@ N/A
 
     XClearWindow(nxagentDisplay, nxagentDefaultWindows[pScreen->myNum]);
 
+    if (nxagentOption(AllScreens))
+    {
+      if (nxagentReconnectTrap)
+      {
+        XGrabKeyboard(nxagentDisplay, nxagentFullscreenWindow, True, GrabModeAsync,
+                      GrabModeAsync, CurrentTime);
+      }
+
+      nxagentIconWindow = nxagentCreateIconWindow();
+    }
+    else
+    {
+      nxagentIconWindow = 0;
+    }
+
     /*
      * When we don't have window manager we grab keyboard
      * to let nxagent get keyboard events.
@@ -1983,8 +2172,6 @@ Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
   int oldMmWidth;
   int oldMmHeight;
 
-  RegionPtr pRootWinSize;
-
   #ifdef TEST
   nxagentPrintAgentGeometry("Before Resize Screen", "nxagentResizeScreen:");
   #endif
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 1ab6caad2..5b1957755 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -47,6 +47,8 @@ extern ScreenPtr nxagentDefaultScreen;
 
 extern Pixmap nxagentPixmapLogo;
 
+extern Window nxagentIconWindow;
+
 extern Window nxagentFullscreenWindow;
 
 extern RegionRec nxagentShadowUpdateRegion;
@@ -87,6 +89,12 @@ extern int nxagentBitsPerPixel(int depth);
 
 void nxagentSetScreenSaverTime(void);
 
+void nxagentMinimizeFromFullScreen(ScreenPtr pScreen);
+
+void nxagentMaximizeToFullScreen(ScreenPtr pScreen);
+
+Window nxagentCreateIconWindow(void);
+
 Bool nxagentMagicPixelZone(int x, int y);
 
 Bool nxagentResizeScreen(ScreenPtr pScreen, int width, int height,
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.c b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
index 24dbf1413..235c48c23 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Splash.h b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
index 86920ad8b..f7ba6c2e2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Splash.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Splash.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.c b/nx-X11/programs/Xserver/hw/nxagent/Split.c
index bf7f705b9..4cc2ea607 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Split.h b/nx-X11/programs/Xserver/hw/nxagent/Split.h
index 60be29b39..2be449a18 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Split.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Split.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
index 1d5fdee20..6bce2eaeb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/TestExt.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.c b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
index 22de3bc1b..f5e6bde0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Trap.h b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
index aa6937e70..9258e3b67 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Trap.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Trap.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Utils.h b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
index 830b2753f..f5bd55d8b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Utils.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Utils.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.c b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
index f38931677..b086c0e9a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Visual.h b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
index c682f92dd..8436f79ad 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Visual.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Visual.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 2da21b91c..3e6d41d04 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Window.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -693,7 +693,6 @@ void nxagentRestackWindow(WindowPtr pWin, WindowPtr pOldNextSib)
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 {
   XEvent e;
-  XSizeHints sizeHints;
 
   if (nxagentOption(Rootless) == 1)
   {
@@ -731,27 +730,6 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
 
   nxagentChangeOption(Fullscreen, switchOn);
 
-  if (nxagentOption(DesktopResize) == 1)
-  {
-    sizeHints.flags = PSize;
-
-    if (switchOn == 1)
-    {
-      sizeHints.width =
-          WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
-      sizeHints.height =
-          HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay));
-    }
-    else
-    {
-      sizeHints.width = nxagentOption(RootWidth);
-      sizeHints.height = nxagentOption(RootHeight);
-    }
-
-    XSetWMNormalHints(nxagentDisplay, nxagentDefaultWindows[pScreen -> myNum],
-                         &sizeHints);
-  }
-
   memset(&e, 0, sizeof(e));
 
   e.xclient.type = ClientMessage;
@@ -779,6 +757,245 @@ void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn)
   } 
 }
 
+void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn)
+{
+  Window w;
+  XSetWindowAttributes attributes;
+  unsigned long valuemask;
+
+  if (nxagentOption(Rootless))
+  {
+    return;
+  }
+
+  if (!switchOn)
+  {
+    nxagentWMDetect();
+
+    if (!nxagentWMIsRunning)
+    {
+      #ifdef WARNING
+      fprintf(stderr, "Warning: Can't switch to window mode, no window manager has been detected.\n");
+      #endif
+
+      return;
+    }
+  }
+
+  w = nxagentDefaultWindows[pScreen -> myNum];
+  attributes.override_redirect = switchOn;
+  valuemask = CWOverrideRedirect;
+  XUnmapWindow(nxagentDisplay, w);
+  XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+
+  XReparentWindow(nxagentDisplay, w, DefaultRootWindow(nxagentDisplay), 0, 0);
+
+  if (switchOn)
+  {
+    /*
+     * Change to fullscreen mode.
+     */
+
+    struct timeval timeout;
+    int i;
+    XEvent e;
+
+    /*
+     * Wait for window manager reparenting the default window.
+     */
+
+    for (i = 0; i < 100 && nxagentWMIsRunning; i++)
+    {
+      #ifdef TEST
+      fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Going to wait for the ReparentNotify event.\n");
+      #endif
+
+      if (XCheckTypedWindowEvent(nxagentDisplay, w, ReparentNotify, &e))
+      {
+        break;
+      }
+
+      /*
+       * This should also flush
+       * the NX link for us.
+       */
+
+      XSync(nxagentDisplay, 0);
+
+      timeout.tv_sec  = 0;
+      timeout.tv_usec = 50 * 1000;
+
+      nxagentWaitEvents(nxagentDisplay, &timeout);
+    }
+
+    if (i < 100)
+    {
+      /*
+       * The window manager has done with the reparent
+       * operation. We can resize and map the window.
+       */
+
+      nxagentChangeOption(Fullscreen, True);
+      nxagentChangeOption(AllScreens, True);
+      
+
+      /*
+       * Save the window-mode configuration.
+       */
+
+      nxagentChangeOption(SavedX, nxagentOption(X));
+      nxagentChangeOption(SavedY, nxagentOption(Y));
+      nxagentChangeOption(SavedWidth, nxagentOption(Width));
+      nxagentChangeOption(SavedHeight, nxagentOption(Height));
+      nxagentChangeOption(SavedRootWidth, nxagentOption(RootWidth));
+      nxagentChangeOption(SavedRootHeight, nxagentOption(RootHeight));
+
+      /*
+       * Reconf the Default window.
+       */
+
+      nxagentChangeOption(X, 0);
+      nxagentChangeOption(Y, 0);
+      nxagentChangeOption(Width, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+      nxagentChangeOption(Height, HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+
+      /*
+       * Move the root window.
+       */
+
+      nxagentChangeOption(RootX, (nxagentOption(Width) - nxagentOption(RootWidth)) / 2);
+      nxagentChangeOption(RootY, (nxagentOption(Height) - nxagentOption(RootHeight)) / 2);
+      nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
+      nxagentChangeOption(ViewportYSpan, nxagentOption(Height) - nxagentOption(RootHeight));
+
+      XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+                            nxagentOption(Width), nxagentOption(Height));
+
+      nxagentUpdateViewportFrame(0, 0, nxagentOption(RootWidth), nxagentOption(RootHeight));
+
+      XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]),
+                      nxagentOption(RootX), nxagentOption(RootY));
+
+      /*
+       * We disable the screensaver when changing
+       * mode to fullscreen. Is it really needed?
+       */
+
+      XSetScreenSaver(nxagentDisplay, 0, 0, DefaultExposures, DefaultBlanking);
+
+      if (nxagentIconWindow == None)
+      {
+        nxagentIconWindow = nxagentCreateIconWindow();
+
+        XMapWindow(nxagentDisplay, nxagentIconWindow);
+      }
+
+      XMapRaised(nxagentDisplay, w);
+      XSetInputFocus(nxagentDisplay, w, RevertToParent, CurrentTime);
+      XCheckTypedWindowEvent(nxagentDisplay, w, LeaveNotify, &e);
+      nxagentFullscreenWindow = w;
+
+      if (nxagentOption(DesktopResize) == 1)
+      {
+        if (nxagentOption(Shadow) == 0)
+        {
+          nxagentRRSetScreenConfig(pScreen, WidthOfScreen(DefaultScreenOfDisplay(nxagentDisplay)),
+                                       HeightOfScreen(DefaultScreenOfDisplay(nxagentDisplay)));
+        }
+        else
+        {
+          nxagentShadowAdaptToRatio();
+        }
+      }
+    }
+    else
+    {
+      /*
+       * We have waited for a reparent event unsuccessfully.
+       * Something happened to the window manager.
+       */
+
+      #ifdef WARNING
+      fprintf(stderr, "nxagentSwitchAllScreens: WARNING! Expected ReparentNotify event missing.\n");
+      #endif
+ 
+      nxagentWMIsRunning = False;
+      attributes.override_redirect = False;
+      XChangeWindowAttributes(nxagentDisplay, w, valuemask, &attributes);
+      XMapWindow(nxagentDisplay, w);
+    }
+  }
+  else
+  {
+    /*
+     * FIXME:
+     * It could be necessary:
+     * - To restore screensaver.
+     * - To set or reset nxagentForceBackingStore flag.
+     * - To propagate device settings to the X server if no WM is running.
+     */
+
+    /*
+     * Change to windowed mode.
+     */
+
+    nxagentChangeOption(Fullscreen, False);
+    nxagentChangeOption(AllScreens, False);
+
+    XDestroyWindow(nxagentDisplay, nxagentIconWindow);
+
+    nxagentIconWindow = nxagentFullscreenWindow = None;
+
+    if (nxagentOption(DesktopResize) == 1)
+    {
+      nxagentChangeOption(RootWidth, nxagentOption(SavedRootWidth));
+      nxagentChangeOption(RootHeight, nxagentOption(SavedRootHeight));
+
+      if (nxagentOption(Shadow) == 0)
+      {
+        nxagentRRSetScreenConfig(pScreen, nxagentOption(RootWidth), nxagentOption(RootHeight));
+      }
+    }
+
+    if (nxagentOption(WMBorderWidth) > 0 && nxagentOption(WMTitleHeight) > 0)
+    {
+      nxagentChangeOption(X, nxagentOption(SavedX) -
+                              nxagentOption(WMBorderWidth));
+      nxagentChangeOption(Y, nxagentOption(SavedY) -
+                              nxagentOption(WMTitleHeight));
+    }
+    else
+    {
+      nxagentChangeOption(X, nxagentOption(SavedX));
+      nxagentChangeOption(Y, nxagentOption(SavedY));
+    }
+
+    nxagentChangeOption(Width, nxagentOption(SavedWidth));
+    nxagentChangeOption(Height, nxagentOption(SavedHeight));
+
+    if (nxagentOption(Shadow) == 1 && nxagentOption(DesktopResize) == 1)
+    {
+      nxagentShadowAdaptToRatio();
+    }
+
+    XMoveResizeWindow(nxagentDisplay, w, nxagentOption(X), nxagentOption(Y),
+                          nxagentOption(Width), nxagentOption(Height));
+
+    nxagentUpdateViewportFrame(0, 0, nxagentOption(Width), nxagentOption(Height));
+
+    XMoveWindow(nxagentDisplay, nxagentWindow(WindowTable[pScreen -> myNum]), 0, 0);
+    XMapWindow(nxagentDisplay, w);
+
+    nxagentChangeOption(RootX, 0);
+    nxagentChangeOption(RootY, 0);
+  }
+
+  XMoveResizeWindow(nxagentDisplay, nxagentInputWindows[0], 0, 0,
+                        nxagentOption(Width), nxagentOption(Height));
+
+  nxagentSetPrintGeometry(pScreen -> myNum); 
+}
+
 #ifdef VIEWPORT_FRAME
 
 void nxagentUpdateViewportFrame(int x, int y, int w, int h)
@@ -2281,7 +2498,7 @@ void nxagentMapDefaultWindows()
 
         if (nxagentOption(Fullscreen) == 1 && nxagentWMIsRunning == 1)
         {
-          nxagentSwitchFullscreen(pScreen, 1);
+          nxagentMaximizeToFullScreen(pScreen);
         }
       }
 
@@ -2312,6 +2529,26 @@ void nxagentMapDefaultWindows()
                            nxagentDefaultWindows[i], CurrentTime);
   }
 
+  /*
+   * Map the icon window.
+   */
+
+  if (nxagentIconWindow != 0)
+  {
+    #ifdef TEST
+    fprintf(stderr, "nxagentMapDefaultWindows: Mapping icon window id [%ld].\n",
+                nxagentIconWindow);
+    #endif
+
+    XMapWindow(nxagentDisplay, nxagentIconWindow);
+
+    if (nxagentIpaq != 0)
+    {
+      XIconifyWindow(nxagentDisplay, nxagentIconWindow,
+                         DefaultScreen(nxagentDisplay));
+    }
+  }
+
   /*
    * Ensure that the fullscreen window gets the focus.
    */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Windows.h b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
index 6fc97b341..3ca74ba8e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Windows.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Windows.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -222,6 +222,8 @@ void nxagentSetTopLevelEventMask(WindowPtr pWin);
 
 void nxagentSwitchFullscreen(ScreenPtr pScreen, Bool switchOn);
 
+void nxagentSwitchAllScreens(ScreenPtr pScreen, Bool switchOn);
+
 void nxagentMoveViewport(ScreenPtr pScreen, int hShift, int vShift);
 
 #ifdef VIEWPORT_FRAME
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
index 7bc1c74cb..cf5d48ba2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
index 7bc1c74cb..cf5d48ba2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdamage.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
index ba4e1e662..69ad30d2d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
index ba4e1e662..69ad30d2d 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdispatch.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
index 225ecdaf8..04fc047fc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
index 225ecdaf8..04fc047fc 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
index 8e87d58c4..c5593adbb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
index 8e87d58c4..c5593adbb 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXevents.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
index 6e67b7ffe..ead9b9d28 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
index 6e67b7ffe..ead9b9d28 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXextension.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
index 172252b32..51c547984 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
index 172252b32..51c547984 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglxext.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
index 6340de537..cd65fdc0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
index 6340de537..cd65fdc0e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
index d6cd96631..7a1d813b3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
index d6cd96631..7a1d813b3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphcurs.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
index e78a1bf14..fa6b5fb02 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
index e78a1bf14..fa6b5fb02 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXglyphstr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
index c71ea8142..3fc73cf3b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
index c71ea8142..3fc73cf3b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiexpose.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
index efb295861..5f32334ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
index efb295861..5f32334ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiglyph.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
index d2bead0bc..f418654b4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
index d2bead0bc..f418654b4 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmitrap.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
index be1096c6c..190294979 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
index be1096c6c..190294979 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXmiwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
index be961c400..d9054b4b6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -873,6 +873,9 @@ AllocatePicture (ScreenPtr  pScreen)
 	else
 	    ppriv->ptr = (pointer)NULL;
     }
+
+    nxagentPicturePriv(pPicture) -> picture = 0;
+
     return pPicture;
 }
 
@@ -1103,6 +1106,8 @@ static PicturePtr createSourcePicture(void)
       ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
 
       pPicture -> devPrivates = ppriv;
+
+      nxagentPicturePriv(pPicture) -> picture = 0;
     }
 
     pPicture->pDrawable = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
index be961c400..d9054b4b6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicture.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
@@ -873,6 +873,9 @@ AllocatePicture (ScreenPtr  pScreen)
 	else
 	    ppriv->ptr = (pointer)NULL;
     }
+
+    nxagentPicturePriv(pPicture) -> picture = 0;
+
     return pPicture;
 }
 
@@ -1103,6 +1106,8 @@ static PicturePtr createSourcePicture(void)
       ppriv[nxagentPicturePrivateIndex].ptr = (pointer) privPictureRecAddr;
 
       pPicture -> devPrivates = ppriv;
+
+      nxagentPicturePriv(pPicture) -> picture = 0;
     }
 
     pPicture->pDrawable = 0;
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
index b6cee91f1..0d1a8e1d8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
index b6cee91f1..0d1a8e1d8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXpicturestr.h.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
index d02f3f015..cd1ec6ddd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
index d02f3f015..cd1ec6ddd 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXproperty.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
index e1bb44148..5f460f23e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
index e1bb44148..5f460f23e 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
index 562cd2c66..89e790135 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
index 562cd2c66..89e790135 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXrender.c.NX.original
@@ -26,7 +26,7 @@
 
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
index 8c69217e7..d1c8325f2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
index 8c69217e7..d1c8325f2 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXresource.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
index b99cbe3e3..eaaa92041 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
index b99cbe3e3..eaaa92041 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXshm.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
index 4022bc397..76e86fd2a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
index 4022bc397..76e86fd2a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXwindow.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
index aa902226e..f6dad312a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
index aa902226e..f6dad312a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
+++ b/nx-X11/programs/Xserver/hw/nxagent/X/NXxvdisp.c.NX.original
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
index 5955f1705..dd8be6cb3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxagent.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
index e7dee27b1..854e0a611 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
+++ b/nx-X11/programs/Xserver/hw/nxagent/nxmissing.xpm
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
index 80419d871..9ec7e6bc8 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/os2Stub.c
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/screensaver b/nx-X11/programs/Xserver/hw/nxagent/screensaver
index 4c5c10620..ef7cd661a 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/screensaver
+++ b/nx-X11/programs/Xserver/hw/nxagent/screensaver
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /*                                                                        */
-/* Copyright (c) 2001, 2010 NoMachine, http://www.nomachine.com/.         */
+/* 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      */
-- 
cgit v1.2.3


From e01b9177b41f7d27a934d41fa38d550fa0026b45 Mon Sep 17 00:00:00 2001
From: Reinhard Tartler <siretart@tauware.de>
Date: Mon, 10 Oct 2011 17:59:01 +0200
Subject: Imported nxagent-3.5.0-5.tar.gz

Summary: Imported nxagent-3.5.0-5.tar.gz
Keywords:

Imported nxagent-3.5.0-5.tar.gz
into Git repository
---
 nx-X11/programs/Xserver/hw/nxagent/Args.c          |    4 +
 nx-X11/programs/Xserver/hw/nxagent/Args.h          |    2 +
 nx-X11/programs/Xserver/hw/nxagent/CHANGELOG       |   19 +
 nx-X11/programs/Xserver/hw/nxagent/Cursor.c        |   26 +-
 nx-X11/programs/Xserver/hw/nxagent/Display.c       |    2 +
 nx-X11/programs/Xserver/hw/nxagent/Events.c        |    8 +-
 nx-X11/programs/Xserver/hw/nxagent/Extensions.c    |  142 ++-
 nx-X11/programs/Xserver/hw/nxagent/Imakefile       |    8 +-
 nx-X11/programs/Xserver/hw/nxagent/Init.c          |   20 +
 nx-X11/programs/Xserver/hw/nxagent/Init.h          |    2 +
 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c       | 1229 ------------------
 .../Xserver/hw/nxagent/NXrandr.c.NX.original       | 1229 ------------------
 .../Xserver/hw/nxagent/NXrandr.c.XF86.original     | 1197 -----------------
 nx-X11/programs/Xserver/hw/nxagent/Reconnect.c     |    3 +-
 nx-X11/programs/Xserver/hw/nxagent/Screen.c        |  230 ++--
 nx-X11/programs/Xserver/hw/nxagent/Screen.h        |    2 +-
 nx-X11/programs/Xserver/hw/nxagent/Window.c        |    7 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c  |    3 +-
 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c     | 1344 --------------------
 .../Xserver/hw/nxagent/X/NXrandr.c.NX.original     | 1344 --------------------
 .../Xserver/hw/nxagent/X/NXrandr.c.X.original      | 1319 -------------------
 21 files changed, 342 insertions(+), 7798 deletions(-)
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
 delete mode 100644 nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Args.c b/nx-X11/programs/Xserver/hw/nxagent/Args.c
index 8fbb275a6..ecf0a21af 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.c
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Args.h b/nx-X11/programs/Xserver/hw/nxagent/Args.h
index 9cb97ca03..8f4d05d6c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Args.h
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG b/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
index 5f4b561ca..0f20b79c3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/CHANGELOG
+++ b/nx-X11/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.
+
 nxagent-3.5.0-2
 
 - Fixed TR0502449. Initialized font server path even if font server
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c b/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
index 9ed7c233f..e27415b91 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Cursor.c
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c
index 87be98116..db70434e3 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Display.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c
@@ -2406,6 +2406,8 @@ Bool nxagentReconnectDisplay(void *p0)
   nxagentPackQuality    = -1;
   nxagentSplitThreshold = -1;
 
+  nxagentRemoteMajor = -1;
+
   nxagentInstallSignalHandlers();
 
   nxagentInstallDisplayHandlers();
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index b9da934d6..ce84c1b19 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Extensions.c b/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
index aced24ff4..6dce644ae 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Extensions.c
+++ b/nx-X11/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;
@@ -106,12 +143,6 @@ int nxagentRandRGetInfo(ScreenPtr pScreen, Rotation *pRotations)
   int mmWidth;
   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/nx-X11/programs/Xserver/hw/nxagent/Imakefile b/nx-X11/programs/Xserver/hw/nxagent/Imakefile
index 51173e410..96579583b 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Imakefile
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Init.c b/nx-X11/programs/Xserver/hw/nxagent/Init.c
index 4f675a630..f4fc3c7e5 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.c
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Init.h b/nx-X11/programs/Xserver/hw/nxagent/Init.h
index cf154e86d..2dc0f5c02 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Init.h
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c
deleted file mode 100644
index d593fa6aa..000000000
--- a/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.NX.original
deleted file mode 100644
index d593fa6aa..000000000
--- a/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original b/nx-X11/programs/Xserver/hw/nxagent/NXrandr.c.XF86.original
deleted file mode 100644
index 666605e96..000000000
--- a/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c b/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
index b78660240..90b80799c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Reconnect.c
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Screen.c b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
index 0a0d409eb..b847b08e6 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Screen.c
@@ -2120,8 +2120,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)
@@ -2265,6 +2265,52 @@ FIXME: We should try to restore the previously
   nxagentChangeOption(ViewportXSpan, nxagentOption(Width) - nxagentOption(RootWidth));
   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.
    */
@@ -2654,9 +2700,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]);
 
@@ -3453,118 +3502,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/nx-X11/programs/Xserver/hw/nxagent/Screen.h b/nx-X11/programs/Xserver/hw/nxagent/Screen.h
index 5b1957755..aab3ba19c 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Screen.h
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/Window.c b/nx-X11/programs/Xserver/hw/nxagent/Window.c
index 3e6d41d04..988193609 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Window.c
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
index 04fc047fc..3234c9929 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXdixfonts.c
+++ b/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c
deleted file mode 100644
index 5f460f23e..000000000
--- a/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.NX.original
deleted file mode 100644
index 5f460f23e..000000000
--- a/nx-X11/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/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original b/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
deleted file mode 100644
index 3911a3498..000000000
--- a/nx-X11/programs/Xserver/hw/nxagent/X/NXrandr.c.X.original
+++ /dev/null
@@ -1,1319 +0,0 @@
-/*
- * $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 "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;
-}
-		
-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;
-#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++)
-	{
-	    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;
-    
-    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;
-}
-- 
cgit v1.2.3